aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/common/reset.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/netlogic/common/reset.S')
0 files changed, 0 insertions, 0 deletions
le diffstat' width='100%'> -rw-r--r--drivers/dma-buf/sync_debug.h10
-rw-r--r--drivers/gpu/drm/Kconfig13
-rw-r--r--drivers/gpu/drm/Makefile4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Makefile24
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h45
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c11
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c87
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c1043
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c584
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c44
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c247
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c81
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c195
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c121
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c40
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c20
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h11
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c21
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c11
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c50
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c70
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c111
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h11
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c120
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.h38
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c365
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c21
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_test.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c496
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c54
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h22
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c292
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h19
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c40
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h11
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c273
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/ci_dpm.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c30
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v6_0.c17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/df_v1_7.c120
-rw-r--r--drivers/gpu/drm/amd/amdgpu/df_v1_7.h (renamed from drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk104.c)30
-rw-r--r--drivers/gpu/drm/amd/amdgpu/df_v3_6.c116
-rw-r--r--drivers/gpu/drm/amd/amdgpu/df_v3_6.h (renamed from drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk110.c)30
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c102
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c344
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c33
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c146
-rw-r--r--drivers/gpu/drm/amd/amdgpu/kv_dpm.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h67
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v10_0.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v3_1.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c96
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si_dpm.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15.c125
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15_common.h15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15d.h6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c46
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c40
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c112
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c1073
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v3_0.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v4_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c188
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c53
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vi.c130
-rw-r--r--drivers/gpu/drm/amd/amdkfd/Makefile10
-rw-r--r--drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c20
-rw-r--r--drivers/gpu/drm/amd/amdkfd/cik_regs.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h560
-rw-r--r--drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx8.asm274
-rw-r--r--drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx9.asm1214
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c52
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_crat.c11
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device.c131
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c114
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c84
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c65
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_events.c4
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c119
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c92
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c39
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h7
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c9
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_v9.c340
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c319
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_module.c7
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c6
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c443
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c392
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h583
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h112
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process.c50
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c22
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_queue.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.c6
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.h1
-rw-r--r--drivers/gpu/drm/amd/amdkfd/soc15_int.h47
-rw-r--r--drivers/gpu/drm/amd/display/Kconfig8
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c225
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h5
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c15
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c5
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c13
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/conversion.c28
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c376
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/fixpt32_32.c161
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/log_helpers.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/logger.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table.c22
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table2.c26
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h579
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/custom_float.c46
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c256
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c82
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c112
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_debug.c38
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c24
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link.c170
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c30
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c345
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c24
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_surface.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h46
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dp_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_helper.c59
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_hw_types.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_link.h9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stream.h28
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h17
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_abm.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_audio.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c73
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c33
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c103
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h17
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c48
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c76
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_transform.c26
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c33
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c200
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c33
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c35
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c50
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c49
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c98
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c43
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h76
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c96
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c38
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c229
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c215
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h82
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c435
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c1362
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h330
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c24
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c104
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h26
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c349
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c1490
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h524
-rw-r--r--drivers/gpu/drm/amd/display/dc/dm_services.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h13
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c138
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h969
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_types.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/dce_calcs.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h64
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h18
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h17
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h36
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/transform.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h22
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/reg_helper.h56
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/resource.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq_types.h9
-rw-r--r--drivers/gpu/drm/amd/display/include/dal_asic_id.h11
-rw-r--r--drivers/gpu/drm/amd/display/include/dal_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/include/fixed31_32.h272
-rw-r--r--drivers/gpu/drm/amd/display/include/fixed32_32.h129
-rw-r--r--drivers/gpu/drm/amd/display/include/logger_interface.h9
-rw-r--r--drivers/gpu/drm/amd/display/include/logger_types.h66
-rw-r--r--drivers/gpu/drm/amd/display/modules/color/color_gamma.c692
-rw-r--r--drivers/gpu/drm/amd/display/modules/color/color_gamma.h48
-rw-r--r--drivers/gpu/drm/amd/display/modules/inc/mod_stats.h4
-rw-r--r--drivers/gpu/drm/amd/display/modules/stats/stats.c254
-rw-r--r--drivers/gpu/drm/amd/include/amd_shared.h23
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h12
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_sh_mask.h152
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h19
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_sh_mask.h8
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_default.h26
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_offset.h37
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_sh_mask.h52
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_default.h26
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_offset.h33
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_sh_mask.h48
-rw-r--r--drivers/gpu/drm/amd/include/atombios.h7
-rw-r--r--drivers/gpu/drm/amd/include/atomfirmware.h35
-rw-r--r--drivers/gpu/drm/amd/include/cgs_common.h170
-rw-r--r--drivers/gpu/drm/amd/include/kgd_kfd_interface.h26
-rw-r--r--drivers/gpu/drm/amd/include/kgd_pp_interface.h13
-rw-r--r--drivers/gpu/drm/amd/include/soc15_ih_clientid.h1
-rw-r--r--drivers/gpu/drm/amd/include/v9_structs.h48
-rw-r--r--drivers/gpu/drm/amd/include/vega20_ip_offset.h1051
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c489
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c41
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c91
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c11
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c222
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h15
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c99
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c39
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c4
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c208
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.h3
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c16
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c330
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c229
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c37
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c98
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h27
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c951
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h26
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c121
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c2
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c107
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c95
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c7
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c37
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h9
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h35
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h4
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu75.h760
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu75_discrete.h886
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h1
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/Makefile2
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c12
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c24
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c9
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c25
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c39
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c46
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h1
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c2
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c19
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c52
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c56
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c2383
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.h75
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c2
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h13
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c89
-rw-r--r--drivers/gpu/drm/bochs/bochs_kms.c2
-rw-r--r--drivers/gpu/drm/bridge/Kconfig16
-rw-r--r--drivers/gpu/drm/bridge/Makefile2
-rw-r--r--drivers/gpu/drm/bridge/adv7511/Kconfig2
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511.h6
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c46
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c331
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.h5
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c236
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h7
-rw-r--r--drivers/gpu/drm/bridge/cdns-dsi.c1623
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c1
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c18
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c2
-rw-r--r--drivers/gpu/drm/bridge/thc63lvd1024.c206
-rw-r--r--drivers/gpu/drm/drm_atomic.c26
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c109
-rw-r--r--drivers/gpu/drm/drm_blend.c39
-rw-r--r--drivers/gpu/drm/drm_connector.c50
-rw-r--r--drivers/gpu/drm/drm_crtc.c54
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h2
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c22
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c9
-rw-r--r--drivers/gpu/drm/drm_drv.c64
-rw-r--r--drivers/gpu/drm/drm_edid.c43
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c12
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c33
-rw-r--r--drivers/gpu/drm/drm_gem.c9
-rw-r--r--drivers/gpu/drm/drm_gem_framebuffer_helper.c19
-rw-r--r--drivers/gpu/drm/drm_ioc32.c4
-rw-r--r--drivers/gpu/drm/drm_ioctl.c85
-rw-r--r--drivers/gpu/drm/drm_lease.c2
-rw-r--r--drivers/gpu/drm/drm_modes.c179
-rw-r--r--drivers/gpu/drm/drm_panel_orientation_quirks.c29
-rw-r--r--drivers/gpu/drm/drm_plane.c54
-rw-r--r--drivers/gpu/drm/drm_prime.c21
-rw-r--r--drivers/gpu/drm/drm_property.c27
-rw-r--r--drivers/gpu/drm/drm_rect.c74
-rw-r--r--drivers/gpu/drm/drm_scdc_helper.c10
-rw-r--r--drivers/gpu/drm/drm_simple_kms_helper.c4
-rw-r--r--drivers/gpu/drm/drm_sysfs.c4
-rw-r--r--drivers/gpu/drm/etnaviv/Kconfig8
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_buffer.c16
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c15
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c15
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h13
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.c68
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.h45
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_dump.c15
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_dump.h16
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem.c15
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem.h15
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c16
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c19
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.h19
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_hwdb.c13
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_iommu.c49
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_iommu.h15
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c143
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_mmu.c31
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_mmu.h16
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_perfmon.c13
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_perfmon.h13
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_sched.c13
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_sched.h13
-rw-r--r--drivers/gpu/drm/exynos/Kconfig18
-rw-r--r--drivers/gpu/drm/exynos/Makefile2
-rw-r--r--drivers/gpu/drm/exynos/exynos5433_drm_decon.c21
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c55
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h11
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c46
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimc.c1080
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimc.h23
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c21
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.h3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gsc.c1075
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gsc.h24
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.c916
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.h175
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c9
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_rotator.c758
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_scaler.c694
-rw-r--r--drivers/gpu/drm/exynos/regs-scaler.h426
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c4
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_crt.c2
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_dp.c2
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_hdmi.c2
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_lvds.c2
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_output.c2
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_drv.h2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_lvds.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo.c4
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c2
-rw-r--r--drivers/gpu/drm/i2c/Kconfig6
-rw-r--r--drivers/gpu/drm/i2c/Makefile1
-rw-r--r--drivers/gpu/drm/i2c/tda9950.c509
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c244
-rw-r--r--drivers/gpu/drm/i915/Kconfig.debug15
-rw-r--r--drivers/gpu/drm/i915/Makefile20
-rw-r--r--drivers/gpu/drm/i915/gvt/cmd_parser.c81
-rw-r--r--drivers/gpu/drm/i915/gvt/debugfs.c72
-rw-r--r--drivers/gpu/drm/i915/gvt/gvt.h2
-rw-r--r--drivers/gpu/drm/i915/gvt/handlers.c35
-rw-r--r--drivers/gpu/drm/i915/gvt/mmio.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/mmio_context.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/sched_policy.c31
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.c89
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.h1
-rw-r--r--drivers/gpu/drm/i915/gvt/trace.h24
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c566
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c89
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h424
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c394
-rw-r--r--drivers/gpu/drm/i915/i915_gem.h13
-rw-r--r--drivers/gpu/drm/i915/i915_gem_batch_pool.c30
-rw-r--r--drivers/gpu/drm/i915/i915_gem_batch_pool.h29
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c62
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.h43
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c32
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c70
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.h5
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c178
-rw-r--r--drivers/gpu/drm/i915/i915_gem_timeline.c154
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c66
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.h366
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c410
-rw-r--r--drivers/gpu/drm/i915/i915_oa_icl.c118
-rw-r--r--drivers/gpu/drm/i915/i915_oa_icl.h34
-rw-r--r--drivers/gpu/drm/i915/i915_params.c3
-rw-r--r--drivers/gpu/drm/i915/i915_params.h3
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c1
-rw-r--r--drivers/gpu/drm/i915/i915_perf.c96
-rw-r--r--drivers/gpu/drm/i915/i915_pmu.c27
-rw-r--r--drivers/gpu/drm/i915/i915_pmu.h30
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h879
-rw-r--r--drivers/gpu/drm/i915/i915_request.c438
-rw-r--r--drivers/gpu/drm/i915/i915_request.h49
-rw-r--r--drivers/gpu/drm/i915/i915_scheduler.h72
-rw-r--r--drivers/gpu/drm/i915/i915_timeline.c105
-rw-r--r--drivers/gpu/drm/i915/i915_timeline.h (renamed from drivers/gpu/drm/i915/i915_gem_timeline.h)71
-rw-r--r--drivers/gpu/drm/i915/i915_trace.h129
-rw-r--r--drivers/gpu/drm/i915/i915_utils.h10
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c73
-rw-r--r--drivers/gpu/drm/i915/i915_vma.h6
-rw-r--r--drivers/gpu/drm/i915/intel_atomic.c19
-rw-r--r--drivers/gpu/drm/i915/intel_atomic_plane.c7
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c18
-rw-r--r--drivers/gpu/drm/i915/intel_breadcrumbs.c52
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c8
-rw-r--r--drivers/gpu/drm/i915/intel_csr.c9
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c451
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.c169
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.h4
-rw-r--r--drivers/gpu/drm/i915/intel_display.c472
-rw-r--r--drivers/gpu/drm/i915/intel_display.h4
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c298
-rw-r--r--drivers/gpu/drm/i915/intel_dp_link_training.c5
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c8
-rw-r--r--drivers/gpu/drm/i915/intel_dpio_phy.c11
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.c909
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.h97
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h84
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_vbt.c34
-rw-r--r--drivers/gpu/drm/i915/intel_engine_cs.c937
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c28
-rw-r--r--drivers/gpu/drm/i915/intel_fbdev.c7
-rw-r--r--drivers/gpu/drm/i915/intel_frontbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/intel_gpu_commands.h274
-rw-r--r--drivers/gpu/drm/i915/intel_guc.c231
-rw-r--r--drivers/gpu/drm/i915/intel_guc.h82
-rw-r--r--drivers/gpu/drm/i915/intel_guc_ads.c9
-rw-r--r--drivers/gpu/drm/i915/intel_guc_ct.c545
-rw-r--r--drivers/gpu/drm/i915/intel_guc_ct.h18
-rw-r--r--drivers/gpu/drm/i915/intel_guc_fw.c7
-rw-r--r--drivers/gpu/drm/i915/intel_guc_fwif.h162
-rw-r--r--drivers/gpu/drm/i915/intel_guc_log.c544
-rw-r--r--drivers/gpu/drm/i915/intel_guc_log.h59
-rw-r--r--drivers/gpu/drm/i915/intel_guc_reg.h14
-rw-r--r--drivers/gpu/drm/i915/intel_guc_submission.c114
-rw-r--r--drivers/gpu/drm/i915/intel_hangcheck.c16
-rw-r--r--drivers/gpu/drm/i915/intel_hdcp.c185
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c40
-rw-r--r--drivers/gpu/drm/i915/intel_hotplug.c3
-rw-r--r--drivers/gpu/drm/i915/intel_huc.c30
-rw-r--r--drivers/gpu/drm/i915/intel_huc.h7
-rw-r--r--drivers/gpu/drm/i915/intel_huc_fw.c8
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c538
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.h2
-rw-r--r--drivers/gpu/drm/i915/intel_mocs.c5
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c1
-rw-r--r--drivers/gpu/drm/i915/intel_pipe_crc.c75
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c578
-rw-r--r--drivers/gpu/drm/i915/intel_psr.c444
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c78
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h71
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c101
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c5
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c178
-rw-r--r--drivers/gpu/drm/i915/intel_uc.c132
-rw-r--r--drivers/gpu/drm/i915/intel_uc.h5
-rw-r--r--drivers/gpu/drm/i915/intel_uc_fw.c13
-rw-r--r--drivers/gpu/drm/i915/intel_uc_fw.h24
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.c175
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.h1
-rw-r--r--drivers/gpu/drm/i915/intel_wopcm.c275
-rw-r--r--drivers/gpu/drm/i915/intel_wopcm.h31
-rw-r--r--drivers/gpu/drm/i915/intel_workarounds.c949
-rw-r--r--drivers/gpu/drm/i915/intel_workarounds.h17
-rw-r--r--drivers/gpu/drm/i915/selftests/huge_pages.c5
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_context.c3
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_live_selftests.h2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_mock_selftests.h1
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_timeline.c (renamed from drivers/gpu/drm/i915/selftests/i915_gem_timeline.c)94
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_vma.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/igt_flush_test.c70
-rw-r--r--drivers/gpu/drm/i915/selftests/igt_flush_test.h14
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c5
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_engine_cs.c58
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_hangcheck.c414
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_lrc.c459
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_workarounds.c291
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_engine.c67
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gem_device.c21
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gtt.c1
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_timeline.c45
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_timeline.h28
-rw-r--r--drivers/gpu/drm/mediatek/Kconfig1
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dpi.c60
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_gem.c2
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c14
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_device.c1
-rw-r--r--drivers/gpu/drm/msm/msm_debugfs.c3
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c11
-rw-r--r--drivers/gpu/drm/nouveau/Kbuild8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/Kbuild51
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/atom.h222
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base.c53
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base.h31
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base507c.c286
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base827c.c71
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base907c.c110
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/base917c.c48
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/core.c70
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/core.h50
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/core507d.c115
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/core827d.c41
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/core907d.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt215.c)34
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/core917d.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt200.c)34
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/corec37d.c110
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/curs.c52
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/curs.h14
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/curs507a.c145
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/curs907a.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk110.c)22
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/cursc37a.c50
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/dac507d.c44
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/dac907d.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c)30
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c2238
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.h89
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/head.c511
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/head.h78
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/head507d.c325
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/head827d.c124
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/head907d.c284
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/head917d.c100
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/headc37d.c212
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/lut.c95
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/lut.h15
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/oimm.c51
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/oimm.h8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/oimm507b.c52
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly.c57
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly.h30
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly507e.c217
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly827e.c107
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly907e.c70
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/ovly917e.c45
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/pior507d.c44
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/sor507d.c44
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/sor907d.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt200.c)31
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/sorc37d.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c)30
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wimm.c47
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wimm.h8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c86
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wndw.c641
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wndw.h96
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c278
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/cl0080.h47
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/cla06f.h18
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/class.h14
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/clc37b.h11
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/clc37e.h13
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/device.h9
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/disp.h12
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/fifo.h18
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/mem.h2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/mmu.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/object.h16
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/user.h19
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/device.h13
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/engine.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h3
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h4
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h33
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h3
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c36
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c39
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c16
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c39
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.c15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c90
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c50
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hwmon.c16
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_vmm.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_vmm.h2
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv10_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv17_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c4558
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv84_fence.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvif/Kbuild6
-rw-r--r--drivers/gpu/drm/nouveau/nvif/device.c5
-rw-r--r--drivers/gpu/drm/nouveau/nvif/disp.c (renamed from drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h)62
-rw-r--r--drivers/gpu/drm/nouveau/nvif/fifo.c99
-rw-r--r--drivers/gpu/drm/nouveau/nvif/mem.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvif/mmu.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvif/user.c64
-rw-r--r--drivers/gpu/drm/nouveau/nvif/userc361.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogp100.c)21
-rw-r--r--drivers/gpu/drm/nouveau/nvif/vmm.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/engine.c15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/subdev.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/gv100.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c)29
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/base.c73
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/user.c74
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild30
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c42
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/changv100.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm200.c)24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c146
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h190
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c47
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk110.c38
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm107.c38
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm200.c38
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp100.c38
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c34
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt215.c38
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/coregv100.c204
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c61
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.c81
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c40
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgv100.c77
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c179
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h102
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c91
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c427
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c85
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/headgv100.c105
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c207
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h50
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c37
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c37
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt215.c38
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c42
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c101
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c52
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c175
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c120
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/wimmgv100.c82
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/wndwgv100.c184
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dma/Kbuild2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dma/gv100.c (renamed from drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dma/user.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.c119
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c46
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/cgrp.h11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h20
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c373
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h57
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c28
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c20
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c155
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c225
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c306
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/user.h6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/usergv100.c45
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c423
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h79
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c114
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c190
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c28
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c20
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c93
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c120
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c100
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c42
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c48
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgv100.c215
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c417
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h109
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c42
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c143
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c31
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c37
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c178
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c175
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c180
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c77
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c66
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c120
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gv100.c79
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c179
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c69
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c206
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h34
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c46
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp102.c51
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c20
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp10b.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gv100.c43
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgv100.c87
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c2
-rw-r--r--drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c14
-rw-r--r--drivers/gpu/drm/pl111/Makefile1
-rw-r--r--drivers/gpu/drm/pl111/pl111_display.c11
-rw-r--r--drivers/gpu/drm/pl111/pl111_drm.h1
-rw-r--r--drivers/gpu/drm/pl111/pl111_drv.c34
-rw-r--r--drivers/gpu/drm/pl111/pl111_versatile.c56
-rw-r--r--drivers/gpu/drm/pl111/pl111_vexpress.c134
-rw-r--r--drivers/gpu/drm/pl111/pl111_vexpress.h29
-rw-r--r--drivers/gpu/drm/qxl/qxl_cmd.c36
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c278
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.h3
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_irq.c3
-rw-r--r--drivers/gpu/drm/qxl/qxl_ttm.c8
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c32
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c53
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c20
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c20
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h8
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c26
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.h3
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c51
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.h5
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_group.c16
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_group.h2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c41
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_of.c1
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_of.h2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c15
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.h2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_regs.h16
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.c51
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.h3
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c37
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.h1
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fb.c61
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.c4
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_psr.c158
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_psr.h7
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c28
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.h1
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c1
-rw-r--r--drivers/gpu/drm/scheduler/gpu_scheduler.c91
-rw-r--r--drivers/gpu/drm/scheduler/gpu_scheduler_trace.h (renamed from include/drm/gpu_scheduler_trace.h)2
-rw-r--r--drivers/gpu/drm/scheduler/sched_fence.c8
-rw-r--r--drivers/gpu/drm/selftests/Makefile2
-rw-r--r--drivers/gpu/drm/selftests/drm_helper_selftests.h9
-rw-r--r--drivers/gpu/drm/selftests/test-drm-helper.c247
-rw-r--r--drivers/gpu/drm/sti/Kconfig3
-rw-r--r--drivers/gpu/drm/sti/sti_crtc.c2
-rw-r--r--drivers/gpu/drm/sti/sti_drv.c24
-rw-r--r--drivers/gpu/drm/sti/sti_plane.c9
-rw-r--r--drivers/gpu/drm/stm/drv.c2
-rw-r--r--drivers/gpu/drm/stm/ltdc.c88
-rw-r--r--drivers/gpu/drm/stm/ltdc.h10
-rw-r--r--drivers/gpu/drm/sun4i/Kconfig10
-rw-r--r--drivers/gpu/drm/sun4i/Makefile4
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.c16
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.h3
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.c86
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.h46
-rw-r--r--drivers/gpu/drm/sun4i/sun6i_mipi_dphy.c292
-rw-r--r--drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c1107
-rw-r--r--drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h63
-rw-r--r--drivers/gpu/drm/tegra/dc.c300
-rw-r--r--drivers/gpu/drm/tegra/dc.h11
-rw-r--r--drivers/gpu/drm/tegra/drm.c154
-rw-r--r--drivers/gpu/drm/tegra/drm.h13
-rw-r--r--drivers/gpu/drm/tegra/fb.c99
-rw-r--r--drivers/gpu/drm/tegra/gem.c20
-rw-r--r--drivers/gpu/drm/tegra/gr2d.c57
-rw-r--r--drivers/gpu/drm/tegra/gr3d.c60
-rw-r--r--drivers/gpu/drm/tegra/hub.c2
-rw-r--r--drivers/gpu/drm/tegra/plane.c194
-rw-r--r--drivers/gpu/drm/tegra/plane.h15
-rw-r--r--drivers/gpu/drm/tegra/vic.c5
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c2
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-core.c2
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c30
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c22
-rw-r--r--drivers/gpu/drm/tinydrm/ili9225.c28
-rw-r--r--drivers/gpu/drm/tinydrm/mi0283qt.c49
-rw-r--r--drivers/gpu/drm/tinydrm/mipi-dbi.c30
-rw-r--r--drivers/gpu/drm/tinydrm/repaper.c33
-rw-r--r--drivers/gpu/drm/tinydrm/st7586.c28
-rw-r--r--drivers/gpu/drm/tinydrm/st7735r.c7
-rw-r--r--drivers/gpu/drm/ttm/ttm_agp_backend.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c2
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_manager.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c51
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_vm.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_execbuf_util.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_lock.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_memory.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_module.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_object.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c1
-rw-r--r--drivers/gpu/drm/tve200/tve200_display.c11
-rw-r--r--drivers/gpu/drm/udl/udl_connector.c2
-rw-r--r--drivers/gpu/drm/udl/udl_dmabuf.c5
-rw-r--r--drivers/gpu/drm/udl/udl_drv.c2
-rw-r--r--drivers/gpu/drm/udl/udl_drv.h2
-rw-r--r--drivers/gpu/drm/udl/udl_gem.c5
-rw-r--r--drivers/gpu/drm/udl/udl_main.c2
-rw-r--r--drivers/gpu/drm/v3d/Kconfig9
-rw-r--r--drivers/gpu/drm/v3d/Makefile18
-rw-r--r--drivers/gpu/drm/v3d/v3d_bo.c389
-rw-r--r--drivers/gpu/drm/v3d/v3d_debugfs.c191
-rw-r--r--drivers/gpu/drm/v3d/v3d_drv.c371
-rw-r--r--drivers/gpu/drm/v3d/v3d_drv.h294
-rw-r--r--drivers/gpu/drm/v3d/v3d_fence.c58
-rw-r--r--drivers/gpu/drm/v3d/v3d_gem.c668
-rw-r--r--drivers/gpu/drm/v3d/v3d_irq.c206
-rw-r--r--drivers/gpu/drm/v3d/v3d_mmu.c122
-rw-r--r--drivers/gpu/drm/v3d/v3d_regs.h295
-rw-r--r--drivers/gpu/drm/v3d/v3d_sched.c228
-rw-r--r--drivers/gpu/drm/v3d/v3d_trace.h82
-rw-r--r--drivers/gpu/drm/v3d/v3d_trace_points.c9
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c75
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c9
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h38
-rw-r--r--drivers/gpu/drm/vc4/vc4_dsi.c5
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c57
-rw-r--r--drivers/gpu/drm/vc4/vc4_hvs.c4
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c224
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c152
-rw-r--r--drivers/gpu/drm/vc4/vc4_regs.h97
-rw-r--r--drivers/gpu/drm/vc4/vc4_v3d.c3
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c8
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c35
-rw-r--r--drivers/gpu/drm/xen/Kconfig17
-rw-r--r--drivers/gpu/drm/xen/Makefile11
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front.c839
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front.h158
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_cfg.c77
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_cfg.h37
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_conn.c115
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_conn.h27
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_evtchnl.c387
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_evtchnl.h81
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_gem.c308
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_gem.h40
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_kms.c366
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_kms.h26
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_shbuf.c414
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_shbuf.h64
-rw-r--r--drivers/gpu/drm/zte/zx_plane.c2
-rw-r--r--drivers/gpu/drm/zte/zx_vou.c5
-rw-r--r--drivers/gpu/drm/zte/zx_vou.h3
-rw-r--r--drivers/gpu/host1x/cdma.c6
-rw-r--r--drivers/gpu/host1x/cdma.h4
-rw-r--r--drivers/gpu/host1x/debug.c2
-rw-r--r--drivers/gpu/host1x/dev.c11
-rw-r--r--drivers/gpu/host1x/dev.h8
-rw-r--r--drivers/gpu/host1x/hw/channel_hw.c5
-rw-r--r--drivers/gpu/host1x/hw/syncpt_hw.c11
-rw-r--r--drivers/gpu/host1x/intr.c16
-rw-r--r--drivers/gpu/host1x/intr.h8
-rw-r--r--drivers/gpu/host1x/job.c147
-rw-r--r--drivers/gpu/host1x/job.h4
-rw-r--r--drivers/gpu/host1x/syncpt.c10
-rw-r--r--drivers/gpu/host1x/syncpt.h3
-rw-r--r--drivers/staging/vboxvideo/vbox_drv.c2
-rw-r--r--drivers/video/hdmi.c3
-rw-r--r--include/drm/amd_asic_type.h2
-rw-r--r--include/drm/bridge/analogix_dp.h3
-rw-r--r--include/drm/drmP.h28
-rw-r--r--include/drm/drm_blend.h3
-rw-r--r--include/drm/drm_device.h10
-rw-r--r--include/drm/drm_dp_helper.h24
-rw-r--r--include/drm/drm_drv.h15
-rw-r--r--include/drm/drm_edid.h2
-rw-r--r--include/drm/drm_file.h23
-rw-r--r--include/drm/drm_gem_framebuffer_helper.h3
-rw-r--r--include/drm/drm_ioctl.h7
-rw-r--r--include/drm/drm_legacy.h4
-rw-r--r--include/drm/drm_mode_config.h8
-rw-r--r--include/drm/drm_modes.h22
-rw-r--r--include/drm/drm_modeset_helper_vtables.h5
-rw-r--r--include/drm/drm_plane.h21
-rw-r--r--include/drm/drm_property.h28
-rw-r--r--include/drm/drm_rect.h3
-rw-r--r--include/drm/drm_simple_kms_helper.h6
-rw-r--r--include/drm/gpu_scheduler.h56
-rw-r--r--include/drm/i915_pciids.h1
-rw-r--r--include/drm/tinydrm/mipi-dbi.h4
-rw-r--r--include/drm/tinydrm/tinydrm-helpers.h5
-rw-r--r--include/drm/tinydrm/tinydrm.h8
-rw-r--r--include/linux/dma-fence.h236
-rw-r--r--include/linux/host1x.h24
-rw-r--r--include/linux/platform_data/tda9950.h16
-rw-r--r--include/trace/events/host1x.h16
-rw-r--r--include/uapi/drm/amdgpu_drm.h20
-rw-r--r--include/uapi/drm/drm.h7
-rw-r--r--include/uapi/drm/drm_mode.h6
-rw-r--r--include/uapi/drm/exynos_drm.h240
-rw-r--r--include/uapi/drm/tegra_drm.h492
-rw-r--r--include/uapi/drm/v3d_drm.h194
-rw-r--r--include/uapi/drm/vc4_drm.h13
-rw-r--r--include/uapi/linux/virtio_gpu.h1
-rw-r--r--scripts/coccinelle/api/drm-get-put.cocci10
1110 files changed, 72647 insertions, 26344 deletions
diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
index 0047b1394c70..2c887536258c 100644
--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
@@ -14,7 +14,13 @@ Required properties:
14 "adi,adv7513" 14 "adi,adv7513"
15 "adi,adv7533" 15 "adi,adv7533"
16 16
17- reg: I2C slave address 17- reg: I2C slave addresses
18 The ADV7511 internal registers are split into four pages exposed through
19 different I2C addresses, creating four register maps. Each map has it own
20 I2C address and acts as a standard slave device on the I2C bus. The main
21 address is mandatory, others are optional and revert to defaults if not
22 specified.
23
18 24
19The ADV7511 supports a large number of input data formats that differ by their 25The ADV7511 supports a large number of input data formats that differ by their
20color depth, color format, clock mode, bit justification and random 26color depth, color format, clock mode, bit justification and random
@@ -70,6 +76,9 @@ Optional properties:
70 rather than generate its own timings for HDMI output. 76 rather than generate its own timings for HDMI output.
71- clocks: from common clock binding: reference to the CEC clock. 77- clocks: from common clock binding: reference to the CEC clock.
72- clock-names: from common clock binding: must be "cec". 78- clock-names: from common clock binding: must be "cec".
79- reg-names : Names of maps with programmable addresses.
80 It can contain any map needing a non-default address.
81 Possible maps names are : "main", "edid", "cec", "packet"
73 82
74Required nodes: 83Required nodes:
75 84
@@ -88,7 +97,12 @@ Example
88 97
89 adv7511w: hdmi@39 { 98 adv7511w: hdmi@39 {
90 compatible = "adi,adv7511w"; 99 compatible = "adi,adv7511w";
91 reg = <39>; 100 /*
101 * The EDID page will be accessible on address 0x66 on the I2C
102 * bus. All other maps continue to use their default addresses.
103 */
104 reg = <0x39>, <0x66>;
105 reg-names = "main", "edid";
92 interrupt-parent = <&gpio3>; 106 interrupt-parent = <&gpio3>;
93 interrupts = <29 IRQ_TYPE_EDGE_FALLING>; 107 interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
94 clocks = <&cec_clock>; 108 clocks = <&cec_clock>;
diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt
new file mode 100644
index 000000000000..f5725bb6c61c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt
@@ -0,0 +1,133 @@
1Cadence DSI bridge
2==================
3
4The Cadence DSI bridge is a DPI to DSI bridge supporting up to 4 DSI lanes.
5
6Required properties:
7- compatible: should be set to "cdns,dsi".
8- reg: physical base address and length of the controller's registers.
9- interrupts: interrupt line connected to the DSI bridge.
10- clocks: DSI bridge clocks.
11- clock-names: must contain "dsi_p_clk" and "dsi_sys_clk".
12- phys: phandle link to the MIPI D-PHY controller.
13- phy-names: must contain "dphy".
14- #address-cells: must be set to 1.
15- #size-cells: must be set to 0.
16
17Optional properties:
18- resets: DSI reset lines.
19- reset-names: can contain "dsi_p_rst".
20
21Required subnodes:
22- ports: Ports as described in Documentation/devicetree/bindings/graph.txt.
23 2 ports are available:
24 * port 0: this port is only needed if some of your DSI devices are
25 controlled through an external bus like I2C or SPI. Can have at
26 most 4 endpoints. The endpoint number is directly encoding the
27 DSI virtual channel used by this device.
28 * port 1: represents the DPI input.
29 Other ports will be added later to support the new kind of inputs.
30
31- one subnode per DSI device connected on the DSI bus. Each DSI device should
32 contain a reg property encoding its virtual channel.
33
34Cadence DPHY
35============
36
37Cadence DPHY block.
38
39Required properties:
40- compatible: should be set to "cdns,dphy".
41- reg: physical base address and length of the DPHY registers.
42- clocks: DPHY reference clocks.
43- clock-names: must contain "psm" and "pll_ref".
44- #phy-cells: must be set to 0.
45
46
47Example:
48 dphy0: dphy@fd0e0000{
49 compatible = "cdns,dphy";
50 reg = <0x0 0xfd0e0000 0x0 0x1000>;
51 clocks = <&psm_clk>, <&pll_ref_clk>;
52 clock-names = "psm", "pll_ref";
53 #phy-cells = <0>;
54 };
55
56 dsi0: dsi@fd0c0000 {
57 compatible = "cdns,dsi";
58 reg = <0x0 0xfd0c0000 0x0 0x1000>;
59 clocks = <&pclk>, <&sysclk>;
60 clock-names = "dsi_p_clk", "dsi_sys_clk";
61 interrupts = <1>;
62 phys = <&dphy0>;
63 phy-names = "dphy";
64 #address-cells = <1>;
65 #size-cells = <0>;
66
67 ports {
68 #address-cells = <1>;
69 #size-cells = <0>;
70
71 port@1 {
72 reg = <1>;
73 dsi0_dpi_input: endpoint {
74 remote-endpoint = <&xxx_dpi_output>;
75 };
76 };
77 };
78
79 panel: dsi-dev@0 {
80 compatible = "<vendor,panel>";
81 reg = <0>;
82 };
83 };
84
85or
86
87 dsi0: dsi@fd0c0000 {
88 compatible = "cdns,dsi";
89 reg = <0x0 0xfd0c0000 0x0 0x1000>;
90 clocks = <&pclk>, <&sysclk>;
91 clock-names = "dsi_p_clk", "dsi_sys_clk";
92 interrupts = <1>;
93 phys = <&dphy1>;
94 phy-names = "dphy";
95 #address-cells = <1>;
96 #size-cells = <0>;
97
98 ports {
99 #address-cells = <1>;
100 #size-cells = <0>;
101
102 port@0 {
103 reg = <0>;
104 #address-cells = <1>;
105 #size-cells = <0>;
106
107 dsi0_output: endpoint@0 {
108 reg = <0>;
109 remote-endpoint = <&dsi_panel_input>;
110 };
111 };
112
113 port@1 {
114 reg = <1>;
115 dsi0_dpi_input: endpoint {
116 remote-endpoint = <&xxx_dpi_output>;
117 };
118 };
119 };
120 };
121
122 i2c@xxx {
123 panel: panel@59 {
124 compatible = "<vendor,panel>";
125 reg = <0x59>;
126
127 port {
128 dsi_panel_input: endpoint {
129 remote-endpoint = <&dsi0_output>;
130 };
131 };
132 };
133 };
diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt b/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
index 3a72a103a18a..a41d280c3f9f 100644
--- a/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
@@ -14,6 +14,7 @@ Required properties:
14- compatible : Shall contain one or more of 14- compatible : Shall contain one or more of
15 - "renesas,r8a7795-hdmi" for R8A7795 (R-Car H3) compatible HDMI TX 15 - "renesas,r8a7795-hdmi" for R8A7795 (R-Car H3) compatible HDMI TX
16 - "renesas,r8a7796-hdmi" for R8A7796 (R-Car M3-W) compatible HDMI TX 16 - "renesas,r8a7796-hdmi" for R8A7796 (R-Car M3-W) compatible HDMI TX
17 - "renesas,r8a77965-hdmi" for R8A77965 (R-Car M3-N) compatible HDMI TX
17 - "renesas,rcar-gen3-hdmi" for the generic R-Car Gen3 compatible HDMI TX 18 - "renesas,rcar-gen3-hdmi" for the generic R-Car Gen3 compatible HDMI TX
18 19
19 When compatible with generic versions, nodes must list the SoC-specific 20 When compatible with generic versions, nodes must list the SoC-specific
diff --git a/Documentation/devicetree/bindings/display/bridge/tda998x.txt b/Documentation/devicetree/bindings/display/bridge/tda998x.txt
index 24cc2466185a..1a4eaca40d94 100644
--- a/Documentation/devicetree/bindings/display/bridge/tda998x.txt
+++ b/Documentation/devicetree/bindings/display/bridge/tda998x.txt
@@ -27,6 +27,9 @@ Optional properties:
27 in question is used. The implementation allows one or two DAIs. If two 27 in question is used. The implementation allows one or two DAIs. If two
28 DAIs are defined, they must be of different type. 28 DAIs are defined, they must be of different type.
29 29
30 - nxp,calib-gpios: calibration GPIO, which must correspond with the
31 gpio used for the TDA998x interrupt pin.
32
30[1] Documentation/sound/alsa/soc/DAI.txt 33[1] Documentation/sound/alsa/soc/DAI.txt
31[2] include/dt-bindings/display/tda998x.h 34[2] include/dt-bindings/display/tda998x.h
32 35
diff --git a/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.txt b/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.txt
new file mode 100644
index 000000000000..37f0c04d5a28
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.txt
@@ -0,0 +1,60 @@
1Thine Electronics THC63LVD1024 LVDS decoder
2-------------------------------------------
3
4The THC63LVD1024 is a dual link LVDS receiver designed to convert LVDS streams
5to parallel data outputs. The chip supports single/dual input/output modes,
6handling up to two LVDS input streams and up to two digital CMOS/TTL outputs.
7
8Single or dual operation mode, output data mapping and DDR output modes are
9configured through input signals and the chip does not expose any control bus.
10
11Required properties:
12- compatible: Shall be "thine,thc63lvd1024"
13- vcc-supply: Power supply for TTL output, TTL CLOCKOUT signal, LVDS input,
14 PPL and digital circuitry
15
16Optional properties:
17- powerdown-gpios: Power down GPIO signal, pin name "/PDWN". Active low
18- oe-gpios: Output enable GPIO signal, pin name "OE". Active high
19
20The THC63LVD1024 video port connections are modeled according
21to OF graph bindings specified by Documentation/devicetree/bindings/graph.txt
22
23Required video port nodes:
24- port@0: First LVDS input port
25- port@2: First digital CMOS/TTL parallel output
26
27Optional video port nodes:
28- port@1: Second LVDS input port
29- port@3: Second digital CMOS/TTL parallel output
30
31Example:
32--------
33
34 thc63lvd1024: lvds-decoder {
35 compatible = "thine,thc63lvd1024";
36
37 vcc-supply = <&reg_lvds_vcc>;
38 powerdown-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
39
40 ports {
41 #address-cells = <1>;
42 #size-cells = <0>;
43
44 port@0 {
45 reg = <0>;
46
47 lvds_dec_in_0: endpoint {
48 remote-endpoint = <&lvds_out>;
49 };
50 };
51
52 port@2{
53 reg = <2>;
54
55 lvds_dec_out_2: endpoint {
56 remote-endpoint = <&adv7511_in>;
57 };
58 };
59 };
60 };
diff --git a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt b/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt
index fc2588292a68..775193e1c641 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt
@@ -19,7 +19,8 @@ Required properties:
19 clock-names property. 19 clock-names property.
20- clock-names: list of clock names sorted in the same order as the clocks 20- clock-names: list of clock names sorted in the same order as the clocks
21 property. Must contain "pclk", "aclk_decon", "aclk_smmu_decon0x", 21 property. Must contain "pclk", "aclk_decon", "aclk_smmu_decon0x",
22 "aclk_xiu_decon0x", "pclk_smmu_decon0x", clk_decon_vclk", 22 "aclk_xiu_decon0x", "pclk_smmu_decon0x", "aclk_smmu_decon1x",
23 "aclk_xiu_decon1x", "pclk_smmu_decon1x", clk_decon_vclk",
23 "sclk_decon_eclk" 24 "sclk_decon_eclk"
24- ports: contains a port which is connected to mic node. address-cells and 25- ports: contains a port which is connected to mic node. address-cells and
25 size-cells must 1 and 0, respectively. 26 size-cells must 1 and 0, respectively.
@@ -34,10 +35,14 @@ decon: decon@13800000 {
34 clocks = <&cmu_disp CLK_ACLK_DECON>, <&cmu_disp CLK_ACLK_SMMU_DECON0X>, 35 clocks = <&cmu_disp CLK_ACLK_DECON>, <&cmu_disp CLK_ACLK_SMMU_DECON0X>,
35 <&cmu_disp CLK_ACLK_XIU_DECON0X>, 36 <&cmu_disp CLK_ACLK_XIU_DECON0X>,
36 <&cmu_disp CLK_PCLK_SMMU_DECON0X>, 37 <&cmu_disp CLK_PCLK_SMMU_DECON0X>,
38 <&cmu_disp CLK_ACLK_SMMU_DECON1X>,
39 <&cmu_disp CLK_ACLK_XIU_DECON1X>,
40 <&cmu_disp CLK_PCLK_SMMU_DECON1X>,
37 <&cmu_disp CLK_SCLK_DECON_VCLK>, 41 <&cmu_disp CLK_SCLK_DECON_VCLK>,
38 <&cmu_disp CLK_SCLK_DECON_ECLK>; 42 <&cmu_disp CLK_SCLK_DECON_ECLK>;
39 clock-names = "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x", 43 clock-names = "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x",
40 "pclk_smmu_decon0x", "sclk_decon_vclk", "sclk_decon_eclk"; 44 "pclk_smmu_decon0x", "aclk_smmu_decon1x", "aclk_xiu_decon1x",
45 "pclk_smmu_decon1x", "sclk_decon_vclk", "sclk_decon_eclk";
41 interrupt-names = "vsync", "lcd_sys"; 46 interrupt-names = "vsync", "lcd_sys";
42 interrupts = <0 202 0>, <0 203 0>; 47 interrupts = <0 202 0>, <0 203 0>;
43 48
diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt
index c9cd17f99702..7c6854bd0a04 100644
--- a/Documentation/devicetree/bindings/display/renesas,du.txt
+++ b/Documentation/devicetree/bindings/display/renesas,du.txt
@@ -13,6 +13,7 @@ Required Properties:
13 - "renesas,du-r8a7794" for R8A7794 (R-Car E2) compatible DU 13 - "renesas,du-r8a7794" for R8A7794 (R-Car E2) compatible DU
14 - "renesas,du-r8a7795" for R8A7795 (R-Car H3) compatible DU 14 - "renesas,du-r8a7795" for R8A7795 (R-Car H3) compatible DU
15 - "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU 15 - "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU
16 - "renesas,du-r8a77965" for R8A77965 (R-Car M3-N) compatible DU
16 - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU 17 - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU
17 - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU 18 - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU
18 19
@@ -47,20 +48,21 @@ bindings specified in Documentation/devicetree/bindings/graph.txt.
47The following table lists for each supported model the port number 48The following table lists for each supported model the port number
48corresponding to each DU output. 49corresponding to each DU output.
49 50
50 Port0 Port1 Port2 Port3 51 Port0 Port1 Port2 Port3
51----------------------------------------------------------------------------- 52-----------------------------------------------------------------------------
52 R8A7743 (RZ/G1M) DPAD 0 LVDS 0 - - 53 R8A7743 (RZ/G1M) DPAD 0 LVDS 0 - -
53 R8A7745 (RZ/G1E) DPAD 0 DPAD 1 - - 54 R8A7745 (RZ/G1E) DPAD 0 DPAD 1 - -
54 R8A7779 (R-Car H1) DPAD 0 DPAD 1 - - 55 R8A7779 (R-Car H1) DPAD 0 DPAD 1 - -
55 R8A7790 (R-Car H2) DPAD 0 LVDS 0 LVDS 1 - 56 R8A7790 (R-Car H2) DPAD 0 LVDS 0 LVDS 1 -
56 R8A7791 (R-Car M2-W) DPAD 0 LVDS 0 - - 57 R8A7791 (R-Car M2-W) DPAD 0 LVDS 0 - -
57 R8A7792 (R-Car V2H) DPAD 0 DPAD 1 - - 58 R8A7792 (R-Car V2H) DPAD 0 DPAD 1 - -
58 R8A7793 (R-Car M2-N) DPAD 0 LVDS 0 - - 59 R8A7793 (R-Car M2-N) DPAD 0 LVDS 0 - -
59 R8A7794 (R-Car E2) DPAD 0 DPAD 1 - - 60 R8A7794 (R-Car E2) DPAD 0 DPAD 1 - -
60 R8A7795 (R-Car H3) DPAD 0 HDMI 0 HDMI 1 LVDS 0 61 R8A7795 (R-Car H3) DPAD 0 HDMI 0 HDMI 1 LVDS 0
61 R8A7796 (R-Car M3-W) DPAD 0 HDMI 0 LVDS 0 - 62 R8A7796 (R-Car M3-W) DPAD 0 HDMI 0 LVDS 0 -
62 R8A77970 (R-Car V3M) DPAD 0 LVDS 0 - - 63 R8A77965 (R-Car M3-N) DPAD 0 HDMI 0 LVDS 0 -
63 R8A77995 (R-Car D3) DPAD 0 LVDS 0 LVDS 1 - 64 R8A77970 (R-Car V3M) DPAD 0 LVDS 0 - -
65 R8A77995 (R-Car D3) DPAD 0 LVDS 0 LVDS 1 -
64 66
65 67
66Example: R8A7795 (R-Car H3) ES2.0 DU 68Example: R8A7795 (R-Car H3) ES2.0 DU
diff --git a/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
new file mode 100644
index 000000000000..6a6cf5de08b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/sunxi/sun6i-dsi.txt
@@ -0,0 +1,93 @@
1Allwinner A31 DSI Encoder
2=========================
3
4The DSI pipeline consists of two separate blocks: the DSI controller
5itself, and its associated D-PHY.
6
7DSI Encoder
8-----------
9
10The DSI Encoder generates the DSI signal from the TCON's.
11
12Required properties:
13 - compatible: value must be one of:
14 * allwinner,sun6i-a31-mipi-dsi
15 - reg: base address and size of memory-mapped region
16 - interrupts: interrupt associated to this IP
17 - clocks: phandles to the clocks feeding the DSI encoder
18 * bus: the DSI interface clock
19 * mod: the DSI module clock
20 - clock-names: the clock names mentioned above
21 - phys: phandle to the D-PHY
22 - phy-names: must be "dphy"
23 - resets: phandle to the reset controller driving the encoder
24
25 - ports: A ports node with endpoint definitions as defined in
26 Documentation/devicetree/bindings/media/video-interfaces.txt. The
27 first port should be the input endpoint, usually coming from the
28 associated TCON.
29
30Any MIPI-DSI device attached to this should be described according to
31the bindings defined in ../mipi-dsi-bus.txt
32
33D-PHY
34-----
35
36Required properties:
37 - compatible: value must be one of:
38 * allwinner,sun6i-a31-mipi-dphy
39 - reg: base address and size of memory-mapped region
40 - clocks: phandles to the clocks feeding the DSI encoder
41 * bus: the DSI interface clock
42 * mod: the DSI module clock
43 - clock-names: the clock names mentioned above
44 - resets: phandle to the reset controller driving the encoder
45
46Example:
47
48dsi0: dsi@1ca0000 {
49 compatible = "allwinner,sun6i-a31-mipi-dsi";
50 reg = <0x01ca0000 0x1000>;
51 interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
52 clocks = <&ccu CLK_BUS_MIPI_DSI>,
53 <&ccu CLK_DSI_SCLK>;
54 clock-names = "bus", "mod";
55 resets = <&ccu RST_BUS_MIPI_DSI>;
56 phys = <&dphy0>;
57 phy-names = "dphy";
58 #address-cells = <1>;
59 #size-cells = <0>;
60
61 panel@0 {
62 compatible = "bananapi,lhr050h41", "ilitek,ili9881c";
63 reg = <0>;
64 power-gpios = <&pio 1 7 GPIO_ACTIVE_HIGH>; /* PB07 */
65 reset-gpios = <&r_pio 0 5 GPIO_ACTIVE_LOW>; /* PL05 */
66 backlight = <&pwm_bl>;
67 };
68
69 ports {
70 #address-cells = <1>;
71 #size-cells = <0>;
72
73 port@0 {
74 #address-cells = <1>;
75 #size-cells = <0>;
76 reg = <0>;
77
78 dsi0_in_tcon0: endpoint {
79 remote-endpoint = <&tcon0_out_dsi0>;
80 };
81 };
82 };
83};
84
85dphy0: d-phy@1ca1000 {
86 compatible = "allwinner,sun6i-a31-mipi-dphy";
87 reg = <0x01ca1000 0x1000>;
88 clocks = <&ccu CLK_BUS_MIPI_DSI>,
89 <&ccu CLK_DSI_DPHY>;
90 clock-names = "bus", "mod";
91 resets = <&ccu RST_BUS_MIPI_DSI>;
92 #phy-cells = <0>;
93};
diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt
new file mode 100644
index 000000000000..c907aa8dd755
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt
@@ -0,0 +1,28 @@
1Broadcom V3D GPU
2
3Only the Broadcom V3D 3.x and newer GPUs are covered by this binding.
4For V3D 2.x, see brcm,bcm-vc4.txt.
5
6Required properties:
7- compatible: Should be "brcm,7268-v3d" or "brcm,7278-v3d"
8- reg: Physical base addresses and lengths of the register areas
9- reg-names: Names for the register areas. The "hub", "bridge", and "core0"
10 register areas are always required. The "gca" register area
11 is required if the GCA cache controller is present.
12- interrupts: The interrupt numbers. The first interrupt is for the hub,
13 while the following interrupts are for the cores.
14 See bindings/interrupt-controller/interrupts.txt
15
16Optional properties:
17- clocks: The core clock the unit runs on
18
19v3d {
20 compatible = "brcm,7268-v3d";
21 reg = <0xf1204000 0x100>,
22 <0xf1200000 0x4000>,
23 <0xf1208000 0x4000>,
24 <0xf1204100 0x100>;
25 reg-names = "bridge", "hub", "core0", "gca";
26 interrupts = <0 78 4>,
27 <0 77 4>;
28};
diff --git a/Documentation/devicetree/bindings/gpu/samsung-scaler.txt b/Documentation/devicetree/bindings/gpu/samsung-scaler.txt
new file mode 100644
index 000000000000..9c3d98105dfd
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/samsung-scaler.txt
@@ -0,0 +1,27 @@
1* Samsung Exynos Image Scaler
2
3Required properties:
4 - compatible : value should be one of the following:
5 (a) "samsung,exynos5420-scaler" for Scaler IP in Exynos5420
6 (b) "samsung,exynos5433-scaler" for Scaler IP in Exynos5433
7
8 - reg : Physical base address of the IP registers and length of memory
9 mapped region.
10
11 - interrupts : Interrupt specifier for scaler interrupt, according to format
12 specific to interrupt parent.
13
14 - clocks : Clock specifier for scaler clock, according to generic clock
15 bindings. (See Documentation/devicetree/bindings/clock/exynos*.txt)
16
17 - clock-names : Names of clocks. For exynos scaler, it should be "mscl"
18 on 5420 and "pclk", "aclk" and "aclk_xiu" on 5433.
19
20Example:
21 scaler@12800000 {
22 compatible = "samsung,exynos5420-scaler";
23 reg = <0x12800000 0x1294>;
24 interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH>;
25 clocks = <&clock CLK_MSCL0>;
26 clock-names = "mscl";
27 };
diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst
index e8c84419a2a1..f982558fc25d 100644
--- a/Documentation/gpu/drivers.rst
+++ b/Documentation/gpu/drivers.rst
@@ -10,8 +10,10 @@ GPU Driver Documentation
10 tegra 10 tegra
11 tinydrm 11 tinydrm
12 tve200 12 tve200
13 v3d
13 vc4 14 vc4
14 bridge/dw-hdmi 15 bridge/dw-hdmi
16 xen-front
15 17
16.. only:: subproject and html 18.. only:: subproject and html
17 19
diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index 41dc881b00dc..055df45596c1 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -58,6 +58,12 @@ Intel GVT-g Host Support(vGPU device model)
58.. kernel-doc:: drivers/gpu/drm/i915/intel_gvt.c 58.. kernel-doc:: drivers/gpu/drm/i915/intel_gvt.c
59 :internal: 59 :internal:
60 60
61Workarounds
62-----------
63
64.. kernel-doc:: drivers/gpu/drm/i915/intel_workarounds.c
65 :doc: Hardware workarounds
66
61Display Hardware Handling 67Display Hardware Handling
62========================= 68=========================
63 69
@@ -249,6 +255,103 @@ Memory Management and Command Submission
249This sections covers all things related to the GEM implementation in the 255This sections covers all things related to the GEM implementation in the
250i915 driver. 256i915 driver.
251 257
258Intel GPU Basics
259----------------
260
261An Intel GPU has multiple engines. There are several engine types.
262
263- RCS engine is for rendering 3D and performing compute, this is named
264 `I915_EXEC_RENDER` in user space.
265- BCS is a blitting (copy) engine, this is named `I915_EXEC_BLT` in user
266 space.
267- VCS is a video encode and decode engine, this is named `I915_EXEC_BSD`
268 in user space
269- VECS is video enhancement engine, this is named `I915_EXEC_VEBOX` in user
270 space.
271- The enumeration `I915_EXEC_DEFAULT` does not refer to specific engine;
272 instead it is to be used by user space to specify a default rendering
273 engine (for 3D) that may or may not be the same as RCS.
274
275The Intel GPU family is a family of integrated GPU's using Unified
276Memory Access. For having the GPU "do work", user space will feed the
277GPU batch buffers via one of the ioctls `DRM_IOCTL_I915_GEM_EXECBUFFER2`
278or `DRM_IOCTL_I915_GEM_EXECBUFFER2_WR`. Most such batchbuffers will
279instruct the GPU to perform work (for example rendering) and that work
280needs memory from which to read and memory to which to write. All memory
281is encapsulated within GEM buffer objects (usually created with the ioctl
282`DRM_IOCTL_I915_GEM_CREATE`). An ioctl providing a batchbuffer for the GPU
283to create will also list all GEM buffer objects that the batchbuffer reads
284and/or writes. For implementation details of memory management see
285`GEM BO Management Implementation Details`_.
286
287The i915 driver allows user space to create a context via the ioctl
288`DRM_IOCTL_I915_GEM_CONTEXT_CREATE` which is identified by a 32-bit
289integer. Such a context should be viewed by user-space as -loosely-
290analogous to the idea of a CPU process of an operating system. The i915
291driver guarantees that commands issued to a fixed context are to be
292executed so that writes of a previously issued command are seen by
293reads of following commands. Actions issued between different contexts
294(even if from the same file descriptor) are NOT given that guarantee
295and the only way to synchronize across contexts (even from the same
296file descriptor) is through the use of fences. At least as far back as
297Gen4, also have that a context carries with it a GPU HW context;
298the HW context is essentially (most of atleast) the state of a GPU.
299In addition to the ordering guarantees, the kernel will restore GPU
300state via HW context when commands are issued to a context, this saves
301user space the need to restore (most of atleast) the GPU state at the
302start of each batchbuffer. The non-deprecated ioctls to submit batchbuffer
303work can pass that ID (in the lower bits of drm_i915_gem_execbuffer2::rsvd1)
304to identify what context to use with the command.
305
306The GPU has its own memory management and address space. The kernel
307driver maintains the memory translation table for the GPU. For older
308GPUs (i.e. those before Gen8), there is a single global such translation
309table, a global Graphics Translation Table (GTT). For newer generation
310GPUs each context has its own translation table, called Per-Process
311Graphics Translation Table (PPGTT). Of important note, is that although
312PPGTT is named per-process it is actually per context. When user space
313submits a batchbuffer, the kernel walks the list of GEM buffer objects
314used by the batchbuffer and guarantees that not only is the memory of
315each such GEM buffer object resident but it is also present in the
316(PP)GTT. If the GEM buffer object is not yet placed in the (PP)GTT,
317then it is given an address. Two consequences of this are: the kernel
318needs to edit the batchbuffer submitted to write the correct value of
319the GPU address when a GEM BO is assigned a GPU address and the kernel
320might evict a different GEM BO from the (PP)GTT to make address room
321for another GEM BO. Consequently, the ioctls submitting a batchbuffer
322for execution also include a list of all locations within buffers that
323refer to GPU-addresses so that the kernel can edit the buffer correctly.
324This process is dubbed relocation.
325
326GEM BO Management Implementation Details
327----------------------------------------
328
329.. kernel-doc:: drivers/gpu/drm/i915/i915_vma.h
330 :doc: Virtual Memory Address
331
332Buffer Object Eviction
333----------------------
334
335This section documents the interface functions for evicting buffer
336objects to make space available in the virtual gpu address spaces. Note
337that this is mostly orthogonal to shrinking buffer objects caches, which
338has the goal to make main memory (shared with the gpu through the
339unified memory architecture) available.
340
341.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_evict.c
342 :internal:
343
344Buffer Object Memory Shrinking
345------------------------------
346
347This section documents the interface function for shrinking memory usage
348of buffer object caches. Shrinking is used to make main memory
349available. Note that this is mostly orthogonal to evicting buffer
350objects, which has the goal to make space in gpu virtual address spaces.
351
352.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_shrinker.c
353 :internal:
354
252Batchbuffer Parsing 355Batchbuffer Parsing
253------------------- 356-------------------
254 357
@@ -267,6 +370,12 @@ Batchbuffer Pools
267.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_batch_pool.c 370.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_batch_pool.c
268 :internal: 371 :internal:
269 372
373User Batchbuffer Execution
374--------------------------
375
376.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_execbuffer.c
377 :doc: User command execution
378
270Logical Rings, Logical Ring Contexts and Execlists 379Logical Rings, Logical Ring Contexts and Execlists
271-------------------------------------------------- 380--------------------------------------------------
272 381
@@ -312,28 +421,14 @@ Object Tiling IOCTLs
312.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_tiling.c 421.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_tiling.c
313 :doc: buffer object tiling 422 :doc: buffer object tiling
314 423
315Buffer Object Eviction 424WOPCM
316---------------------- 425=====
317
318This section documents the interface functions for evicting buffer
319objects to make space available in the virtual gpu address spaces. Note
320that this is mostly orthogonal to shrinking buffer objects caches, which
321has the goal to make main memory (shared with the gpu through the
322unified memory architecture) available.
323
324.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_evict.c
325 :internal:
326
327Buffer Object Memory Shrinking
328------------------------------
329 426
330This section documents the interface function for shrinking memory usage 427WOPCM Layout
331of buffer object caches. Shrinking is used to make main memory 428------------
332available. Note that this is mostly orthogonal to evicting buffer
333objects, which has the goal to make space in gpu virtual address spaces.
334 429
335.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_shrinker.c 430.. kernel-doc:: drivers/gpu/drm/i915/intel_wopcm.c
336 :internal: 431 :doc: WOPCM Layout
337 432
338GuC 433GuC
339=== 434===
@@ -359,6 +454,12 @@ GuC Firmware Layout
359.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_fwif.h 454.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_fwif.h
360 :doc: GuC Firmware Layout 455 :doc: GuC Firmware Layout
361 456
457GuC Address Space
458-----------------
459
460.. kernel-doc:: drivers/gpu/drm/i915/intel_guc.c
461 :doc: GuC Address Space
462
362Tracing 463Tracing
363======= 464=======
364 465
diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
index 6b28b014cb7d..07ed22ea3bd6 100644
--- a/Documentation/gpu/kms-properties.csv
+++ b/Documentation/gpu/kms-properties.csv
@@ -98,5 +98,4 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD
98,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD 98,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD
99,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD 99,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD
100,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD 100,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD
101rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD
102,,"""colorkey""",RANGE,"Min=0, Max=0x01ffffff",Plane,TBD 101,,"""colorkey""",RANGE,"Min=0, Max=0x01ffffff",Plane,TBD
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index f4d0b3476d9c..a7c150d6b63f 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -212,6 +212,24 @@ probably use drm_fb_helper_fbdev_teardown().
212 212
213Contact: Maintainer of the driver you plan to convert 213Contact: Maintainer of the driver you plan to convert
214 214
215Clean up mmap forwarding
216------------------------
217
218A lot of drivers forward gem mmap calls to dma-buf mmap for imported buffers.
219And also a lot of them forward dma-buf mmap to the gem mmap implementations.
220Would be great to refactor this all into a set of small common helpers.
221
222Contact: Daniel Vetter
223
224Put a reservation_object into drm_gem_object
225--------------------------------------------
226
227This would remove the need for the ->gem_prime_res_obj callback. It would also
228allow us to implement generic helpers for waiting for a bo, allowing for quite a
229bit of refactoring in the various wait ioctl implementations.
230
231Contact: Daniel Vetter
232
215idr_init_base() 233idr_init_base()
216--------------- 234---------------
217 235
diff --git a/Documentation/gpu/xen-front.rst b/Documentation/gpu/xen-front.rst
new file mode 100644
index 000000000000..d988da7d1983
--- /dev/null
+++ b/Documentation/gpu/xen-front.rst
@@ -0,0 +1,31 @@
1====================================================
2 drm/xen-front Xen para-virtualized frontend driver
3====================================================
4
5This frontend driver implements Xen para-virtualized display
6according to the display protocol described at
7include/xen/interface/io/displif.h
8
9Driver modes of operation in terms of display buffers used
10==========================================================
11
12.. kernel-doc:: drivers/gpu/drm/xen/xen_drm_front.h
13 :doc: Driver modes of operation in terms of display buffers used
14
15Buffers allocated by the frontend driver
16----------------------------------------
17
18.. kernel-doc:: drivers/gpu/drm/xen/xen_drm_front.h
19 :doc: Buffers allocated by the frontend driver
20
21Buffers allocated by the backend
22--------------------------------
23
24.. kernel-doc:: drivers/gpu/drm/xen/xen_drm_front.h
25 :doc: Buffers allocated by the backend
26
27Driver limitations
28==================
29
30.. kernel-doc:: drivers/gpu/drm/xen/xen_drm_front.h
31 :doc: Driver limitations
diff --git a/MAINTAINERS b/MAINTAINERS
index 5c374d97c967..8ebb000a2fbf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -767,12 +767,14 @@ F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
767F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 767F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
768F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c 768F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
769F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c 769F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
770F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
770F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c 771F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c
771F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 772F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
772F: drivers/gpu/drm/amd/amdkfd/ 773F: drivers/gpu/drm/amd/amdkfd/
773F: drivers/gpu/drm/amd/include/cik_structs.h 774F: drivers/gpu/drm/amd/include/cik_structs.h
774F: drivers/gpu/drm/amd/include/kgd_kfd_interface.h 775F: drivers/gpu/drm/amd/include/kgd_kfd_interface.h
775F: drivers/gpu/drm/amd/include/vi_structs.h 776F: drivers/gpu/drm/amd/include/vi_structs.h
777F: drivers/gpu/drm/amd/include/v9_structs.h
776F: include/uapi/linux/kfd_ioctl.h 778F: include/uapi/linux/kfd_ioctl.h
777 779
778AMD SEATTLE DEVICE TREE SUPPORT 780AMD SEATTLE DEVICE TREE SUPPORT
@@ -4685,7 +4687,7 @@ F: Documentation/devicetree/bindings/display/exynos/
4685 4687
4686DRM DRIVERS FOR FREESCALE DCU 4688DRM DRIVERS FOR FREESCALE DCU
4687M: Stefan Agner <stefan@agner.ch> 4689M: Stefan Agner <stefan@agner.ch>
4688M: Alison Wang <alison.wang@freescale.com> 4690M: Alison Wang <alison.wang@nxp.com>
4689L: dri-devel@lists.freedesktop.org 4691L: dri-devel@lists.freedesktop.org
4690S: Supported 4692S: Supported
4691F: drivers/gpu/drm/fsl-dcu/ 4693F: drivers/gpu/drm/fsl-dcu/
@@ -4796,6 +4798,14 @@ S: Maintained
4796F: drivers/gpu/drm/omapdrm/ 4798F: drivers/gpu/drm/omapdrm/
4797F: Documentation/devicetree/bindings/display/ti/ 4799F: Documentation/devicetree/bindings/display/ti/
4798 4800
4801DRM DRIVERS FOR V3D
4802M: Eric Anholt <eric@anholt.net>
4803S: Supported
4804F: drivers/gpu/drm/v3d/
4805F: include/uapi/drm/v3d_drm.h
4806F: Documentation/devicetree/bindings/display/brcm,bcm-v3d.txt
4807T: git git://anongit.freedesktop.org/drm/drm-misc
4808
4799DRM DRIVERS FOR VC4 4809DRM DRIVERS FOR VC4
4800M: Eric Anholt <eric@anholt.net> 4810M: Eric Anholt <eric@anholt.net>
4801T: git git://github.com/anholt/linux 4811T: git git://github.com/anholt/linux
@@ -4842,6 +4852,15 @@ S: Maintained
4842F: drivers/gpu/drm/tinydrm/ 4852F: drivers/gpu/drm/tinydrm/
4843F: include/drm/tinydrm/ 4853F: include/drm/tinydrm/
4844 4854
4855DRM DRIVERS FOR XEN
4856M: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
4857T: git git://anongit.freedesktop.org/drm/drm-misc
4858L: dri-devel@lists.freedesktop.org
4859L: xen-devel@lists.xen.org
4860S: Supported
4861F: drivers/gpu/drm/xen/
4862F: Documentation/gpu/xen-front.rst
4863
4845DRM TTM SUBSYSTEM 4864DRM TTM SUBSYSTEM
4846M: Christian Koenig <christian.koenig@amd.com> 4865M: Christian Koenig <christian.koenig@amd.com>
4847M: Roger He <Hongbo.He@amd.com> 4866M: Roger He <Hongbo.He@amd.com>
diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h
index d615a89f774c..05e33f937ad0 100644
--- a/drivers/dma-buf/sync_debug.h
+++ b/drivers/dma-buf/sync_debug.h
@@ -62,8 +62,6 @@ struct sync_pt {
62 struct rb_node node; 62 struct rb_node node;
63}; 63};
64 64
65#ifdef CONFIG_SW_SYNC
66
67extern const struct file_operations sw_sync_debugfs_fops; 65extern const struct file_operations sw_sync_debugfs_fops;
68 66
69void sync_timeline_debug_add(struct sync_timeline *obj); 67void sync_timeline_debug_add(struct sync_timeline *obj);
@@ -72,12 +70,4 @@ void sync_file_debug_add(struct sync_file *fence);
72void sync_file_debug_remove(struct sync_file *fence); 70void sync_file_debug_remove(struct sync_file *fence);
73void sync_dump(void); 71void sync_dump(void);
74 72
75#else
76# define sync_timeline_debug_add(obj)
77# define sync_timeline_debug_remove(obj)
78# define sync_file_debug_add(fence)
79# define sync_file_debug_remove(fence)
80# define sync_dump()
81#endif
82
83#endif /* _LINUX_SYNC_H */ 73#endif /* _LINUX_SYNC_H */
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index deeefa7a1773..2a72d2feb76d 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -49,16 +49,17 @@ config DRM_DEBUG_MM
49 49
50 If in doubt, say "N". 50 If in doubt, say "N".
51 51
52config DRM_DEBUG_MM_SELFTEST 52config DRM_DEBUG_SELFTEST
53 tristate "kselftests for DRM range manager (struct drm_mm)" 53 tristate "kselftests for DRM"
54 depends on DRM 54 depends on DRM
55 depends on DEBUG_KERNEL 55 depends on DEBUG_KERNEL
56 select PRIME_NUMBERS 56 select PRIME_NUMBERS
57 select DRM_LIB_RANDOM 57 select DRM_LIB_RANDOM
58 select DRM_KMS_HELPER
58 default n 59 default n
59 help 60 help
60 This option provides a kernel module that can be used to test 61 This option provides kernel modules that can be used to run
61 the DRM range manager (drm_mm) and its API. This option is not 62 various selftests on parts of the DRM api. This option is not
62 useful for distributions or general kernels, but only for kernel 63 useful for distributions or general kernels, but only for kernel
63 developers working on DRM and associated drivers. 64 developers working on DRM and associated drivers.
64 65
@@ -267,6 +268,8 @@ source "drivers/gpu/drm/amd/amdkfd/Kconfig"
267 268
268source "drivers/gpu/drm/imx/Kconfig" 269source "drivers/gpu/drm/imx/Kconfig"
269 270
271source "drivers/gpu/drm/v3d/Kconfig"
272
270source "drivers/gpu/drm/vc4/Kconfig" 273source "drivers/gpu/drm/vc4/Kconfig"
271 274
272source "drivers/gpu/drm/etnaviv/Kconfig" 275source "drivers/gpu/drm/etnaviv/Kconfig"
@@ -289,6 +292,8 @@ source "drivers/gpu/drm/pl111/Kconfig"
289 292
290source "drivers/gpu/drm/tve200/Kconfig" 293source "drivers/gpu/drm/tve200/Kconfig"
291 294
295source "drivers/gpu/drm/xen/Kconfig"
296
292# Keep legacy drivers last 297# Keep legacy drivers last
293 298
294menuconfig DRM_LEGACY 299menuconfig DRM_LEGACY
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 50093ff4479b..ef9f3dab287f 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -43,7 +43,7 @@ drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
43drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o 43drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
44 44
45obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o 45obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
46obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/ 46obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
47 47
48obj-$(CONFIG_DRM) += drm.o 48obj-$(CONFIG_DRM) += drm.o
49obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o 49obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
@@ -61,6 +61,7 @@ obj-$(CONFIG_DRM_MGA) += mga/
61obj-$(CONFIG_DRM_I810) += i810/ 61obj-$(CONFIG_DRM_I810) += i810/
62obj-$(CONFIG_DRM_I915) += i915/ 62obj-$(CONFIG_DRM_I915) += i915/
63obj-$(CONFIG_DRM_MGAG200) += mgag200/ 63obj-$(CONFIG_DRM_MGAG200) += mgag200/
64obj-$(CONFIG_DRM_V3D) += v3d/
64obj-$(CONFIG_DRM_VC4) += vc4/ 65obj-$(CONFIG_DRM_VC4) += vc4/
65obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/ 66obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
66obj-$(CONFIG_DRM_SIS) += sis/ 67obj-$(CONFIG_DRM_SIS) += sis/
@@ -103,3 +104,4 @@ obj-$(CONFIG_DRM_MXSFB) += mxsfb/
103obj-$(CONFIG_DRM_TINYDRM) += tinydrm/ 104obj-$(CONFIG_DRM_TINYDRM) += tinydrm/
104obj-$(CONFIG_DRM_PL111) += pl111/ 105obj-$(CONFIG_DRM_PL111) += pl111/
105obj-$(CONFIG_DRM_TVE200) += tve200/ 106obj-$(CONFIG_DRM_TVE200) += tve200/
107obj-$(CONFIG_DRM_XEN) += xen/
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index 2ca2b5154d52..bfd332c95b61 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -56,13 +56,18 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
56 56
57# add asic specific block 57# add asic specific block
58amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ 58amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
59 ci_smc.o ci_dpm.o dce_v8_0.o gfx_v7_0.o cik_sdma.o uvd_v4_2.o vce_v2_0.o \ 59 ci_smc.o ci_dpm.o dce_v8_0.o gfx_v7_0.o cik_sdma.o uvd_v4_2.o vce_v2_0.o
60 amdgpu_amdkfd_gfx_v7.o
61 60
62amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce_v6_0.o si_dpm.o si_smc.o 61amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce_v6_0.o si_dpm.o si_smc.o
63 62
64amdgpu-y += \ 63amdgpu-y += \
65 vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o 64 vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \
65 vega20_reg_init.o
66
67# add DF block
68amdgpu-y += \
69 df_v1_7.o \
70 df_v3_6.o
66 71
67# add GMC block 72# add GMC block
68amdgpu-y += \ 73amdgpu-y += \
@@ -126,11 +131,20 @@ amdgpu-y += \
126 vcn_v1_0.o 131 vcn_v1_0.o
127 132
128# add amdkfd interfaces 133# add amdkfd interfaces
134amdgpu-y += amdgpu_amdkfd.o
135
136ifneq ($(CONFIG_HSA_AMD),)
129amdgpu-y += \ 137amdgpu-y += \
130 amdgpu_amdkfd.o \
131 amdgpu_amdkfd_fence.o \ 138 amdgpu_amdkfd_fence.o \
132 amdgpu_amdkfd_gpuvm.o \ 139 amdgpu_amdkfd_gpuvm.o \
133 amdgpu_amdkfd_gfx_v8.o 140 amdgpu_amdkfd_gfx_v8.o \
141 amdgpu_amdkfd_gfx_v9.o
142
143ifneq ($(CONFIG_DRM_AMDGPU_CIK),)
144amdgpu-y += amdgpu_amdkfd_gfx_v7.o
145endif
146
147endif
134 148
135# add cgs 149# add cgs
136amdgpu-y += amdgpu_cgs.o 150amdgpu-y += amdgpu_cgs.o
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index c8b605f3dc05..a59c07590cee 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -129,6 +129,7 @@ extern int amdgpu_lbpw;
129extern int amdgpu_compute_multipipe; 129extern int amdgpu_compute_multipipe;
130extern int amdgpu_gpu_recovery; 130extern int amdgpu_gpu_recovery;
131extern int amdgpu_emu_mode; 131extern int amdgpu_emu_mode;
132extern uint amdgpu_smu_memory_pool_size;
132 133
133#ifdef CONFIG_DRM_AMDGPU_SI 134#ifdef CONFIG_DRM_AMDGPU_SI
134extern int amdgpu_si_support; 135extern int amdgpu_si_support;
@@ -137,6 +138,7 @@ extern int amdgpu_si_support;
137extern int amdgpu_cik_support; 138extern int amdgpu_cik_support;
138#endif 139#endif
139 140
141#define AMDGPU_SG_THRESHOLD (256*1024*1024)
140#define AMDGPU_DEFAULT_GTT_SIZE_MB 3072ULL /* 3GB by default */ 142#define AMDGPU_DEFAULT_GTT_SIZE_MB 3072ULL /* 3GB by default */
141#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 143#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
142#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ 144#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */
@@ -222,10 +224,10 @@ enum amdgpu_kiq_irq {
222 AMDGPU_CP_KIQ_IRQ_LAST 224 AMDGPU_CP_KIQ_IRQ_LAST
223}; 225};
224 226
225int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev, 227int amdgpu_device_ip_set_clockgating_state(void *dev,
226 enum amd_ip_block_type block_type, 228 enum amd_ip_block_type block_type,
227 enum amd_clockgating_state state); 229 enum amd_clockgating_state state);
228int amdgpu_device_ip_set_powergating_state(struct amdgpu_device *adev, 230int amdgpu_device_ip_set_powergating_state(void *dev,
229 enum amd_ip_block_type block_type, 231 enum amd_ip_block_type block_type,
230 enum amd_powergating_state state); 232 enum amd_powergating_state state);
231void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev, 233void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev,
@@ -681,6 +683,8 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
681int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, unsigned ring_id); 683int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, unsigned ring_id);
682 684
683void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr); 685void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr);
686void amdgpu_ctx_mgr_entity_cleanup(struct amdgpu_ctx_mgr *mgr);
687void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr);
684void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr); 688void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
685 689
686 690
@@ -771,9 +775,18 @@ struct amdgpu_rlc {
771 u32 starting_offsets_start; 775 u32 starting_offsets_start;
772 u32 reg_list_format_size_bytes; 776 u32 reg_list_format_size_bytes;
773 u32 reg_list_size_bytes; 777 u32 reg_list_size_bytes;
778 u32 reg_list_format_direct_reg_list_length;
779 u32 save_restore_list_cntl_size_bytes;
780 u32 save_restore_list_gpm_size_bytes;
781 u32 save_restore_list_srm_size_bytes;
774 782
775 u32 *register_list_format; 783 u32 *register_list_format;
776 u32 *register_restore; 784 u32 *register_restore;
785 u8 *save_restore_list_cntl;
786 u8 *save_restore_list_gpm;
787 u8 *save_restore_list_srm;
788
789 bool is_rlc_v2_1;
777}; 790};
778 791
779#define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES 792#define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES
@@ -867,6 +880,8 @@ struct amdgpu_gfx_config {
867 880
868 /* gfx configure feature */ 881 /* gfx configure feature */
869 uint32_t double_offchip_lds_buf; 882 uint32_t double_offchip_lds_buf;
883 /* cached value of DB_DEBUG2 */
884 uint32_t db_debug2;
870}; 885};
871 886
872struct amdgpu_cu_info { 887struct amdgpu_cu_info {
@@ -938,6 +953,12 @@ struct amdgpu_gfx {
938 uint32_t ce_feature_version; 953 uint32_t ce_feature_version;
939 uint32_t pfp_feature_version; 954 uint32_t pfp_feature_version;
940 uint32_t rlc_feature_version; 955 uint32_t rlc_feature_version;
956 uint32_t rlc_srlc_fw_version;
957 uint32_t rlc_srlc_feature_version;
958 uint32_t rlc_srlg_fw_version;
959 uint32_t rlc_srlg_feature_version;
960 uint32_t rlc_srls_fw_version;
961 uint32_t rlc_srls_feature_version;
941 uint32_t mec_feature_version; 962 uint32_t mec_feature_version;
942 uint32_t mec2_feature_version; 963 uint32_t mec2_feature_version;
943 struct amdgpu_ring gfx_ring[AMDGPU_MAX_GFX_RINGS]; 964 struct amdgpu_ring gfx_ring[AMDGPU_MAX_GFX_RINGS];
@@ -1204,6 +1225,8 @@ struct amdgpu_asic_funcs {
1204 /* invalidate hdp read cache */ 1225 /* invalidate hdp read cache */
1205 void (*invalidate_hdp)(struct amdgpu_device *adev, 1226 void (*invalidate_hdp)(struct amdgpu_device *adev,
1206 struct amdgpu_ring *ring); 1227 struct amdgpu_ring *ring);
1228 /* check if the asic needs a full reset of if soft reset will work */
1229 bool (*need_full_reset)(struct amdgpu_device *adev);
1207}; 1230};
1208 1231
1209/* 1232/*
@@ -1368,7 +1391,19 @@ struct amdgpu_nbio_funcs {
1368 void (*detect_hw_virt)(struct amdgpu_device *adev); 1391 void (*detect_hw_virt)(struct amdgpu_device *adev);
1369}; 1392};
1370 1393
1371 1394struct amdgpu_df_funcs {
1395 void (*init)(struct amdgpu_device *adev);
1396 void (*enable_broadcast_mode)(struct amdgpu_device *adev,
1397 bool enable);
1398 u32 (*get_fb_channel_number)(struct amdgpu_device *adev);
1399 u32 (*get_hbm_channel_number)(struct amdgpu_device *adev);
1400 void (*update_medium_grain_clock_gating)(struct amdgpu_device *adev,
1401 bool enable);
1402 void (*get_clockgating_state)(struct amdgpu_device *adev,
1403 u32 *flags);
1404 void (*enable_ecc_force_par_wr_rmw)(struct amdgpu_device *adev,
1405 bool enable);
1406};
1372/* Define the HW IP blocks will be used in driver , add more if necessary */ 1407/* Define the HW IP blocks will be used in driver , add more if necessary */
1373enum amd_hw_ip_block_type { 1408enum amd_hw_ip_block_type {
1374 GC_HWIP = 1, 1409 GC_HWIP = 1,
@@ -1398,6 +1433,7 @@ enum amd_hw_ip_block_type {
1398struct amd_powerplay { 1433struct amd_powerplay {
1399 void *pp_handle; 1434 void *pp_handle;
1400 const struct amd_pm_funcs *pp_funcs; 1435 const struct amd_pm_funcs *pp_funcs;
1436 uint32_t pp_feature;
1401}; 1437};
1402 1438
1403#define AMDGPU_RESET_MAGIC_NUM 64 1439#define AMDGPU_RESET_MAGIC_NUM 64
@@ -1590,6 +1626,7 @@ struct amdgpu_device {
1590 uint32_t *reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE]; 1626 uint32_t *reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE];
1591 1627
1592 const struct amdgpu_nbio_funcs *nbio_funcs; 1628 const struct amdgpu_nbio_funcs *nbio_funcs;
1629 const struct amdgpu_df_funcs *df_funcs;
1593 1630
1594 /* delayed work_func for deferring clockgating during resume */ 1631 /* delayed work_func for deferring clockgating during resume */
1595 struct delayed_work late_init_work; 1632 struct delayed_work late_init_work;
@@ -1764,6 +1801,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
1764#define amdgpu_asic_get_config_memsize(adev) (adev)->asic_funcs->get_config_memsize((adev)) 1801#define amdgpu_asic_get_config_memsize(adev) (adev)->asic_funcs->get_config_memsize((adev))
1765#define amdgpu_asic_flush_hdp(adev, r) (adev)->asic_funcs->flush_hdp((adev), (r)) 1802#define amdgpu_asic_flush_hdp(adev, r) (adev)->asic_funcs->flush_hdp((adev), (r))
1766#define amdgpu_asic_invalidate_hdp(adev, r) (adev)->asic_funcs->invalidate_hdp((adev), (r)) 1803#define amdgpu_asic_invalidate_hdp(adev, r) (adev)->asic_funcs->invalidate_hdp((adev), (r))
1804#define amdgpu_asic_need_full_reset(adev) (adev)->asic_funcs->need_full_reset((adev))
1767#define amdgpu_gmc_flush_gpu_tlb(adev, vmid) (adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid)) 1805#define amdgpu_gmc_flush_gpu_tlb(adev, vmid) (adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid))
1768#define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr)) 1806#define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr))
1769#define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid)) 1807#define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid))
@@ -1790,6 +1828,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
1790#define amdgpu_ring_emit_rreg(r, d) (r)->funcs->emit_rreg((r), (d)) 1828#define amdgpu_ring_emit_rreg(r, d) (r)->funcs->emit_rreg((r), (d))
1791#define amdgpu_ring_emit_wreg(r, d, v) (r)->funcs->emit_wreg((r), (d), (v)) 1829#define amdgpu_ring_emit_wreg(r, d, v) (r)->funcs->emit_wreg((r), (d), (v))
1792#define amdgpu_ring_emit_reg_wait(r, d, v, m) (r)->funcs->emit_reg_wait((r), (d), (v), (m)) 1830#define amdgpu_ring_emit_reg_wait(r, d, v, m) (r)->funcs->emit_reg_wait((r), (d), (v), (m))
1831#define amdgpu_ring_emit_reg_write_reg_wait(r, d0, d1, v, m) (r)->funcs->emit_reg_write_reg_wait((r), (d0), (d1), (v), (m))
1793#define amdgpu_ring_emit_tmz(r, b) (r)->funcs->emit_tmz((r), (b)) 1832#define amdgpu_ring_emit_tmz(r, b) (r)->funcs->emit_tmz((r), (b))
1794#define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib))) 1833#define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib)))
1795#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r)) 1834#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index 12558044acd4..428e5eb3444f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -290,12 +290,11 @@ static int acp_hw_init(void *handle)
290 else if (r) 290 else if (r)
291 return r; 291 return r;
292 292
293 r = cgs_get_pci_resource(adev->acp.cgs_device, CGS_RESOURCE_TYPE_MMIO, 293 if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289)
294 0x5289, 0, &acp_base); 294 return -EINVAL;
295 if (r == -ENODEV) 295
296 return 0; 296 acp_base = adev->rmmio_base;
297 else if (r) 297
298 return r;
299 if (adev->asic_type != CHIP_STONEY) { 298 if (adev->asic_type != CHIP_STONEY) {
300 adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL); 299 adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);
301 if (adev->acp.acp_genpd == NULL) 300 if (adev->acp.acp_genpd == NULL)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
index 4d36203ffb11..8f6f45567bfa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -50,15 +50,21 @@ int amdgpu_amdkfd_init(void)
50 kgd2kfd = NULL; 50 kgd2kfd = NULL;
51 } 51 }
52 52
53
53#elif defined(CONFIG_HSA_AMD) 54#elif defined(CONFIG_HSA_AMD)
55
54 ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd); 56 ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd);
55 if (ret) 57 if (ret)
56 kgd2kfd = NULL; 58 kgd2kfd = NULL;
57 59
58#else 60#else
61 kgd2kfd = NULL;
59 ret = -ENOENT; 62 ret = -ENOENT;
60#endif 63#endif
64
65#if defined(CONFIG_HSA_AMD_MODULE) || defined(CONFIG_HSA_AMD)
61 amdgpu_amdkfd_gpuvm_init_mem_limits(); 66 amdgpu_amdkfd_gpuvm_init_mem_limits();
67#endif
62 68
63 return ret; 69 return ret;
64} 70}
@@ -92,8 +98,12 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
92 case CHIP_POLARIS11: 98 case CHIP_POLARIS11:
93 kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions(); 99 kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions();
94 break; 100 break;
101 case CHIP_VEGA10:
102 case CHIP_RAVEN:
103 kfd2kgd = amdgpu_amdkfd_gfx_9_0_get_functions();
104 break;
95 default: 105 default:
96 dev_dbg(adev->dev, "kfd not supported on this ASIC\n"); 106 dev_info(adev->dev, "kfd not supported on this ASIC\n");
97 return; 107 return;
98 } 108 }
99 109
@@ -175,6 +185,28 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
175 &gpu_resources.doorbell_physical_address, 185 &gpu_resources.doorbell_physical_address,
176 &gpu_resources.doorbell_aperture_size, 186 &gpu_resources.doorbell_aperture_size,
177 &gpu_resources.doorbell_start_offset); 187 &gpu_resources.doorbell_start_offset);
188 if (adev->asic_type >= CHIP_VEGA10) {
189 /* On SOC15 the BIF is involved in routing
190 * doorbells using the low 12 bits of the
191 * address. Communicate the assignments to
192 * KFD. KFD uses two doorbell pages per
193 * process in case of 64-bit doorbells so we
194 * can use each doorbell assignment twice.
195 */
196 gpu_resources.sdma_doorbell[0][0] =
197 AMDGPU_DOORBELL64_sDMA_ENGINE0;
198 gpu_resources.sdma_doorbell[0][1] =
199 AMDGPU_DOORBELL64_sDMA_ENGINE0 + 0x200;
200 gpu_resources.sdma_doorbell[1][0] =
201 AMDGPU_DOORBELL64_sDMA_ENGINE1;
202 gpu_resources.sdma_doorbell[1][1] =
203 AMDGPU_DOORBELL64_sDMA_ENGINE1 + 0x200;
204 /* Doorbells 0x0f0-0ff and 0x2f0-2ff are reserved for
205 * SDMA, IH and VCN. So don't use them for the CP.
206 */
207 gpu_resources.reserved_doorbell_mask = 0x1f0;
208 gpu_resources.reserved_doorbell_val = 0x0f0;
209 }
178 210
179 kgd2kfd->device_init(adev->kfd, &gpu_resources); 211 kgd2kfd->device_init(adev->kfd, &gpu_resources);
180 } 212 }
@@ -217,13 +249,19 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
217{ 249{
218 struct amdgpu_device *adev = (struct amdgpu_device *)kgd; 250 struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
219 struct amdgpu_bo *bo = NULL; 251 struct amdgpu_bo *bo = NULL;
252 struct amdgpu_bo_param bp;
220 int r; 253 int r;
221 uint64_t gpu_addr_tmp = 0; 254 uint64_t gpu_addr_tmp = 0;
222 void *cpu_ptr_tmp = NULL; 255 void *cpu_ptr_tmp = NULL;
223 256
224 r = amdgpu_bo_create(adev, size, PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, 257 memset(&bp, 0, sizeof(bp));
225 AMDGPU_GEM_CREATE_CPU_GTT_USWC, ttm_bo_type_kernel, 258 bp.size = size;
226 NULL, &bo); 259 bp.byte_align = PAGE_SIZE;
260 bp.domain = AMDGPU_GEM_DOMAIN_GTT;
261 bp.flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC;
262 bp.type = ttm_bo_type_kernel;
263 bp.resv = NULL;
264 r = amdgpu_bo_create(adev, &bp, &bo);
227 if (r) { 265 if (r) {
228 dev_err(adev->dev, 266 dev_err(adev->dev,
229 "failed to allocate BO for amdkfd (%d)\n", r); 267 "failed to allocate BO for amdkfd (%d)\n", r);
@@ -432,3 +470,44 @@ bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
432 470
433 return false; 471 return false;
434} 472}
473
474#if !defined(CONFIG_HSA_AMD_MODULE) && !defined(CONFIG_HSA_AMD)
475bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm)
476{
477 return false;
478}
479
480void amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo *bo)
481{
482}
483
484void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
485 struct amdgpu_vm *vm)
486{
487}
488
489struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f)
490{
491 return NULL;
492}
493
494int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem, struct mm_struct *mm)
495{
496 return 0;
497}
498
499struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void)
500{
501 return NULL;
502}
503
504struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void)
505{
506 return NULL;
507}
508
509struct kfd2kgd_calls *amdgpu_amdkfd_gfx_9_0_get_functions(void)
510{
511 return NULL;
512}
513#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index c2c2bea731e0..a8418a3f4e9d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -28,6 +28,7 @@
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/mm.h> 29#include <linux/mm.h>
30#include <linux/mmu_context.h> 30#include <linux/mmu_context.h>
31#include <linux/workqueue.h>
31#include <kgd_kfd_interface.h> 32#include <kgd_kfd_interface.h>
32#include <drm/ttm/ttm_execbuf_util.h> 33#include <drm/ttm/ttm_execbuf_util.h>
33#include "amdgpu_sync.h" 34#include "amdgpu_sync.h"
@@ -59,7 +60,9 @@ struct kgd_mem {
59 60
60 uint32_t mapping_flags; 61 uint32_t mapping_flags;
61 62
63 atomic_t invalid;
62 struct amdkfd_process_info *process_info; 64 struct amdkfd_process_info *process_info;
65 struct page **user_pages;
63 66
64 struct amdgpu_sync sync; 67 struct amdgpu_sync sync;
65 68
@@ -84,6 +87,9 @@ struct amdkfd_process_info {
84 struct list_head vm_list_head; 87 struct list_head vm_list_head;
85 /* List head for all KFD BOs that belong to a KFD process. */ 88 /* List head for all KFD BOs that belong to a KFD process. */
86 struct list_head kfd_bo_list; 89 struct list_head kfd_bo_list;
90 /* List of userptr BOs that are valid or invalid */
91 struct list_head userptr_valid_list;
92 struct list_head userptr_inval_list;
87 /* Lock to protect kfd_bo_list */ 93 /* Lock to protect kfd_bo_list */
88 struct mutex lock; 94 struct mutex lock;
89 95
@@ -91,6 +97,11 @@ struct amdkfd_process_info {
91 unsigned int n_vms; 97 unsigned int n_vms;
92 /* Eviction Fence */ 98 /* Eviction Fence */
93 struct amdgpu_amdkfd_fence *eviction_fence; 99 struct amdgpu_amdkfd_fence *eviction_fence;
100
101 /* MMU-notifier related fields */
102 atomic_t evicted_bos;
103 struct delayed_work restore_userptr_work;
104 struct pid *pid;
94}; 105};
95 106
96int amdgpu_amdkfd_init(void); 107int amdgpu_amdkfd_init(void);
@@ -104,12 +115,14 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev);
104void amdgpu_amdkfd_device_init(struct amdgpu_device *adev); 115void amdgpu_amdkfd_device_init(struct amdgpu_device *adev);
105void amdgpu_amdkfd_device_fini(struct amdgpu_device *adev); 116void amdgpu_amdkfd_device_fini(struct amdgpu_device *adev);
106 117
118int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem, struct mm_struct *mm);
107int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine, 119int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
108 uint32_t vmid, uint64_t gpu_addr, 120 uint32_t vmid, uint64_t gpu_addr,
109 uint32_t *ib_cmd, uint32_t ib_len); 121 uint32_t *ib_cmd, uint32_t ib_len);
110 122
111struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void); 123struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void);
112struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void); 124struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void);
125struct kfd2kgd_calls *amdgpu_amdkfd_gfx_9_0_get_functions(void);
113 126
114bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid); 127bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid);
115 128
@@ -143,14 +156,14 @@ uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd);
143 156
144/* GPUVM API */ 157/* GPUVM API */
145int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm, 158int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
146 void **process_info, 159 void **process_info,
147 struct dma_fence **ef); 160 struct dma_fence **ef);
148int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd, 161int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd,
149 struct file *filp, 162 struct file *filp,
150 void **vm, void **process_info, 163 void **vm, void **process_info,
151 struct dma_fence **ef); 164 struct dma_fence **ef);
152void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev, 165void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
153 struct amdgpu_vm *vm); 166 struct amdgpu_vm *vm);
154void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm); 167void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm);
155uint32_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm); 168uint32_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm);
156int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( 169int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index ea54e53172b9..0ff36d45a597 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -98,8 +98,6 @@ static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
98static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, 98static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
99 unsigned int vmid); 99 unsigned int vmid);
100 100
101static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
102 uint32_t hpd_size, uint64_t hpd_gpu_addr);
103static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id); 101static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
104static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, 102static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
105 uint32_t queue_id, uint32_t __user *wptr, 103 uint32_t queue_id, uint32_t __user *wptr,
@@ -183,7 +181,6 @@ static const struct kfd2kgd_calls kfd2kgd = {
183 .free_pasid = amdgpu_pasid_free, 181 .free_pasid = amdgpu_pasid_free,
184 .program_sh_mem_settings = kgd_program_sh_mem_settings, 182 .program_sh_mem_settings = kgd_program_sh_mem_settings,
185 .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, 183 .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
186 .init_pipeline = kgd_init_pipeline,
187 .init_interrupts = kgd_init_interrupts, 184 .init_interrupts = kgd_init_interrupts,
188 .hqd_load = kgd_hqd_load, 185 .hqd_load = kgd_hqd_load,
189 .hqd_sdma_load = kgd_hqd_sdma_load, 186 .hqd_sdma_load = kgd_hqd_sdma_load,
@@ -309,13 +306,6 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
309 return 0; 306 return 0;
310} 307}
311 308
312static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
313 uint32_t hpd_size, uint64_t hpd_gpu_addr)
314{
315 /* amdgpu owns the per-pipe state */
316 return 0;
317}
318
319static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id) 309static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
320{ 310{
321 struct amdgpu_device *adev = get_amdgpu_device(kgd); 311 struct amdgpu_device *adev = get_amdgpu_device(kgd);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
index 89264c9a5e9f..6ef9762b4b00 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -57,8 +57,6 @@ static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
57 uint32_t sh_mem_bases); 57 uint32_t sh_mem_bases);
58static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, 58static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
59 unsigned int vmid); 59 unsigned int vmid);
60static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
61 uint32_t hpd_size, uint64_t hpd_gpu_addr);
62static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id); 60static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
63static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, 61static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
64 uint32_t queue_id, uint32_t __user *wptr, 62 uint32_t queue_id, uint32_t __user *wptr,
@@ -141,7 +139,6 @@ static const struct kfd2kgd_calls kfd2kgd = {
141 .free_pasid = amdgpu_pasid_free, 139 .free_pasid = amdgpu_pasid_free,
142 .program_sh_mem_settings = kgd_program_sh_mem_settings, 140 .program_sh_mem_settings = kgd_program_sh_mem_settings,
143 .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, 141 .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
144 .init_pipeline = kgd_init_pipeline,
145 .init_interrupts = kgd_init_interrupts, 142 .init_interrupts = kgd_init_interrupts,
146 .hqd_load = kgd_hqd_load, 143 .hqd_load = kgd_hqd_load,
147 .hqd_sdma_load = kgd_hqd_sdma_load, 144 .hqd_sdma_load = kgd_hqd_sdma_load,
@@ -270,13 +267,6 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
270 return 0; 267 return 0;
271} 268}
272 269
273static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
274 uint32_t hpd_size, uint64_t hpd_gpu_addr)
275{
276 /* amdgpu owns the per-pipe state */
277 return 0;
278}
279
280static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id) 270static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
281{ 271{
282 struct amdgpu_device *adev = get_amdgpu_device(kgd); 272 struct amdgpu_device *adev = get_amdgpu_device(kgd);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
new file mode 100644
index 000000000000..f0c0d3953f69
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
@@ -0,0 +1,1043 @@
1/*
2 * Copyright 2014-2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#define pr_fmt(fmt) "kfd2kgd: " fmt
24
25#include <linux/module.h>
26#include <linux/fdtable.h>
27#include <linux/uaccess.h>
28#include <linux/firmware.h>
29#include <drm/drmP.h>
30#include "amdgpu.h"
31#include "amdgpu_amdkfd.h"
32#include "amdgpu_ucode.h"
33#include "soc15_hw_ip.h"
34#include "gc/gc_9_0_offset.h"
35#include "gc/gc_9_0_sh_mask.h"
36#include "vega10_enum.h"
37#include "sdma0/sdma0_4_0_offset.h"
38#include "sdma0/sdma0_4_0_sh_mask.h"
39#include "sdma1/sdma1_4_0_offset.h"
40#include "sdma1/sdma1_4_0_sh_mask.h"
41#include "athub/athub_1_0_offset.h"
42#include "athub/athub_1_0_sh_mask.h"
43#include "oss/osssys_4_0_offset.h"
44#include "oss/osssys_4_0_sh_mask.h"
45#include "soc15_common.h"
46#include "v9_structs.h"
47#include "soc15.h"
48#include "soc15d.h"
49
50/* HACK: MMHUB and GC both have VM-related register with the same
51 * names but different offsets. Define the MMHUB register we need here
52 * with a prefix. A proper solution would be to move the functions
53 * programming these registers into gfx_v9_0.c and mmhub_v1_0.c
54 * respectively.
55 */
56#define mmMMHUB_VM_INVALIDATE_ENG16_REQ 0x06f3
57#define mmMMHUB_VM_INVALIDATE_ENG16_REQ_BASE_IDX 0
58
59#define mmMMHUB_VM_INVALIDATE_ENG16_ACK 0x0705
60#define mmMMHUB_VM_INVALIDATE_ENG16_ACK_BASE_IDX 0
61
62#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32 0x072b
63#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 0
64#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32 0x072c
65#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 0
66
67#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32 0x074b
68#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 0
69#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32 0x074c
70#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 0
71
72#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32 0x076b
73#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 0
74#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32 0x076c
75#define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 0
76
77#define mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_LO32 0x0727
78#define mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_LO32_BASE_IDX 0
79#define mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_HI32 0x0728
80#define mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_HI32_BASE_IDX 0
81
82#define V9_PIPE_PER_MEC (4)
83#define V9_QUEUES_PER_PIPE_MEC (8)
84
85enum hqd_dequeue_request_type {
86 NO_ACTION = 0,
87 DRAIN_PIPE,
88 RESET_WAVES
89};
90
91/*
92 * Register access functions
93 */
94
95static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
96 uint32_t sh_mem_config,
97 uint32_t sh_mem_ape1_base, uint32_t sh_mem_ape1_limit,
98 uint32_t sh_mem_bases);
99static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
100 unsigned int vmid);
101static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
102static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
103 uint32_t queue_id, uint32_t __user *wptr,
104 uint32_t wptr_shift, uint32_t wptr_mask,
105 struct mm_struct *mm);
106static int kgd_hqd_dump(struct kgd_dev *kgd,
107 uint32_t pipe_id, uint32_t queue_id,
108 uint32_t (**dump)[2], uint32_t *n_regs);
109static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
110 uint32_t __user *wptr, struct mm_struct *mm);
111static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
112 uint32_t engine_id, uint32_t queue_id,
113 uint32_t (**dump)[2], uint32_t *n_regs);
114static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
115 uint32_t pipe_id, uint32_t queue_id);
116static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
117static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
118 enum kfd_preempt_type reset_type,
119 unsigned int utimeout, uint32_t pipe_id,
120 uint32_t queue_id);
121static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
122 unsigned int utimeout);
123static int kgd_address_watch_disable(struct kgd_dev *kgd);
124static int kgd_address_watch_execute(struct kgd_dev *kgd,
125 unsigned int watch_point_id,
126 uint32_t cntl_val,
127 uint32_t addr_hi,
128 uint32_t addr_lo);
129static int kgd_wave_control_execute(struct kgd_dev *kgd,
130 uint32_t gfx_index_val,
131 uint32_t sq_cmd);
132static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
133 unsigned int watch_point_id,
134 unsigned int reg_offset);
135
136static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd,
137 uint8_t vmid);
138static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
139 uint8_t vmid);
140static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
141 uint32_t page_table_base);
142static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
143static void set_scratch_backing_va(struct kgd_dev *kgd,
144 uint64_t va, uint32_t vmid);
145static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid);
146static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid);
147
148/* Because of REG_GET_FIELD() being used, we put this function in the
149 * asic specific file.
150 */
151static int amdgpu_amdkfd_get_tile_config(struct kgd_dev *kgd,
152 struct tile_config *config)
153{
154 struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
155
156 config->gb_addr_config = adev->gfx.config.gb_addr_config;
157
158 config->tile_config_ptr = adev->gfx.config.tile_mode_array;
159 config->num_tile_configs =
160 ARRAY_SIZE(adev->gfx.config.tile_mode_array);
161 config->macro_tile_config_ptr =
162 adev->gfx.config.macrotile_mode_array;
163 config->num_macro_tile_configs =
164 ARRAY_SIZE(adev->gfx.config.macrotile_mode_array);
165
166 return 0;
167}
168
169static const struct kfd2kgd_calls kfd2kgd = {
170 .init_gtt_mem_allocation = alloc_gtt_mem,
171 .free_gtt_mem = free_gtt_mem,
172 .get_local_mem_info = get_local_mem_info,
173 .get_gpu_clock_counter = get_gpu_clock_counter,
174 .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz,
175 .alloc_pasid = amdgpu_pasid_alloc,
176 .free_pasid = amdgpu_pasid_free,
177 .program_sh_mem_settings = kgd_program_sh_mem_settings,
178 .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
179 .init_interrupts = kgd_init_interrupts,
180 .hqd_load = kgd_hqd_load,
181 .hqd_sdma_load = kgd_hqd_sdma_load,
182 .hqd_dump = kgd_hqd_dump,
183 .hqd_sdma_dump = kgd_hqd_sdma_dump,
184 .hqd_is_occupied = kgd_hqd_is_occupied,
185 .hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
186 .hqd_destroy = kgd_hqd_destroy,
187 .hqd_sdma_destroy = kgd_hqd_sdma_destroy,
188 .address_watch_disable = kgd_address_watch_disable,
189 .address_watch_execute = kgd_address_watch_execute,
190 .wave_control_execute = kgd_wave_control_execute,
191 .address_watch_get_offset = kgd_address_watch_get_offset,
192 .get_atc_vmid_pasid_mapping_pasid =
193 get_atc_vmid_pasid_mapping_pasid,
194 .get_atc_vmid_pasid_mapping_valid =
195 get_atc_vmid_pasid_mapping_valid,
196 .get_fw_version = get_fw_version,
197 .set_scratch_backing_va = set_scratch_backing_va,
198 .get_tile_config = amdgpu_amdkfd_get_tile_config,
199 .get_cu_info = get_cu_info,
200 .get_vram_usage = amdgpu_amdkfd_get_vram_usage,
201 .create_process_vm = amdgpu_amdkfd_gpuvm_create_process_vm,
202 .acquire_process_vm = amdgpu_amdkfd_gpuvm_acquire_process_vm,
203 .destroy_process_vm = amdgpu_amdkfd_gpuvm_destroy_process_vm,
204 .get_process_page_dir = amdgpu_amdkfd_gpuvm_get_process_page_dir,
205 .set_vm_context_page_table_base = set_vm_context_page_table_base,
206 .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu,
207 .free_memory_of_gpu = amdgpu_amdkfd_gpuvm_free_memory_of_gpu,
208 .map_memory_to_gpu = amdgpu_amdkfd_gpuvm_map_memory_to_gpu,
209 .unmap_memory_to_gpu = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu,
210 .sync_memory = amdgpu_amdkfd_gpuvm_sync_memory,
211 .map_gtt_bo_to_kernel = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel,
212 .restore_process_bos = amdgpu_amdkfd_gpuvm_restore_process_bos,
213 .invalidate_tlbs = invalidate_tlbs,
214 .invalidate_tlbs_vmid = invalidate_tlbs_vmid,
215 .submit_ib = amdgpu_amdkfd_submit_ib,
216};
217
218struct kfd2kgd_calls *amdgpu_amdkfd_gfx_9_0_get_functions(void)
219{
220 return (struct kfd2kgd_calls *)&kfd2kgd;
221}
222
223static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
224{
225 return (struct amdgpu_device *)kgd;
226}
227
228static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe,
229 uint32_t queue, uint32_t vmid)
230{
231 struct amdgpu_device *adev = get_amdgpu_device(kgd);
232
233 mutex_lock(&adev->srbm_mutex);
234 soc15_grbm_select(adev, mec, pipe, queue, vmid);
235}
236
237static void unlock_srbm(struct kgd_dev *kgd)
238{
239 struct amdgpu_device *adev = get_amdgpu_device(kgd);
240
241 soc15_grbm_select(adev, 0, 0, 0, 0);
242 mutex_unlock(&adev->srbm_mutex);
243}
244
245static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
246 uint32_t queue_id)
247{
248 struct amdgpu_device *adev = get_amdgpu_device(kgd);
249
250 uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
251 uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
252
253 lock_srbm(kgd, mec, pipe, queue_id, 0);
254}
255
256static uint32_t get_queue_mask(struct amdgpu_device *adev,
257 uint32_t pipe_id, uint32_t queue_id)
258{
259 unsigned int bit = (pipe_id * adev->gfx.mec.num_queue_per_pipe +
260 queue_id) & 31;
261
262 return ((uint32_t)1) << bit;
263}
264
265static void release_queue(struct kgd_dev *kgd)
266{
267 unlock_srbm(kgd);
268}
269
270static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
271 uint32_t sh_mem_config,
272 uint32_t sh_mem_ape1_base,
273 uint32_t sh_mem_ape1_limit,
274 uint32_t sh_mem_bases)
275{
276 struct amdgpu_device *adev = get_amdgpu_device(kgd);
277
278 lock_srbm(kgd, 0, 0, 0, vmid);
279
280 WREG32(SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG), sh_mem_config);
281 WREG32(SOC15_REG_OFFSET(GC, 0, mmSH_MEM_BASES), sh_mem_bases);
282 /* APE1 no longer exists on GFX9 */
283
284 unlock_srbm(kgd);
285}
286
287static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
288 unsigned int vmid)
289{
290 struct amdgpu_device *adev = get_amdgpu_device(kgd);
291
292 /*
293 * We have to assume that there is no outstanding mapping.
294 * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 because
295 * a mapping is in progress or because a mapping finished
296 * and the SW cleared it.
297 * So the protocol is to always wait & clear.
298 */
299 uint32_t pasid_mapping = (pasid == 0) ? 0 : (uint32_t)pasid |
300 ATC_VMID0_PASID_MAPPING__VALID_MASK;
301
302 /*
303 * need to do this twice, once for gfx and once for mmhub
304 * for ATC add 16 to VMID for mmhub, for IH different registers.
305 * ATC_VMID0..15 registers are separate from ATC_VMID16..31.
306 */
307
308 WREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING) + vmid,
309 pasid_mapping);
310
311 while (!(RREG32(SOC15_REG_OFFSET(
312 ATHUB, 0,
313 mmATC_VMID_PASID_MAPPING_UPDATE_STATUS)) &
314 (1U << vmid)))
315 cpu_relax();
316
317 WREG32(SOC15_REG_OFFSET(ATHUB, 0,
318 mmATC_VMID_PASID_MAPPING_UPDATE_STATUS),
319 1U << vmid);
320
321 /* Mapping vmid to pasid also for IH block */
322 WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_VMID_0_LUT) + vmid,
323 pasid_mapping);
324
325 WREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID16_PASID_MAPPING) + vmid,
326 pasid_mapping);
327
328 while (!(RREG32(SOC15_REG_OFFSET(
329 ATHUB, 0,
330 mmATC_VMID_PASID_MAPPING_UPDATE_STATUS)) &
331 (1U << (vmid + 16))))
332 cpu_relax();
333
334 WREG32(SOC15_REG_OFFSET(ATHUB, 0,
335 mmATC_VMID_PASID_MAPPING_UPDATE_STATUS),
336 1U << (vmid + 16));
337
338 /* Mapping vmid to pasid also for IH block */
339 WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_VMID_0_LUT_MM) + vmid,
340 pasid_mapping);
341 return 0;
342}
343
344/* TODO - RING0 form of field is obsolete, seems to date back to SI
345 * but still works
346 */
347
348static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
349{
350 struct amdgpu_device *adev = get_amdgpu_device(kgd);
351 uint32_t mec;
352 uint32_t pipe;
353
354 mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
355 pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
356
357 lock_srbm(kgd, mec, pipe, 0, 0);
358
359 WREG32(SOC15_REG_OFFSET(GC, 0, mmCPC_INT_CNTL),
360 CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
361 CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
362
363 unlock_srbm(kgd);
364
365 return 0;
366}
367
368static uint32_t get_sdma_base_addr(struct amdgpu_device *adev,
369 unsigned int engine_id,
370 unsigned int queue_id)
371{
372 uint32_t base[2] = {
373 SOC15_REG_OFFSET(SDMA0, 0,
374 mmSDMA0_RLC0_RB_CNTL) - mmSDMA0_RLC0_RB_CNTL,
375 SOC15_REG_OFFSET(SDMA1, 0,
376 mmSDMA1_RLC0_RB_CNTL) - mmSDMA1_RLC0_RB_CNTL
377 };
378 uint32_t retval;
379
380 retval = base[engine_id] + queue_id * (mmSDMA0_RLC1_RB_CNTL -
381 mmSDMA0_RLC0_RB_CNTL);
382
383 pr_debug("sdma base address: 0x%x\n", retval);
384
385 return retval;
386}
387
388static inline struct v9_mqd *get_mqd(void *mqd)
389{
390 return (struct v9_mqd *)mqd;
391}
392
393static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd)
394{
395 return (struct v9_sdma_mqd *)mqd;
396}
397
398static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
399 uint32_t queue_id, uint32_t __user *wptr,
400 uint32_t wptr_shift, uint32_t wptr_mask,
401 struct mm_struct *mm)
402{
403 struct amdgpu_device *adev = get_amdgpu_device(kgd);
404 struct v9_mqd *m;
405 uint32_t *mqd_hqd;
406 uint32_t reg, hqd_base, data;
407
408 m = get_mqd(mqd);
409
410 acquire_queue(kgd, pipe_id, queue_id);
411
412 /* HIQ is set during driver init period with vmid set to 0*/
413 if (m->cp_hqd_vmid == 0) {
414 uint32_t value, mec, pipe;
415
416 mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
417 pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
418
419 pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n",
420 mec, pipe, queue_id);
421 value = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS));
422 value = REG_SET_FIELD(value, RLC_CP_SCHEDULERS, scheduler1,
423 ((mec << 5) | (pipe << 3) | queue_id | 0x80));
424 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS), value);
425 }
426
427 /* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */
428 mqd_hqd = &m->cp_mqd_base_addr_lo;
429 hqd_base = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR);
430
431 for (reg = hqd_base;
432 reg <= SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_HI); reg++)
433 WREG32(reg, mqd_hqd[reg - hqd_base]);
434
435
436 /* Activate doorbell logic before triggering WPTR poll. */
437 data = REG_SET_FIELD(m->cp_hqd_pq_doorbell_control,
438 CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
439 WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL), data);
440
441 if (wptr) {
442 /* Don't read wptr with get_user because the user
443 * context may not be accessible (if this function
444 * runs in a work queue). Instead trigger a one-shot
445 * polling read from memory in the CP. This assumes
446 * that wptr is GPU-accessible in the queue's VMID via
447 * ATC or SVM. WPTR==RPTR before starting the poll so
448 * the CP starts fetching new commands from the right
449 * place.
450 *
451 * Guessing a 64-bit WPTR from a 32-bit RPTR is a bit
452 * tricky. Assume that the queue didn't overflow. The
453 * number of valid bits in the 32-bit RPTR depends on
454 * the queue size. The remaining bits are taken from
455 * the saved 64-bit WPTR. If the WPTR wrapped, add the
456 * queue size.
457 */
458 uint32_t queue_size =
459 2 << REG_GET_FIELD(m->cp_hqd_pq_control,
460 CP_HQD_PQ_CONTROL, QUEUE_SIZE);
461 uint64_t guessed_wptr = m->cp_hqd_pq_rptr & (queue_size - 1);
462
463 if ((m->cp_hqd_pq_wptr_lo & (queue_size - 1)) < guessed_wptr)
464 guessed_wptr += queue_size;
465 guessed_wptr += m->cp_hqd_pq_wptr_lo & ~(queue_size - 1);
466 guessed_wptr += (uint64_t)m->cp_hqd_pq_wptr_hi << 32;
467
468 WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_LO),
469 lower_32_bits(guessed_wptr));
470 WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_HI),
471 upper_32_bits(guessed_wptr));
472 WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_POLL_ADDR),
473 lower_32_bits((uintptr_t)wptr));
474 WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI),
475 upper_32_bits((uintptr_t)wptr));
476 WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_PQ_WPTR_POLL_CNTL1),
477 get_queue_mask(adev, pipe_id, queue_id));
478 }
479
480 /* Start the EOP fetcher */
481 WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_EOP_RPTR),
482 REG_SET_FIELD(m->cp_hqd_eop_rptr,
483 CP_HQD_EOP_RPTR, INIT_FETCHER, 1));
484
485 data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
486 WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE), data);
487
488 release_queue(kgd);
489
490 return 0;
491}
492
493static int kgd_hqd_dump(struct kgd_dev *kgd,
494 uint32_t pipe_id, uint32_t queue_id,
495 uint32_t (**dump)[2], uint32_t *n_regs)
496{
497 struct amdgpu_device *adev = get_amdgpu_device(kgd);
498 uint32_t i = 0, reg;
499#define HQD_N_REGS 56
500#define DUMP_REG(addr) do { \
501 if (WARN_ON_ONCE(i >= HQD_N_REGS)) \
502 break; \
503 (*dump)[i][0] = (addr) << 2; \
504 (*dump)[i++][1] = RREG32(addr); \
505 } while (0)
506
507 *dump = kmalloc(HQD_N_REGS*2*sizeof(uint32_t), GFP_KERNEL);
508 if (*dump == NULL)
509 return -ENOMEM;
510
511 acquire_queue(kgd, pipe_id, queue_id);
512
513 for (reg = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR);
514 reg <= SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_HI); reg++)
515 DUMP_REG(reg);
516
517 release_queue(kgd);
518
519 WARN_ON_ONCE(i != HQD_N_REGS);
520 *n_regs = i;
521
522 return 0;
523}
524
525static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
526 uint32_t __user *wptr, struct mm_struct *mm)
527{
528 struct amdgpu_device *adev = get_amdgpu_device(kgd);
529 struct v9_sdma_mqd *m;
530 uint32_t sdma_base_addr, sdmax_gfx_context_cntl;
531 unsigned long end_jiffies;
532 uint32_t data;
533 uint64_t data64;
534 uint64_t __user *wptr64 = (uint64_t __user *)wptr;
535
536 m = get_sdma_mqd(mqd);
537 sdma_base_addr = get_sdma_base_addr(adev, m->sdma_engine_id,
538 m->sdma_queue_id);
539 sdmax_gfx_context_cntl = m->sdma_engine_id ?
540 SOC15_REG_OFFSET(SDMA1, 0, mmSDMA1_GFX_CONTEXT_CNTL) :
541 SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_GFX_CONTEXT_CNTL);
542
543 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
544 m->sdmax_rlcx_rb_cntl & (~SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK));
545
546 end_jiffies = msecs_to_jiffies(2000) + jiffies;
547 while (true) {
548 data = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
549 if (data & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK)
550 break;
551 if (time_after(jiffies, end_jiffies))
552 return -ETIME;
553 usleep_range(500, 1000);
554 }
555 data = RREG32(sdmax_gfx_context_cntl);
556 data = REG_SET_FIELD(data, SDMA0_GFX_CONTEXT_CNTL,
557 RESUME_CTX, 0);
558 WREG32(sdmax_gfx_context_cntl, data);
559
560 WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL_OFFSET,
561 m->sdmax_rlcx_doorbell_offset);
562
563 data = REG_SET_FIELD(m->sdmax_rlcx_doorbell, SDMA0_RLC0_DOORBELL,
564 ENABLE, 1);
565 WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, data);
566 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, m->sdmax_rlcx_rb_rptr);
567 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_HI,
568 m->sdmax_rlcx_rb_rptr_hi);
569
570 WREG32(sdma_base_addr + mmSDMA0_RLC0_MINOR_PTR_UPDATE, 1);
571 if (read_user_wptr(mm, wptr64, data64)) {
572 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR,
573 lower_32_bits(data64));
574 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR_HI,
575 upper_32_bits(data64));
576 } else {
577 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR,
578 m->sdmax_rlcx_rb_rptr);
579 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR_HI,
580 m->sdmax_rlcx_rb_rptr_hi);
581 }
582 WREG32(sdma_base_addr + mmSDMA0_RLC0_MINOR_PTR_UPDATE, 0);
583
584 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdmax_rlcx_rb_base);
585 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI,
586 m->sdmax_rlcx_rb_base_hi);
587 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO,
588 m->sdmax_rlcx_rb_rptr_addr_lo);
589 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI,
590 m->sdmax_rlcx_rb_rptr_addr_hi);
591
592 data = REG_SET_FIELD(m->sdmax_rlcx_rb_cntl, SDMA0_RLC0_RB_CNTL,
593 RB_ENABLE, 1);
594 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, data);
595
596 return 0;
597}
598
599static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
600 uint32_t engine_id, uint32_t queue_id,
601 uint32_t (**dump)[2], uint32_t *n_regs)
602{
603 struct amdgpu_device *adev = get_amdgpu_device(kgd);
604 uint32_t sdma_base_addr = get_sdma_base_addr(adev, engine_id, queue_id);
605 uint32_t i = 0, reg;
606#undef HQD_N_REGS
607#define HQD_N_REGS (19+6+7+10)
608
609 *dump = kmalloc(HQD_N_REGS*2*sizeof(uint32_t), GFP_KERNEL);
610 if (*dump == NULL)
611 return -ENOMEM;
612
613 for (reg = mmSDMA0_RLC0_RB_CNTL; reg <= mmSDMA0_RLC0_DOORBELL; reg++)
614 DUMP_REG(sdma_base_addr + reg);
615 for (reg = mmSDMA0_RLC0_STATUS; reg <= mmSDMA0_RLC0_CSA_ADDR_HI; reg++)
616 DUMP_REG(sdma_base_addr + reg);
617 for (reg = mmSDMA0_RLC0_IB_SUB_REMAIN;
618 reg <= mmSDMA0_RLC0_MINOR_PTR_UPDATE; reg++)
619 DUMP_REG(sdma_base_addr + reg);
620 for (reg = mmSDMA0_RLC0_MIDCMD_DATA0;
621 reg <= mmSDMA0_RLC0_MIDCMD_CNTL; reg++)
622 DUMP_REG(sdma_base_addr + reg);
623
624 WARN_ON_ONCE(i != HQD_N_REGS);
625 *n_regs = i;
626
627 return 0;
628}
629
630static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
631 uint32_t pipe_id, uint32_t queue_id)
632{
633 struct amdgpu_device *adev = get_amdgpu_device(kgd);
634 uint32_t act;
635 bool retval = false;
636 uint32_t low, high;
637
638 acquire_queue(kgd, pipe_id, queue_id);
639 act = RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE));
640 if (act) {
641 low = lower_32_bits(queue_address >> 8);
642 high = upper_32_bits(queue_address >> 8);
643
644 if (low == RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_BASE)) &&
645 high == RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_BASE_HI)))
646 retval = true;
647 }
648 release_queue(kgd);
649 return retval;
650}
651
652static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
653{
654 struct amdgpu_device *adev = get_amdgpu_device(kgd);
655 struct v9_sdma_mqd *m;
656 uint32_t sdma_base_addr;
657 uint32_t sdma_rlc_rb_cntl;
658
659 m = get_sdma_mqd(mqd);
660 sdma_base_addr = get_sdma_base_addr(adev, m->sdma_engine_id,
661 m->sdma_queue_id);
662
663 sdma_rlc_rb_cntl = RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL);
664
665 if (sdma_rlc_rb_cntl & SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK)
666 return true;
667
668 return false;
669}
670
671static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
672 enum kfd_preempt_type reset_type,
673 unsigned int utimeout, uint32_t pipe_id,
674 uint32_t queue_id)
675{
676 struct amdgpu_device *adev = get_amdgpu_device(kgd);
677 enum hqd_dequeue_request_type type;
678 unsigned long end_jiffies;
679 uint32_t temp;
680 struct v9_mqd *m = get_mqd(mqd);
681
682 acquire_queue(kgd, pipe_id, queue_id);
683
684 if (m->cp_hqd_vmid == 0)
685 WREG32_FIELD15(GC, 0, RLC_CP_SCHEDULERS, scheduler1, 0);
686
687 switch (reset_type) {
688 case KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN:
689 type = DRAIN_PIPE;
690 break;
691 case KFD_PREEMPT_TYPE_WAVEFRONT_RESET:
692 type = RESET_WAVES;
693 break;
694 default:
695 type = DRAIN_PIPE;
696 break;
697 }
698
699 WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_DEQUEUE_REQUEST), type);
700
701 end_jiffies = (utimeout * HZ / 1000) + jiffies;
702 while (true) {
703 temp = RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE));
704 if (!(temp & CP_HQD_ACTIVE__ACTIVE_MASK))
705 break;
706 if (time_after(jiffies, end_jiffies)) {
707 pr_err("cp queue preemption time out.\n");
708 release_queue(kgd);
709 return -ETIME;
710 }
711 usleep_range(500, 1000);
712 }
713
714 release_queue(kgd);
715 return 0;
716}
717
718static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
719 unsigned int utimeout)
720{
721 struct amdgpu_device *adev = get_amdgpu_device(kgd);
722 struct v9_sdma_mqd *m;
723 uint32_t sdma_base_addr;
724 uint32_t temp;
725 unsigned long end_jiffies = (utimeout * HZ / 1000) + jiffies;
726
727 m = get_sdma_mqd(mqd);
728 sdma_base_addr = get_sdma_base_addr(adev, m->sdma_engine_id,
729 m->sdma_queue_id);
730
731 temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL);
732 temp = temp & ~SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK;
733 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, temp);
734
735 while (true) {
736 temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
737 if (temp & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK)
738 break;
739 if (time_after(jiffies, end_jiffies))
740 return -ETIME;
741 usleep_range(500, 1000);
742 }
743
744 WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0);
745 WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
746 RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL) |
747 SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK);
748
749 m->sdmax_rlcx_rb_rptr = RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR);
750 m->sdmax_rlcx_rb_rptr_hi =
751 RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_HI);
752
753 return 0;
754}
755
756static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd,
757 uint8_t vmid)
758{
759 uint32_t reg;
760 struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
761
762 reg = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
763 + vmid);
764 return reg & ATC_VMID0_PASID_MAPPING__VALID_MASK;
765}
766
767static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
768 uint8_t vmid)
769{
770 uint32_t reg;
771 struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
772
773 reg = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
774 + vmid);
775 return reg & ATC_VMID0_PASID_MAPPING__PASID_MASK;
776}
777
778static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid)
779{
780 struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
781 uint32_t req = (1 << vmid) |
782 (0 << VM_INVALIDATE_ENG16_REQ__FLUSH_TYPE__SHIFT) | /* legacy */
783 VM_INVALIDATE_ENG16_REQ__INVALIDATE_L2_PTES_MASK |
784 VM_INVALIDATE_ENG16_REQ__INVALIDATE_L2_PDE0_MASK |
785 VM_INVALIDATE_ENG16_REQ__INVALIDATE_L2_PDE1_MASK |
786 VM_INVALIDATE_ENG16_REQ__INVALIDATE_L2_PDE2_MASK |
787 VM_INVALIDATE_ENG16_REQ__INVALIDATE_L1_PTES_MASK;
788
789 mutex_lock(&adev->srbm_mutex);
790
791 /* Use legacy mode tlb invalidation.
792 *
793 * Currently on Raven the code below is broken for anything but
794 * legacy mode due to a MMHUB power gating problem. A workaround
795 * is for MMHUB to wait until the condition PER_VMID_INVALIDATE_REQ
796 * == PER_VMID_INVALIDATE_ACK instead of simply waiting for the ack
797 * bit.
798 *
799 * TODO 1: agree on the right set of invalidation registers for
800 * KFD use. Use the last one for now. Invalidate both GC and
801 * MMHUB.
802 *
803 * TODO 2: support range-based invalidation, requires kfg2kgd
804 * interface change
805 */
806 WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG16_ADDR_RANGE_LO32),
807 0xffffffff);
808 WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG16_ADDR_RANGE_HI32),
809 0x0000001f);
810
811 WREG32(SOC15_REG_OFFSET(MMHUB, 0,
812 mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_LO32),
813 0xffffffff);
814 WREG32(SOC15_REG_OFFSET(MMHUB, 0,
815 mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_HI32),
816 0x0000001f);
817
818 WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG16_REQ), req);
819
820 WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_INVALIDATE_ENG16_REQ),
821 req);
822
823 while (!(RREG32(SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG16_ACK)) &
824 (1 << vmid)))
825 cpu_relax();
826
827 while (!(RREG32(SOC15_REG_OFFSET(MMHUB, 0,
828 mmMMHUB_VM_INVALIDATE_ENG16_ACK)) &
829 (1 << vmid)))
830 cpu_relax();
831
832 mutex_unlock(&adev->srbm_mutex);
833
834}
835
836static int invalidate_tlbs_with_kiq(struct amdgpu_device *adev, uint16_t pasid)
837{
838 signed long r;
839 uint32_t seq;
840 struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
841
842 spin_lock(&adev->gfx.kiq.ring_lock);
843 amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
844 amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
845 amdgpu_ring_write(ring,
846 PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
847 PACKET3_INVALIDATE_TLBS_ALL_HUB(1) |
848 PACKET3_INVALIDATE_TLBS_PASID(pasid) |
849 PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(0)); /* legacy */
850 amdgpu_fence_emit_polling(ring, &seq);
851 amdgpu_ring_commit(ring);
852 spin_unlock(&adev->gfx.kiq.ring_lock);
853
854 r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
855 if (r < 1) {
856 DRM_ERROR("wait for kiq fence error: %ld.\n", r);
857 return -ETIME;
858 }
859
860 return 0;
861}
862
863static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
864{
865 struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
866 int vmid;
867 struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
868
869 if (ring->ready)
870 return invalidate_tlbs_with_kiq(adev, pasid);
871
872 for (vmid = 0; vmid < 16; vmid++) {
873 if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid))
874 continue;
875 if (get_atc_vmid_pasid_mapping_valid(kgd, vmid)) {
876 if (get_atc_vmid_pasid_mapping_pasid(kgd, vmid)
877 == pasid) {
878 write_vmid_invalidate_request(kgd, vmid);
879 break;
880 }
881 }
882 }
883
884 return 0;
885}
886
887static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
888{
889 struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
890
891 if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
892 pr_err("non kfd vmid %d\n", vmid);
893 return 0;
894 }
895
896 write_vmid_invalidate_request(kgd, vmid);
897 return 0;
898}
899
900static int kgd_address_watch_disable(struct kgd_dev *kgd)
901{
902 return 0;
903}
904
905static int kgd_address_watch_execute(struct kgd_dev *kgd,
906 unsigned int watch_point_id,
907 uint32_t cntl_val,
908 uint32_t addr_hi,
909 uint32_t addr_lo)
910{
911 return 0;
912}
913
914static int kgd_wave_control_execute(struct kgd_dev *kgd,
915 uint32_t gfx_index_val,
916 uint32_t sq_cmd)
917{
918 struct amdgpu_device *adev = get_amdgpu_device(kgd);
919 uint32_t data = 0;
920
921 mutex_lock(&adev->grbm_idx_mutex);
922
923 WREG32(SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_INDEX), gfx_index_val);
924 WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_CMD), sq_cmd);
925
926 data = REG_SET_FIELD(data, GRBM_GFX_INDEX,
927 INSTANCE_BROADCAST_WRITES, 1);
928 data = REG_SET_FIELD(data, GRBM_GFX_INDEX,
929 SH_BROADCAST_WRITES, 1);
930 data = REG_SET_FIELD(data, GRBM_GFX_INDEX,
931 SE_BROADCAST_WRITES, 1);
932
933 WREG32(SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_INDEX), data);
934 mutex_unlock(&adev->grbm_idx_mutex);
935
936 return 0;
937}
938
939static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
940 unsigned int watch_point_id,
941 unsigned int reg_offset)
942{
943 return 0;
944}
945
946static void set_scratch_backing_va(struct kgd_dev *kgd,
947 uint64_t va, uint32_t vmid)
948{
949 /* No longer needed on GFXv9. The scratch base address is
950 * passed to the shader by the CP. It's the user mode driver's
951 * responsibility.
952 */
953}
954
955/* FIXME: Does this need to be ASIC-specific code? */
956static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
957{
958 struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
959 const union amdgpu_firmware_header *hdr;
960
961 switch (type) {
962 case KGD_ENGINE_PFP:
963 hdr = (const union amdgpu_firmware_header *)adev->gfx.pfp_fw->data;
964 break;
965
966 case KGD_ENGINE_ME:
967 hdr = (const union amdgpu_firmware_header *)adev->gfx.me_fw->data;
968 break;
969
970 case KGD_ENGINE_CE:
971 hdr = (const union amdgpu_firmware_header *)adev->gfx.ce_fw->data;
972 break;
973
974 case KGD_ENGINE_MEC1:
975 hdr = (const union amdgpu_firmware_header *)adev->gfx.mec_fw->data;
976 break;
977
978 case KGD_ENGINE_MEC2:
979 hdr = (const union amdgpu_firmware_header *)adev->gfx.mec2_fw->data;
980 break;
981
982 case KGD_ENGINE_RLC:
983 hdr = (const union amdgpu_firmware_header *)adev->gfx.rlc_fw->data;
984 break;
985
986 case KGD_ENGINE_SDMA1:
987 hdr = (const union amdgpu_firmware_header *)adev->sdma.instance[0].fw->data;
988 break;
989
990 case KGD_ENGINE_SDMA2:
991 hdr = (const union amdgpu_firmware_header *)adev->sdma.instance[1].fw->data;
992 break;
993
994 default:
995 return 0;
996 }
997
998 if (hdr == NULL)
999 return 0;
1000
1001 /* Only 12 bit in use*/
1002 return hdr->common.ucode_version;
1003}
1004
1005static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
1006 uint32_t page_table_base)
1007{
1008 struct amdgpu_device *adev = get_amdgpu_device(kgd);
1009 uint64_t base = (uint64_t)page_table_base << PAGE_SHIFT |
1010 AMDGPU_PTE_VALID;
1011
1012 if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
1013 pr_err("trying to set page table base for wrong VMID %u\n",
1014 vmid);
1015 return;
1016 }
1017
1018 /* TODO: take advantage of per-process address space size. For
1019 * now, all processes share the same address space size, like
1020 * on GFX8 and older.
1021 */
1022 WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32) + (vmid*2), 0);
1023 WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32) + (vmid*2), 0);
1024
1025 WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32) + (vmid*2),
1026 lower_32_bits(adev->vm_manager.max_pfn - 1));
1027 WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32) + (vmid*2),
1028 upper_32_bits(adev->vm_manager.max_pfn - 1));
1029
1030 WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32) + (vmid*2), lower_32_bits(base));
1031 WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32) + (vmid*2), upper_32_bits(base));
1032
1033 WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32) + (vmid*2), 0);
1034 WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32) + (vmid*2), 0);
1035
1036 WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32) + (vmid*2),
1037 lower_32_bits(adev->vm_manager.max_pfn - 1));
1038 WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32) + (vmid*2),
1039 upper_32_bits(adev->vm_manager.max_pfn - 1));
1040
1041 WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32) + (vmid*2), lower_32_bits(base));
1042 WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32) + (vmid*2), upper_32_bits(base));
1043}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 1d6e1479da38..ff8fd75f7ca5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -23,6 +23,8 @@
23#define pr_fmt(fmt) "kfd2kgd: " fmt 23#define pr_fmt(fmt) "kfd2kgd: " fmt
24 24
25#include <linux/list.h> 25#include <linux/list.h>
26#include <linux/pagemap.h>
27#include <linux/sched/mm.h>
26#include <drm/drmP.h> 28#include <drm/drmP.h>
27#include "amdgpu_object.h" 29#include "amdgpu_object.h"
28#include "amdgpu_vm.h" 30#include "amdgpu_vm.h"
@@ -33,10 +35,20 @@
33 */ 35 */
34#define VI_BO_SIZE_ALIGN (0x8000) 36#define VI_BO_SIZE_ALIGN (0x8000)
35 37
38/* BO flag to indicate a KFD userptr BO */
39#define AMDGPU_AMDKFD_USERPTR_BO (1ULL << 63)
40
41/* Userptr restore delay, just long enough to allow consecutive VM
42 * changes to accumulate
43 */
44#define AMDGPU_USERPTR_RESTORE_DELAY_MS 1
45
36/* Impose limit on how much memory KFD can use */ 46/* Impose limit on how much memory KFD can use */
37static struct { 47static struct {
38 uint64_t max_system_mem_limit; 48 uint64_t max_system_mem_limit;
49 uint64_t max_userptr_mem_limit;
39 int64_t system_mem_used; 50 int64_t system_mem_used;
51 int64_t userptr_mem_used;
40 spinlock_t mem_limit_lock; 52 spinlock_t mem_limit_lock;
41} kfd_mem_limit; 53} kfd_mem_limit;
42 54
@@ -57,6 +69,7 @@ static const char * const domain_bit_to_string[] = {
57 69
58#define domain_string(domain) domain_bit_to_string[ffs(domain)-1] 70#define domain_string(domain) domain_bit_to_string[ffs(domain)-1]
59 71
72static void amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work);
60 73
61 74
62static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd) 75static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
@@ -78,6 +91,7 @@ static bool check_if_add_bo_to_vm(struct amdgpu_vm *avm,
78 91
79/* Set memory usage limits. Current, limits are 92/* Set memory usage limits. Current, limits are
80 * System (kernel) memory - 3/8th System RAM 93 * System (kernel) memory - 3/8th System RAM
94 * Userptr memory - 3/4th System RAM
81 */ 95 */
82void amdgpu_amdkfd_gpuvm_init_mem_limits(void) 96void amdgpu_amdkfd_gpuvm_init_mem_limits(void)
83{ 97{
@@ -90,8 +104,10 @@ void amdgpu_amdkfd_gpuvm_init_mem_limits(void)
90 104
91 spin_lock_init(&kfd_mem_limit.mem_limit_lock); 105 spin_lock_init(&kfd_mem_limit.mem_limit_lock);
92 kfd_mem_limit.max_system_mem_limit = (mem >> 1) - (mem >> 3); 106 kfd_mem_limit.max_system_mem_limit = (mem >> 1) - (mem >> 3);
93 pr_debug("Kernel memory limit %lluM\n", 107 kfd_mem_limit.max_userptr_mem_limit = mem - (mem >> 2);
94 (kfd_mem_limit.max_system_mem_limit >> 20)); 108 pr_debug("Kernel memory limit %lluM, userptr limit %lluM\n",
109 (kfd_mem_limit.max_system_mem_limit >> 20),
110 (kfd_mem_limit.max_userptr_mem_limit >> 20));
95} 111}
96 112
97static int amdgpu_amdkfd_reserve_system_mem_limit(struct amdgpu_device *adev, 113static int amdgpu_amdkfd_reserve_system_mem_limit(struct amdgpu_device *adev,
@@ -111,6 +127,16 @@ static int amdgpu_amdkfd_reserve_system_mem_limit(struct amdgpu_device *adev,
111 goto err_no_mem; 127 goto err_no_mem;
112 } 128 }
113 kfd_mem_limit.system_mem_used += (acc_size + size); 129 kfd_mem_limit.system_mem_used += (acc_size + size);
130 } else if (domain == AMDGPU_GEM_DOMAIN_CPU) {
131 if ((kfd_mem_limit.system_mem_used + acc_size >
132 kfd_mem_limit.max_system_mem_limit) ||
133 (kfd_mem_limit.userptr_mem_used + (size + acc_size) >
134 kfd_mem_limit.max_userptr_mem_limit)) {
135 ret = -ENOMEM;
136 goto err_no_mem;
137 }
138 kfd_mem_limit.system_mem_used += acc_size;
139 kfd_mem_limit.userptr_mem_used += size;
114 } 140 }
115err_no_mem: 141err_no_mem:
116 spin_unlock(&kfd_mem_limit.mem_limit_lock); 142 spin_unlock(&kfd_mem_limit.mem_limit_lock);
@@ -126,10 +152,16 @@ static void unreserve_system_mem_limit(struct amdgpu_device *adev,
126 sizeof(struct amdgpu_bo)); 152 sizeof(struct amdgpu_bo));
127 153
128 spin_lock(&kfd_mem_limit.mem_limit_lock); 154 spin_lock(&kfd_mem_limit.mem_limit_lock);
129 if (domain == AMDGPU_GEM_DOMAIN_GTT) 155 if (domain == AMDGPU_GEM_DOMAIN_GTT) {
130 kfd_mem_limit.system_mem_used -= (acc_size + size); 156 kfd_mem_limit.system_mem_used -= (acc_size + size);
157 } else if (domain == AMDGPU_GEM_DOMAIN_CPU) {
158 kfd_mem_limit.system_mem_used -= acc_size;
159 kfd_mem_limit.userptr_mem_used -= size;
160 }
131 WARN_ONCE(kfd_mem_limit.system_mem_used < 0, 161 WARN_ONCE(kfd_mem_limit.system_mem_used < 0,
132 "kfd system memory accounting unbalanced"); 162 "kfd system memory accounting unbalanced");
163 WARN_ONCE(kfd_mem_limit.userptr_mem_used < 0,
164 "kfd userptr memory accounting unbalanced");
133 165
134 spin_unlock(&kfd_mem_limit.mem_limit_lock); 166 spin_unlock(&kfd_mem_limit.mem_limit_lock);
135} 167}
@@ -138,12 +170,17 @@ void amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo *bo)
138{ 170{
139 spin_lock(&kfd_mem_limit.mem_limit_lock); 171 spin_lock(&kfd_mem_limit.mem_limit_lock);
140 172
141 if (bo->preferred_domains == AMDGPU_GEM_DOMAIN_GTT) { 173 if (bo->flags & AMDGPU_AMDKFD_USERPTR_BO) {
174 kfd_mem_limit.system_mem_used -= bo->tbo.acc_size;
175 kfd_mem_limit.userptr_mem_used -= amdgpu_bo_size(bo);
176 } else if (bo->preferred_domains == AMDGPU_GEM_DOMAIN_GTT) {
142 kfd_mem_limit.system_mem_used -= 177 kfd_mem_limit.system_mem_used -=
143 (bo->tbo.acc_size + amdgpu_bo_size(bo)); 178 (bo->tbo.acc_size + amdgpu_bo_size(bo));
144 } 179 }
145 WARN_ONCE(kfd_mem_limit.system_mem_used < 0, 180 WARN_ONCE(kfd_mem_limit.system_mem_used < 0,
146 "kfd system memory accounting unbalanced"); 181 "kfd system memory accounting unbalanced");
182 WARN_ONCE(kfd_mem_limit.userptr_mem_used < 0,
183 "kfd userptr memory accounting unbalanced");
147 184
148 spin_unlock(&kfd_mem_limit.mem_limit_lock); 185 spin_unlock(&kfd_mem_limit.mem_limit_lock);
149} 186}
@@ -506,7 +543,8 @@ static void remove_bo_from_vm(struct amdgpu_device *adev,
506} 543}
507 544
508static void add_kgd_mem_to_kfd_bo_list(struct kgd_mem *mem, 545static void add_kgd_mem_to_kfd_bo_list(struct kgd_mem *mem,
509 struct amdkfd_process_info *process_info) 546 struct amdkfd_process_info *process_info,
547 bool userptr)
510{ 548{
511 struct ttm_validate_buffer *entry = &mem->validate_list; 549 struct ttm_validate_buffer *entry = &mem->validate_list;
512 struct amdgpu_bo *bo = mem->bo; 550 struct amdgpu_bo *bo = mem->bo;
@@ -515,10 +553,95 @@ static void add_kgd_mem_to_kfd_bo_list(struct kgd_mem *mem,
515 entry->shared = true; 553 entry->shared = true;
516 entry->bo = &bo->tbo; 554 entry->bo = &bo->tbo;
517 mutex_lock(&process_info->lock); 555 mutex_lock(&process_info->lock);
518 list_add_tail(&entry->head, &process_info->kfd_bo_list); 556 if (userptr)
557 list_add_tail(&entry->head, &process_info->userptr_valid_list);
558 else
559 list_add_tail(&entry->head, &process_info->kfd_bo_list);
519 mutex_unlock(&process_info->lock); 560 mutex_unlock(&process_info->lock);
520} 561}
521 562
563/* Initializes user pages. It registers the MMU notifier and validates
564 * the userptr BO in the GTT domain.
565 *
566 * The BO must already be on the userptr_valid_list. Otherwise an
567 * eviction and restore may happen that leaves the new BO unmapped
568 * with the user mode queues running.
569 *
570 * Takes the process_info->lock to protect against concurrent restore
571 * workers.
572 *
573 * Returns 0 for success, negative errno for errors.
574 */
575static int init_user_pages(struct kgd_mem *mem, struct mm_struct *mm,
576 uint64_t user_addr)
577{
578 struct amdkfd_process_info *process_info = mem->process_info;
579 struct amdgpu_bo *bo = mem->bo;
580 struct ttm_operation_ctx ctx = { true, false };
581 int ret = 0;
582
583 mutex_lock(&process_info->lock);
584
585 ret = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, user_addr, 0);
586 if (ret) {
587 pr_err("%s: Failed to set userptr: %d\n", __func__, ret);
588 goto out;
589 }
590
591 ret = amdgpu_mn_register(bo, user_addr);
592 if (ret) {
593 pr_err("%s: Failed to register MMU notifier: %d\n",
594 __func__, ret);
595 goto out;
596 }
597
598 /* If no restore worker is running concurrently, user_pages
599 * should not be allocated
600 */
601 WARN(mem->user_pages, "Leaking user_pages array");
602
603 mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
604 sizeof(struct page *),
605 GFP_KERNEL | __GFP_ZERO);
606 if (!mem->user_pages) {
607 pr_err("%s: Failed to allocate pages array\n", __func__);
608 ret = -ENOMEM;
609 goto unregister_out;
610 }
611
612 ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
613 if (ret) {
614 pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
615 goto free_out;
616 }
617
618 amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
619
620 ret = amdgpu_bo_reserve(bo, true);
621 if (ret) {
622 pr_err("%s: Failed to reserve BO\n", __func__);
623 goto release_out;
624 }
625 amdgpu_ttm_placement_from_domain(bo, mem->domain);
626 ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
627 if (ret)
628 pr_err("%s: failed to validate BO\n", __func__);
629 amdgpu_bo_unreserve(bo);
630
631release_out:
632 if (ret)
633 release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
634free_out:
635 kvfree(mem->user_pages);
636 mem->user_pages = NULL;
637unregister_out:
638 if (ret)
639 amdgpu_mn_unregister(bo);
640out:
641 mutex_unlock(&process_info->lock);
642 return ret;
643}
644
522/* Reserving a BO and its page table BOs must happen atomically to 645/* Reserving a BO and its page table BOs must happen atomically to
523 * avoid deadlocks. Some operations update multiple VMs at once. Track 646 * avoid deadlocks. Some operations update multiple VMs at once. Track
524 * all the reservation info in a context structure. Optionally a sync 647 * all the reservation info in a context structure. Optionally a sync
@@ -748,7 +871,8 @@ static int update_gpuvm_pte(struct amdgpu_device *adev,
748} 871}
749 872
750static int map_bo_to_gpuvm(struct amdgpu_device *adev, 873static int map_bo_to_gpuvm(struct amdgpu_device *adev,
751 struct kfd_bo_va_list *entry, struct amdgpu_sync *sync) 874 struct kfd_bo_va_list *entry, struct amdgpu_sync *sync,
875 bool no_update_pte)
752{ 876{
753 int ret; 877 int ret;
754 878
@@ -762,6 +886,9 @@ static int map_bo_to_gpuvm(struct amdgpu_device *adev,
762 return ret; 886 return ret;
763 } 887 }
764 888
889 if (no_update_pte)
890 return 0;
891
765 ret = update_gpuvm_pte(adev, entry, sync); 892 ret = update_gpuvm_pte(adev, entry, sync);
766 if (ret) { 893 if (ret) {
767 pr_err("update_gpuvm_pte() failed\n"); 894 pr_err("update_gpuvm_pte() failed\n");
@@ -820,6 +947,8 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
820 mutex_init(&info->lock); 947 mutex_init(&info->lock);
821 INIT_LIST_HEAD(&info->vm_list_head); 948 INIT_LIST_HEAD(&info->vm_list_head);
822 INIT_LIST_HEAD(&info->kfd_bo_list); 949 INIT_LIST_HEAD(&info->kfd_bo_list);
950 INIT_LIST_HEAD(&info->userptr_valid_list);
951 INIT_LIST_HEAD(&info->userptr_inval_list);
823 952
824 info->eviction_fence = 953 info->eviction_fence =
825 amdgpu_amdkfd_fence_create(dma_fence_context_alloc(1), 954 amdgpu_amdkfd_fence_create(dma_fence_context_alloc(1),
@@ -830,6 +959,11 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
830 goto create_evict_fence_fail; 959 goto create_evict_fence_fail;
831 } 960 }
832 961
962 info->pid = get_task_pid(current->group_leader, PIDTYPE_PID);
963 atomic_set(&info->evicted_bos, 0);
964 INIT_DELAYED_WORK(&info->restore_userptr_work,
965 amdgpu_amdkfd_restore_userptr_worker);
966
833 *process_info = info; 967 *process_info = info;
834 *ef = dma_fence_get(&info->eviction_fence->base); 968 *ef = dma_fence_get(&info->eviction_fence->base);
835 } 969 }
@@ -872,6 +1006,7 @@ reserve_pd_fail:
872 dma_fence_put(*ef); 1006 dma_fence_put(*ef);
873 *ef = NULL; 1007 *ef = NULL;
874 *process_info = NULL; 1008 *process_info = NULL;
1009 put_pid(info->pid);
875create_evict_fence_fail: 1010create_evict_fence_fail:
876 mutex_destroy(&info->lock); 1011 mutex_destroy(&info->lock);
877 kfree(info); 1012 kfree(info);
@@ -967,8 +1102,12 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
967 /* Release per-process resources when last compute VM is destroyed */ 1102 /* Release per-process resources when last compute VM is destroyed */
968 if (!process_info->n_vms) { 1103 if (!process_info->n_vms) {
969 WARN_ON(!list_empty(&process_info->kfd_bo_list)); 1104 WARN_ON(!list_empty(&process_info->kfd_bo_list));
1105 WARN_ON(!list_empty(&process_info->userptr_valid_list));
1106 WARN_ON(!list_empty(&process_info->userptr_inval_list));
970 1107
971 dma_fence_put(&process_info->eviction_fence->base); 1108 dma_fence_put(&process_info->eviction_fence->base);
1109 cancel_delayed_work_sync(&process_info->restore_userptr_work);
1110 put_pid(process_info->pid);
972 mutex_destroy(&process_info->lock); 1111 mutex_destroy(&process_info->lock);
973 kfree(process_info); 1112 kfree(process_info);
974 } 1113 }
@@ -1003,9 +1142,11 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
1003{ 1142{
1004 struct amdgpu_device *adev = get_amdgpu_device(kgd); 1143 struct amdgpu_device *adev = get_amdgpu_device(kgd);
1005 struct amdgpu_vm *avm = (struct amdgpu_vm *)vm; 1144 struct amdgpu_vm *avm = (struct amdgpu_vm *)vm;
1145 uint64_t user_addr = 0;
1006 struct amdgpu_bo *bo; 1146 struct amdgpu_bo *bo;
1147 struct amdgpu_bo_param bp;
1007 int byte_align; 1148 int byte_align;
1008 u32 alloc_domain; 1149 u32 domain, alloc_domain;
1009 u64 alloc_flags; 1150 u64 alloc_flags;
1010 uint32_t mapping_flags; 1151 uint32_t mapping_flags;
1011 int ret; 1152 int ret;
@@ -1014,14 +1155,21 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
1014 * Check on which domain to allocate BO 1155 * Check on which domain to allocate BO
1015 */ 1156 */
1016 if (flags & ALLOC_MEM_FLAGS_VRAM) { 1157 if (flags & ALLOC_MEM_FLAGS_VRAM) {
1017 alloc_domain = AMDGPU_GEM_DOMAIN_VRAM; 1158 domain = alloc_domain = AMDGPU_GEM_DOMAIN_VRAM;
1018 alloc_flags = AMDGPU_GEM_CREATE_VRAM_CLEARED; 1159 alloc_flags = AMDGPU_GEM_CREATE_VRAM_CLEARED;
1019 alloc_flags |= (flags & ALLOC_MEM_FLAGS_PUBLIC) ? 1160 alloc_flags |= (flags & ALLOC_MEM_FLAGS_PUBLIC) ?
1020 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : 1161 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED :
1021 AMDGPU_GEM_CREATE_NO_CPU_ACCESS; 1162 AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
1022 } else if (flags & ALLOC_MEM_FLAGS_GTT) { 1163 } else if (flags & ALLOC_MEM_FLAGS_GTT) {
1023 alloc_domain = AMDGPU_GEM_DOMAIN_GTT; 1164 domain = alloc_domain = AMDGPU_GEM_DOMAIN_GTT;
1165 alloc_flags = 0;
1166 } else if (flags & ALLOC_MEM_FLAGS_USERPTR) {
1167 domain = AMDGPU_GEM_DOMAIN_GTT;
1168 alloc_domain = AMDGPU_GEM_DOMAIN_CPU;
1024 alloc_flags = 0; 1169 alloc_flags = 0;
1170 if (!offset || !*offset)
1171 return -EINVAL;
1172 user_addr = *offset;
1025 } else { 1173 } else {
1026 return -EINVAL; 1174 return -EINVAL;
1027 } 1175 }
@@ -1069,8 +1217,14 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
1069 pr_debug("\tcreate BO VA 0x%llx size 0x%llx domain %s\n", 1217 pr_debug("\tcreate BO VA 0x%llx size 0x%llx domain %s\n",
1070 va, size, domain_string(alloc_domain)); 1218 va, size, domain_string(alloc_domain));
1071 1219
1072 ret = amdgpu_bo_create(adev, size, byte_align, 1220 memset(&bp, 0, sizeof(bp));
1073 alloc_domain, alloc_flags, ttm_bo_type_device, NULL, &bo); 1221 bp.size = size;
1222 bp.byte_align = byte_align;
1223 bp.domain = alloc_domain;
1224 bp.flags = alloc_flags;
1225 bp.type = ttm_bo_type_device;
1226 bp.resv = NULL;
1227 ret = amdgpu_bo_create(adev, &bp, &bo);
1074 if (ret) { 1228 if (ret) {
1075 pr_debug("Failed to create BO on domain %s. ret %d\n", 1229 pr_debug("Failed to create BO on domain %s. ret %d\n",
1076 domain_string(alloc_domain), ret); 1230 domain_string(alloc_domain), ret);
@@ -1078,18 +1232,34 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
1078 } 1232 }
1079 bo->kfd_bo = *mem; 1233 bo->kfd_bo = *mem;
1080 (*mem)->bo = bo; 1234 (*mem)->bo = bo;
1235 if (user_addr)
1236 bo->flags |= AMDGPU_AMDKFD_USERPTR_BO;
1081 1237
1082 (*mem)->va = va; 1238 (*mem)->va = va;
1083 (*mem)->domain = alloc_domain; 1239 (*mem)->domain = domain;
1084 (*mem)->mapped_to_gpu_memory = 0; 1240 (*mem)->mapped_to_gpu_memory = 0;
1085 (*mem)->process_info = avm->process_info; 1241 (*mem)->process_info = avm->process_info;
1086 add_kgd_mem_to_kfd_bo_list(*mem, avm->process_info); 1242 add_kgd_mem_to_kfd_bo_list(*mem, avm->process_info, user_addr);
1243
1244 if (user_addr) {
1245 ret = init_user_pages(*mem, current->mm, user_addr);
1246 if (ret) {
1247 mutex_lock(&avm->process_info->lock);
1248 list_del(&(*mem)->validate_list.head);
1249 mutex_unlock(&avm->process_info->lock);
1250 goto allocate_init_user_pages_failed;
1251 }
1252 }
1087 1253
1088 if (offset) 1254 if (offset)
1089 *offset = amdgpu_bo_mmap_offset(bo); 1255 *offset = amdgpu_bo_mmap_offset(bo);
1090 1256
1091 return 0; 1257 return 0;
1092 1258
1259allocate_init_user_pages_failed:
1260 amdgpu_bo_unref(&bo);
1261 /* Don't unreserve system mem limit twice */
1262 goto err_reserve_system_mem;
1093err_bo_create: 1263err_bo_create:
1094 unreserve_system_mem_limit(adev, size, alloc_domain); 1264 unreserve_system_mem_limit(adev, size, alloc_domain);
1095err_reserve_system_mem: 1265err_reserve_system_mem:
@@ -1122,12 +1292,24 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
1122 * be freed anyway 1292 * be freed anyway
1123 */ 1293 */
1124 1294
1295 /* No more MMU notifiers */
1296 amdgpu_mn_unregister(mem->bo);
1297
1125 /* Make sure restore workers don't access the BO any more */ 1298 /* Make sure restore workers don't access the BO any more */
1126 bo_list_entry = &mem->validate_list; 1299 bo_list_entry = &mem->validate_list;
1127 mutex_lock(&process_info->lock); 1300 mutex_lock(&process_info->lock);
1128 list_del(&bo_list_entry->head); 1301 list_del(&bo_list_entry->head);
1129 mutex_unlock(&process_info->lock); 1302 mutex_unlock(&process_info->lock);
1130 1303
1304 /* Free user pages if necessary */
1305 if (mem->user_pages) {
1306 pr_debug("%s: Freeing user_pages array\n", __func__);
1307 if (mem->user_pages[0])
1308 release_pages(mem->user_pages,
1309 mem->bo->tbo.ttm->num_pages);
1310 kvfree(mem->user_pages);
1311 }
1312
1131 ret = reserve_bo_and_cond_vms(mem, NULL, BO_VM_ALL, &ctx); 1313 ret = reserve_bo_and_cond_vms(mem, NULL, BO_VM_ALL, &ctx);
1132 if (unlikely(ret)) 1314 if (unlikely(ret))
1133 return ret; 1315 return ret;
@@ -1173,21 +1355,32 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
1173 struct kfd_bo_va_list *bo_va_entry = NULL; 1355 struct kfd_bo_va_list *bo_va_entry = NULL;
1174 struct kfd_bo_va_list *bo_va_entry_aql = NULL; 1356 struct kfd_bo_va_list *bo_va_entry_aql = NULL;
1175 unsigned long bo_size; 1357 unsigned long bo_size;
1176 1358 bool is_invalid_userptr = false;
1177 /* Make sure restore is not running concurrently.
1178 */
1179 mutex_lock(&mem->process_info->lock);
1180
1181 mutex_lock(&mem->lock);
1182 1359
1183 bo = mem->bo; 1360 bo = mem->bo;
1184
1185 if (!bo) { 1361 if (!bo) {
1186 pr_err("Invalid BO when mapping memory to GPU\n"); 1362 pr_err("Invalid BO when mapping memory to GPU\n");
1187 ret = -EINVAL; 1363 return -EINVAL;
1188 goto out;
1189 } 1364 }
1190 1365
1366 /* Make sure restore is not running concurrently. Since we
1367 * don't map invalid userptr BOs, we rely on the next restore
1368 * worker to do the mapping
1369 */
1370 mutex_lock(&mem->process_info->lock);
1371
1372 /* Lock mmap-sem. If we find an invalid userptr BO, we can be
1373 * sure that the MMU notifier is no longer running
1374 * concurrently and the queues are actually stopped
1375 */
1376 if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
1377 down_write(&current->mm->mmap_sem);
1378 is_invalid_userptr = atomic_read(&mem->invalid);
1379 up_write(&current->mm->mmap_sem);
1380 }
1381
1382 mutex_lock(&mem->lock);
1383
1191 domain = mem->domain; 1384 domain = mem->domain;
1192 bo_size = bo->tbo.mem.size; 1385 bo_size = bo->tbo.mem.size;
1193 1386
@@ -1200,6 +1393,14 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
1200 if (unlikely(ret)) 1393 if (unlikely(ret))
1201 goto out; 1394 goto out;
1202 1395
1396 /* Userptr can be marked as "not invalid", but not actually be
1397 * validated yet (still in the system domain). In that case
1398 * the queues are still stopped and we can leave mapping for
1399 * the next restore worker
1400 */
1401 if (bo->tbo.mem.mem_type == TTM_PL_SYSTEM)
1402 is_invalid_userptr = true;
1403
1203 if (check_if_add_bo_to_vm(avm, mem)) { 1404 if (check_if_add_bo_to_vm(avm, mem)) {
1204 ret = add_bo_to_vm(adev, mem, avm, false, 1405 ret = add_bo_to_vm(adev, mem, avm, false,
1205 &bo_va_entry); 1406 &bo_va_entry);
@@ -1217,7 +1418,8 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
1217 goto add_bo_to_vm_failed; 1418 goto add_bo_to_vm_failed;
1218 } 1419 }
1219 1420
1220 if (mem->mapped_to_gpu_memory == 0) { 1421 if (mem->mapped_to_gpu_memory == 0 &&
1422 !amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
1221 /* Validate BO only once. The eviction fence gets added to BO 1423 /* Validate BO only once. The eviction fence gets added to BO
1222 * the first time it is mapped. Validate will wait for all 1424 * the first time it is mapped. Validate will wait for all
1223 * background evictions to complete. 1425 * background evictions to complete.
@@ -1235,7 +1437,8 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
1235 entry->va, entry->va + bo_size, 1437 entry->va, entry->va + bo_size,
1236 entry); 1438 entry);
1237 1439
1238 ret = map_bo_to_gpuvm(adev, entry, ctx.sync); 1440 ret = map_bo_to_gpuvm(adev, entry, ctx.sync,
1441 is_invalid_userptr);
1239 if (ret) { 1442 if (ret) {
1240 pr_err("Failed to map radeon bo to gpuvm\n"); 1443 pr_err("Failed to map radeon bo to gpuvm\n");
1241 goto map_bo_to_gpuvm_failed; 1444 goto map_bo_to_gpuvm_failed;
@@ -1418,6 +1621,337 @@ bo_reserve_failed:
1418 return ret; 1621 return ret;
1419} 1622}
1420 1623
1624/* Evict a userptr BO by stopping the queues if necessary
1625 *
1626 * Runs in MMU notifier, may be in RECLAIM_FS context. This means it
1627 * cannot do any memory allocations, and cannot take any locks that
1628 * are held elsewhere while allocating memory. Therefore this is as
1629 * simple as possible, using atomic counters.
1630 *
1631 * It doesn't do anything to the BO itself. The real work happens in
1632 * restore, where we get updated page addresses. This function only
1633 * ensures that GPU access to the BO is stopped.
1634 */
1635int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem,
1636 struct mm_struct *mm)
1637{
1638 struct amdkfd_process_info *process_info = mem->process_info;
1639 int invalid, evicted_bos;
1640 int r = 0;
1641
1642 invalid = atomic_inc_return(&mem->invalid);
1643 evicted_bos = atomic_inc_return(&process_info->evicted_bos);
1644 if (evicted_bos == 1) {
1645 /* First eviction, stop the queues */
1646 r = kgd2kfd->quiesce_mm(mm);
1647 if (r)
1648 pr_err("Failed to quiesce KFD\n");
1649 schedule_delayed_work(&process_info->restore_userptr_work,
1650 msecs_to_jiffies(AMDGPU_USERPTR_RESTORE_DELAY_MS));
1651 }
1652
1653 return r;
1654}
1655
1656/* Update invalid userptr BOs
1657 *
1658 * Moves invalidated (evicted) userptr BOs from userptr_valid_list to
1659 * userptr_inval_list and updates user pages for all BOs that have
1660 * been invalidated since their last update.
1661 */
1662static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
1663 struct mm_struct *mm)
1664{
1665 struct kgd_mem *mem, *tmp_mem;
1666 struct amdgpu_bo *bo;
1667 struct ttm_operation_ctx ctx = { false, false };
1668 int invalid, ret;
1669
1670 /* Move all invalidated BOs to the userptr_inval_list and
1671 * release their user pages by migration to the CPU domain
1672 */
1673 list_for_each_entry_safe(mem, tmp_mem,
1674 &process_info->userptr_valid_list,
1675 validate_list.head) {
1676 if (!atomic_read(&mem->invalid))
1677 continue; /* BO is still valid */
1678
1679 bo = mem->bo;
1680
1681 if (amdgpu_bo_reserve(bo, true))
1682 return -EAGAIN;
1683 amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU);
1684 ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
1685 amdgpu_bo_unreserve(bo);
1686 if (ret) {
1687 pr_err("%s: Failed to invalidate userptr BO\n",
1688 __func__);
1689 return -EAGAIN;
1690 }
1691
1692 list_move_tail(&mem->validate_list.head,
1693 &process_info->userptr_inval_list);
1694 }
1695
1696 if (list_empty(&process_info->userptr_inval_list))
1697 return 0; /* All evicted userptr BOs were freed */
1698
1699 /* Go through userptr_inval_list and update any invalid user_pages */
1700 list_for_each_entry(mem, &process_info->userptr_inval_list,
1701 validate_list.head) {
1702 invalid = atomic_read(&mem->invalid);
1703 if (!invalid)
1704 /* BO hasn't been invalidated since the last
1705 * revalidation attempt. Keep its BO list.
1706 */
1707 continue;
1708
1709 bo = mem->bo;
1710
1711 if (!mem->user_pages) {
1712 mem->user_pages =
1713 kvmalloc_array(bo->tbo.ttm->num_pages,
1714 sizeof(struct page *),
1715 GFP_KERNEL | __GFP_ZERO);
1716 if (!mem->user_pages) {
1717 pr_err("%s: Failed to allocate pages array\n",
1718 __func__);
1719 return -ENOMEM;
1720 }
1721 } else if (mem->user_pages[0]) {
1722 release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
1723 }
1724
1725 /* Get updated user pages */
1726 ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm,
1727 mem->user_pages);
1728 if (ret) {
1729 mem->user_pages[0] = NULL;
1730 pr_info("%s: Failed to get user pages: %d\n",
1731 __func__, ret);
1732 /* Pretend it succeeded. It will fail later
1733 * with a VM fault if the GPU tries to access
1734 * it. Better than hanging indefinitely with
1735 * stalled user mode queues.
1736 */
1737 }
1738
1739 /* Mark the BO as valid unless it was invalidated
1740 * again concurrently
1741 */
1742 if (atomic_cmpxchg(&mem->invalid, invalid, 0) != invalid)
1743 return -EAGAIN;
1744 }
1745
1746 return 0;
1747}
1748
1749/* Validate invalid userptr BOs
1750 *
1751 * Validates BOs on the userptr_inval_list, and moves them back to the
1752 * userptr_valid_list. Also updates GPUVM page tables with new page
1753 * addresses and waits for the page table updates to complete.
1754 */
1755static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
1756{
1757 struct amdgpu_bo_list_entry *pd_bo_list_entries;
1758 struct list_head resv_list, duplicates;
1759 struct ww_acquire_ctx ticket;
1760 struct amdgpu_sync sync;
1761
1762 struct amdgpu_vm *peer_vm;
1763 struct kgd_mem *mem, *tmp_mem;
1764 struct amdgpu_bo *bo;
1765 struct ttm_operation_ctx ctx = { false, false };
1766 int i, ret;
1767
1768 pd_bo_list_entries = kcalloc(process_info->n_vms,
1769 sizeof(struct amdgpu_bo_list_entry),
1770 GFP_KERNEL);
1771 if (!pd_bo_list_entries) {
1772 pr_err("%s: Failed to allocate PD BO list entries\n", __func__);
1773 return -ENOMEM;
1774 }
1775
1776 INIT_LIST_HEAD(&resv_list);
1777 INIT_LIST_HEAD(&duplicates);
1778
1779 /* Get all the page directory BOs that need to be reserved */
1780 i = 0;
1781 list_for_each_entry(peer_vm, &process_info->vm_list_head,
1782 vm_list_node)
1783 amdgpu_vm_get_pd_bo(peer_vm, &resv_list,
1784 &pd_bo_list_entries[i++]);
1785 /* Add the userptr_inval_list entries to resv_list */
1786 list_for_each_entry(mem, &process_info->userptr_inval_list,
1787 validate_list.head) {
1788 list_add_tail(&mem->resv_list.head, &resv_list);
1789 mem->resv_list.bo = mem->validate_list.bo;
1790 mem->resv_list.shared = mem->validate_list.shared;
1791 }
1792
1793 /* Reserve all BOs and page tables for validation */
1794 ret = ttm_eu_reserve_buffers(&ticket, &resv_list, false, &duplicates);
1795 WARN(!list_empty(&duplicates), "Duplicates should be empty");
1796 if (ret)
1797 goto out;
1798
1799 amdgpu_sync_create(&sync);
1800
1801 /* Avoid triggering eviction fences when unmapping invalid
1802 * userptr BOs (waits for all fences, doesn't use
1803 * FENCE_OWNER_VM)
1804 */
1805 list_for_each_entry(peer_vm, &process_info->vm_list_head,
1806 vm_list_node)
1807 amdgpu_amdkfd_remove_eviction_fence(peer_vm->root.base.bo,
1808 process_info->eviction_fence,
1809 NULL, NULL);
1810
1811 ret = process_validate_vms(process_info);
1812 if (ret)
1813 goto unreserve_out;
1814
1815 /* Validate BOs and update GPUVM page tables */
1816 list_for_each_entry_safe(mem, tmp_mem,
1817 &process_info->userptr_inval_list,
1818 validate_list.head) {
1819 struct kfd_bo_va_list *bo_va_entry;
1820
1821 bo = mem->bo;
1822
1823 /* Copy pages array and validate the BO if we got user pages */
1824 if (mem->user_pages[0]) {
1825 amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm,
1826 mem->user_pages);
1827 amdgpu_ttm_placement_from_domain(bo, mem->domain);
1828 ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
1829 if (ret) {
1830 pr_err("%s: failed to validate BO\n", __func__);
1831 goto unreserve_out;
1832 }
1833 }
1834
1835 /* Validate succeeded, now the BO owns the pages, free
1836 * our copy of the pointer array. Put this BO back on
1837 * the userptr_valid_list. If we need to revalidate
1838 * it, we need to start from scratch.
1839 */
1840 kvfree(mem->user_pages);
1841 mem->user_pages = NULL;
1842 list_move_tail(&mem->validate_list.head,
1843 &process_info->userptr_valid_list);
1844
1845 /* Update mapping. If the BO was not validated
1846 * (because we couldn't get user pages), this will
1847 * clear the page table entries, which will result in
1848 * VM faults if the GPU tries to access the invalid
1849 * memory.
1850 */
1851 list_for_each_entry(bo_va_entry, &mem->bo_va_list, bo_list) {
1852 if (!bo_va_entry->is_mapped)
1853 continue;
1854
1855 ret = update_gpuvm_pte((struct amdgpu_device *)
1856 bo_va_entry->kgd_dev,
1857 bo_va_entry, &sync);
1858 if (ret) {
1859 pr_err("%s: update PTE failed\n", __func__);
1860 /* make sure this gets validated again */
1861 atomic_inc(&mem->invalid);
1862 goto unreserve_out;
1863 }
1864 }
1865 }
1866
1867 /* Update page directories */
1868 ret = process_update_pds(process_info, &sync);
1869
1870unreserve_out:
1871 list_for_each_entry(peer_vm, &process_info->vm_list_head,
1872 vm_list_node)
1873 amdgpu_bo_fence(peer_vm->root.base.bo,
1874 &process_info->eviction_fence->base, true);
1875 ttm_eu_backoff_reservation(&ticket, &resv_list);
1876 amdgpu_sync_wait(&sync, false);
1877 amdgpu_sync_free(&sync);
1878out:
1879 kfree(pd_bo_list_entries);
1880
1881 return ret;
1882}
1883
1884/* Worker callback to restore evicted userptr BOs
1885 *
1886 * Tries to update and validate all userptr BOs. If successful and no
1887 * concurrent evictions happened, the queues are restarted. Otherwise,
1888 * reschedule for another attempt later.
1889 */
1890static void amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work)
1891{
1892 struct delayed_work *dwork = to_delayed_work(work);
1893 struct amdkfd_process_info *process_info =
1894 container_of(dwork, struct amdkfd_process_info,
1895 restore_userptr_work);
1896 struct task_struct *usertask;
1897 struct mm_struct *mm;
1898 int evicted_bos;
1899
1900 evicted_bos = atomic_read(&process_info->evicted_bos);
1901 if (!evicted_bos)
1902 return;
1903
1904 /* Reference task and mm in case of concurrent process termination */
1905 usertask = get_pid_task(process_info->pid, PIDTYPE_PID);
1906 if (!usertask)
1907 return;
1908 mm = get_task_mm(usertask);
1909 if (!mm) {
1910 put_task_struct(usertask);
1911 return;
1912 }
1913
1914 mutex_lock(&process_info->lock);
1915
1916 if (update_invalid_user_pages(process_info, mm))
1917 goto unlock_out;
1918 /* userptr_inval_list can be empty if all evicted userptr BOs
1919 * have been freed. In that case there is nothing to validate
1920 * and we can just restart the queues.
1921 */
1922 if (!list_empty(&process_info->userptr_inval_list)) {
1923 if (atomic_read(&process_info->evicted_bos) != evicted_bos)
1924 goto unlock_out; /* Concurrent eviction, try again */
1925
1926 if (validate_invalid_user_pages(process_info))
1927 goto unlock_out;
1928 }
1929 /* Final check for concurrent evicton and atomic update. If
1930 * another eviction happens after successful update, it will
1931 * be a first eviction that calls quiesce_mm. The eviction
1932 * reference counting inside KFD will handle this case.
1933 */
1934 if (atomic_cmpxchg(&process_info->evicted_bos, evicted_bos, 0) !=
1935 evicted_bos)
1936 goto unlock_out;
1937 evicted_bos = 0;
1938 if (kgd2kfd->resume_mm(mm)) {
1939 pr_err("%s: Failed to resume KFD\n", __func__);
1940 /* No recovery from this failure. Probably the CP is
1941 * hanging. No point trying again.
1942 */
1943 }
1944unlock_out:
1945 mutex_unlock(&process_info->lock);
1946 mmput(mm);
1947 put_task_struct(usertask);
1948
1949 /* If validation failed, reschedule another attempt */
1950 if (evicted_bos)
1951 schedule_delayed_work(&process_info->restore_userptr_work,
1952 msecs_to_jiffies(AMDGPU_USERPTR_RESTORE_DELAY_MS));
1953}
1954
1421/** amdgpu_amdkfd_gpuvm_restore_process_bos - Restore all BOs for the given 1955/** amdgpu_amdkfd_gpuvm_restore_process_bos - Restore all BOs for the given
1422 * KFD process identified by process_info 1956 * KFD process identified by process_info
1423 * 1957 *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
index a0f48cb9b8f0..236915849cfe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
@@ -322,3 +322,47 @@ int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev)
322 322
323 return ret; 323 return ret;
324} 324}
325
326union gfx_info {
327 struct atom_gfx_info_v2_4 v24;
328};
329
330int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev)
331{
332 struct amdgpu_mode_info *mode_info = &adev->mode_info;
333 int index;
334 uint8_t frev, crev;
335 uint16_t data_offset;
336
337 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
338 gfx_info);
339 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
340 &frev, &crev, &data_offset)) {
341 union gfx_info *gfx_info = (union gfx_info *)
342 (mode_info->atom_context->bios + data_offset);
343 switch (crev) {
344 case 4:
345 adev->gfx.config.max_shader_engines = gfx_info->v24.gc_num_se;
346 adev->gfx.config.max_cu_per_sh = gfx_info->v24.gc_num_cu_per_sh;
347 adev->gfx.config.max_sh_per_se = gfx_info->v24.gc_num_sh_per_se;
348 adev->gfx.config.max_backends_per_se = gfx_info->v24.gc_num_rb_per_se;
349 adev->gfx.config.max_texture_channel_caches = gfx_info->v24.gc_num_tccs;
350 adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v24.gc_num_gprs);
351 adev->gfx.config.max_gs_threads = gfx_info->v24.gc_num_max_gs_thds;
352 adev->gfx.config.gs_vgt_table_depth = gfx_info->v24.gc_gs_table_depth;
353 adev->gfx.config.gs_prim_buffer_depth =
354 le16_to_cpu(gfx_info->v24.gc_gsprim_buff_depth);
355 adev->gfx.config.double_offchip_lds_buf =
356 gfx_info->v24.gc_double_offchip_lds_buffer;
357 adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v24.gc_wave_size);
358 adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v24.gc_max_waves_per_simd);
359 adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v24.gc_max_scratch_slots_per_cu;
360 adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v24.gc_lds_size);
361 return 0;
362 default:
363 return -EINVAL;
364 }
365
366 }
367 return -EINVAL;
368}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
index 7689c961c4ef..20f158fd3b76 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
@@ -30,5 +30,6 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev);
30int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev); 30int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev);
31int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev); 31int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev);
32int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev); 32int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
33int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev);
33 34
34#endif 35#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
index 1ae5ae8c45a4..1bcb2b247335 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
@@ -550,7 +550,7 @@ static int amdgpu_atpx_init(void)
550 * look up whether we are the integrated or discrete GPU (all asics). 550 * look up whether we are the integrated or discrete GPU (all asics).
551 * Returns the client id. 551 * Returns the client id.
552 */ 552 */
553static int amdgpu_atpx_get_client_id(struct pci_dev *pdev) 553static enum vga_switcheroo_client_id amdgpu_atpx_get_client_id(struct pci_dev *pdev)
554{ 554{
555 if (amdgpu_atpx_priv.dhandle == ACPI_HANDLE(&pdev->dev)) 555 if (amdgpu_atpx_priv.dhandle == ACPI_HANDLE(&pdev->dev))
556 return VGA_SWITCHEROO_IGD; 556 return VGA_SWITCHEROO_IGD;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
index 02b849be083b..19cfff31f2e1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
@@ -75,13 +75,20 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
75{ 75{
76 struct amdgpu_bo *dobj = NULL; 76 struct amdgpu_bo *dobj = NULL;
77 struct amdgpu_bo *sobj = NULL; 77 struct amdgpu_bo *sobj = NULL;
78 struct amdgpu_bo_param bp;
78 uint64_t saddr, daddr; 79 uint64_t saddr, daddr;
79 int r, n; 80 int r, n;
80 int time; 81 int time;
81 82
83 memset(&bp, 0, sizeof(bp));
84 bp.size = size;
85 bp.byte_align = PAGE_SIZE;
86 bp.domain = sdomain;
87 bp.flags = 0;
88 bp.type = ttm_bo_type_kernel;
89 bp.resv = NULL;
82 n = AMDGPU_BENCHMARK_ITERATIONS; 90 n = AMDGPU_BENCHMARK_ITERATIONS;
83 r = amdgpu_bo_create(adev, size, PAGE_SIZE,sdomain, 0, 91 r = amdgpu_bo_create(adev, &bp, &sobj);
84 ttm_bo_type_kernel, NULL, &sobj);
85 if (r) { 92 if (r) {
86 goto out_cleanup; 93 goto out_cleanup;
87 } 94 }
@@ -93,8 +100,8 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
93 if (r) { 100 if (r) {
94 goto out_cleanup; 101 goto out_cleanup;
95 } 102 }
96 r = amdgpu_bo_create(adev, size, PAGE_SIZE, ddomain, 0, 103 bp.domain = ddomain;
97 ttm_bo_type_kernel, NULL, &dobj); 104 r = amdgpu_bo_create(adev, &bp, &dobj);
98 if (r) { 105 if (r) {
99 goto out_cleanup; 106 goto out_cleanup;
100 } 107 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
index 71a57b2f7f04..e950730f1933 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -23,7 +23,6 @@
23 */ 23 */
24#include <linux/list.h> 24#include <linux/list.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/pci.h>
27#include <drm/drmP.h> 26#include <drm/drmP.h>
28#include <linux/firmware.h> 27#include <linux/firmware.h>
29#include <drm/amdgpu_drm.h> 28#include <drm/amdgpu_drm.h>
@@ -109,121 +108,6 @@ static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
109 WARN(1, "Invalid indirect register space"); 108 WARN(1, "Invalid indirect register space");
110} 109}
111 110
112static int amdgpu_cgs_get_pci_resource(struct cgs_device *cgs_device,
113 enum cgs_resource_type resource_type,
114 uint64_t size,
115 uint64_t offset,
116 uint64_t *resource_base)
117{
118 CGS_FUNC_ADEV;
119
120 if (resource_base == NULL)
121 return -EINVAL;
122
123 switch (resource_type) {
124 case CGS_RESOURCE_TYPE_MMIO:
125 if (adev->rmmio_size == 0)
126 return -ENOENT;
127 if ((offset + size) > adev->rmmio_size)
128 return -EINVAL;
129 *resource_base = adev->rmmio_base;
130 return 0;
131 case CGS_RESOURCE_TYPE_DOORBELL:
132 if (adev->doorbell.size == 0)
133 return -ENOENT;
134 if ((offset + size) > adev->doorbell.size)
135 return -EINVAL;
136 *resource_base = adev->doorbell.base;
137 return 0;
138 case CGS_RESOURCE_TYPE_FB:
139 case CGS_RESOURCE_TYPE_IO:
140 case CGS_RESOURCE_TYPE_ROM:
141 default:
142 return -EINVAL;
143 }
144}
145
146static const void *amdgpu_cgs_atom_get_data_table(struct cgs_device *cgs_device,
147 unsigned table, uint16_t *size,
148 uint8_t *frev, uint8_t *crev)
149{
150 CGS_FUNC_ADEV;
151 uint16_t data_start;
152
153 if (amdgpu_atom_parse_data_header(
154 adev->mode_info.atom_context, table, size,
155 frev, crev, &data_start))
156 return (uint8_t*)adev->mode_info.atom_context->bios +
157 data_start;
158
159 return NULL;
160}
161
162static int amdgpu_cgs_atom_get_cmd_table_revs(struct cgs_device *cgs_device, unsigned table,
163 uint8_t *frev, uint8_t *crev)
164{
165 CGS_FUNC_ADEV;
166
167 if (amdgpu_atom_parse_cmd_header(
168 adev->mode_info.atom_context, table,
169 frev, crev))
170 return 0;
171
172 return -EINVAL;
173}
174
175static int amdgpu_cgs_atom_exec_cmd_table(struct cgs_device *cgs_device, unsigned table,
176 void *args)
177{
178 CGS_FUNC_ADEV;
179
180 return amdgpu_atom_execute_table(
181 adev->mode_info.atom_context, table, args);
182}
183
184static int amdgpu_cgs_set_clockgating_state(struct cgs_device *cgs_device,
185 enum amd_ip_block_type block_type,
186 enum amd_clockgating_state state)
187{
188 CGS_FUNC_ADEV;
189 int i, r = -1;
190
191 for (i = 0; i < adev->num_ip_blocks; i++) {
192 if (!adev->ip_blocks[i].status.valid)
193 continue;
194
195 if (adev->ip_blocks[i].version->type == block_type) {
196 r = adev->ip_blocks[i].version->funcs->set_clockgating_state(
197 (void *)adev,
198 state);
199 break;
200 }
201 }
202 return r;
203}
204
205static int amdgpu_cgs_set_powergating_state(struct cgs_device *cgs_device,
206 enum amd_ip_block_type block_type,
207 enum amd_powergating_state state)
208{
209 CGS_FUNC_ADEV;
210 int i, r = -1;
211
212 for (i = 0; i < adev->num_ip_blocks; i++) {
213 if (!adev->ip_blocks[i].status.valid)
214 continue;
215
216 if (adev->ip_blocks[i].version->type == block_type) {
217 r = adev->ip_blocks[i].version->funcs->set_powergating_state(
218 (void *)adev,
219 state);
220 break;
221 }
222 }
223 return r;
224}
225
226
227static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type) 111static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type)
228{ 112{
229 CGS_FUNC_ADEV; 113 CGS_FUNC_ADEV;
@@ -271,18 +155,6 @@ static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type)
271 return result; 155 return result;
272} 156}
273 157
274static int amdgpu_cgs_rel_firmware(struct cgs_device *cgs_device, enum cgs_ucode_id type)
275{
276 CGS_FUNC_ADEV;
277 if ((CGS_UCODE_ID_SMU == type) || (CGS_UCODE_ID_SMU_SK == type)) {
278 release_firmware(adev->pm.fw);
279 adev->pm.fw = NULL;
280 return 0;
281 }
282 /* cannot release other firmware because they are not created by cgs */
283 return -EINVAL;
284}
285
286static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device, 158static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device,
287 enum cgs_ucode_id type) 159 enum cgs_ucode_id type)
288{ 160{
@@ -326,34 +198,6 @@ static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device,
326 return fw_version; 198 return fw_version;
327} 199}
328 200
329static int amdgpu_cgs_enter_safe_mode(struct cgs_device *cgs_device,
330 bool en)
331{
332 CGS_FUNC_ADEV;
333
334 if (adev->gfx.rlc.funcs->enter_safe_mode == NULL ||
335 adev->gfx.rlc.funcs->exit_safe_mode == NULL)
336 return 0;
337
338 if (en)
339 adev->gfx.rlc.funcs->enter_safe_mode(adev);
340 else
341 adev->gfx.rlc.funcs->exit_safe_mode(adev);
342
343 return 0;
344}
345
346static void amdgpu_cgs_lock_grbm_idx(struct cgs_device *cgs_device,
347 bool lock)
348{
349 CGS_FUNC_ADEV;
350
351 if (lock)
352 mutex_lock(&adev->grbm_idx_mutex);
353 else
354 mutex_unlock(&adev->grbm_idx_mutex);
355}
356
357static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, 201static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
358 enum cgs_ucode_id type, 202 enum cgs_ucode_id type,
359 struct cgs_firmware_info *info) 203 struct cgs_firmware_info *info)
@@ -541,6 +385,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
541 case CHIP_POLARIS12: 385 case CHIP_POLARIS12:
542 strcpy(fw_name, "amdgpu/polaris12_smc.bin"); 386 strcpy(fw_name, "amdgpu/polaris12_smc.bin");
543 break; 387 break;
388 case CHIP_VEGAM:
389 strcpy(fw_name, "amdgpu/vegam_smc.bin");
390 break;
544 case CHIP_VEGA10: 391 case CHIP_VEGA10:
545 if ((adev->pdev->device == 0x687f) && 392 if ((adev->pdev->device == 0x687f) &&
546 ((adev->pdev->revision == 0xc0) || 393 ((adev->pdev->revision == 0xc0) ||
@@ -553,6 +400,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
553 case CHIP_VEGA12: 400 case CHIP_VEGA12:
554 strcpy(fw_name, "amdgpu/vega12_smc.bin"); 401 strcpy(fw_name, "amdgpu/vega12_smc.bin");
555 break; 402 break;
403 case CHIP_VEGA20:
404 strcpy(fw_name, "amdgpu/vega20_smc.bin");
405 break;
556 default: 406 default:
557 DRM_ERROR("SMC firmware not supported\n"); 407 DRM_ERROR("SMC firmware not supported\n");
558 return -EINVAL; 408 return -EINVAL;
@@ -598,97 +448,12 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
598 return 0; 448 return 0;
599} 449}
600 450
601static int amdgpu_cgs_is_virtualization_enabled(void *cgs_device)
602{
603 CGS_FUNC_ADEV;
604 return amdgpu_sriov_vf(adev);
605}
606
607static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device,
608 struct cgs_display_info *info)
609{
610 CGS_FUNC_ADEV;
611 struct cgs_mode_info *mode_info;
612
613 if (info == NULL)
614 return -EINVAL;
615
616 mode_info = info->mode_info;
617 if (mode_info)
618 /* if the displays are off, vblank time is max */
619 mode_info->vblank_time_us = 0xffffffff;
620
621 if (!amdgpu_device_has_dc_support(adev)) {
622 struct amdgpu_crtc *amdgpu_crtc;
623 struct drm_device *ddev = adev->ddev;
624 struct drm_crtc *crtc;
625 uint32_t line_time_us, vblank_lines;
626
627 if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
628 list_for_each_entry(crtc,
629 &ddev->mode_config.crtc_list, head) {
630 amdgpu_crtc = to_amdgpu_crtc(crtc);
631 if (crtc->enabled) {
632 info->active_display_mask |= (1 << amdgpu_crtc->crtc_id);
633 info->display_count++;
634 }
635 if (mode_info != NULL &&
636 crtc->enabled && amdgpu_crtc->enabled &&
637 amdgpu_crtc->hw_mode.clock) {
638 line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
639 amdgpu_crtc->hw_mode.clock;
640 vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
641 amdgpu_crtc->hw_mode.crtc_vdisplay +
642 (amdgpu_crtc->v_border * 2);
643 mode_info->vblank_time_us = vblank_lines * line_time_us;
644 mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
645 /* we have issues with mclk switching with refresh rates
646 * over 120 hz on the non-DC code.
647 */
648 if (mode_info->refresh_rate > 120)
649 mode_info->vblank_time_us = 0;
650 mode_info = NULL;
651 }
652 }
653 }
654 } else {
655 info->display_count = adev->pm.pm_display_cfg.num_display;
656 if (mode_info != NULL) {
657 mode_info->vblank_time_us = adev->pm.pm_display_cfg.min_vblank_time;
658 mode_info->refresh_rate = adev->pm.pm_display_cfg.vrefresh;
659 }
660 }
661 return 0;
662}
663
664
665static int amdgpu_cgs_notify_dpm_enabled(struct cgs_device *cgs_device, bool enabled)
666{
667 CGS_FUNC_ADEV;
668
669 adev->pm.dpm_enabled = enabled;
670
671 return 0;
672}
673
674static const struct cgs_ops amdgpu_cgs_ops = { 451static const struct cgs_ops amdgpu_cgs_ops = {
675 .read_register = amdgpu_cgs_read_register, 452 .read_register = amdgpu_cgs_read_register,
676 .write_register = amdgpu_cgs_write_register, 453 .write_register = amdgpu_cgs_write_register,
677 .read_ind_register = amdgpu_cgs_read_ind_register, 454 .read_ind_register = amdgpu_cgs_read_ind_register,
678 .write_ind_register = amdgpu_cgs_write_ind_register, 455 .write_ind_register = amdgpu_cgs_write_ind_register,
679 .get_pci_resource = amdgpu_cgs_get_pci_resource,
680 .atom_get_data_table = amdgpu_cgs_atom_get_data_table,
681 .atom_get_cmd_table_revs = amdgpu_cgs_atom_get_cmd_table_revs,
682 .atom_exec_cmd_table = amdgpu_cgs_atom_exec_cmd_table,
683 .get_firmware_info = amdgpu_cgs_get_firmware_info, 456 .get_firmware_info = amdgpu_cgs_get_firmware_info,
684 .rel_firmware = amdgpu_cgs_rel_firmware,
685 .set_powergating_state = amdgpu_cgs_set_powergating_state,
686 .set_clockgating_state = amdgpu_cgs_set_clockgating_state,
687 .get_active_displays_info = amdgpu_cgs_get_active_displays_info,
688 .notify_dpm_enabled = amdgpu_cgs_notify_dpm_enabled,
689 .is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled,
690 .enter_safe_mode = amdgpu_cgs_enter_safe_mode,
691 .lock_grbm_idx = amdgpu_cgs_lock_grbm_idx,
692}; 457};
693 458
694struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev) 459struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index 96501ff0e55b..8e66851eb427 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -691,7 +691,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector)
691 return ret; 691 return ret;
692} 692}
693 693
694static int amdgpu_connector_lvds_mode_valid(struct drm_connector *connector, 694static enum drm_mode_status amdgpu_connector_lvds_mode_valid(struct drm_connector *connector,
695 struct drm_display_mode *mode) 695 struct drm_display_mode *mode)
696{ 696{
697 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); 697 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
@@ -843,7 +843,7 @@ static int amdgpu_connector_vga_get_modes(struct drm_connector *connector)
843 return ret; 843 return ret;
844} 844}
845 845
846static int amdgpu_connector_vga_mode_valid(struct drm_connector *connector, 846static enum drm_mode_status amdgpu_connector_vga_mode_valid(struct drm_connector *connector,
847 struct drm_display_mode *mode) 847 struct drm_display_mode *mode)
848{ 848{
849 struct drm_device *dev = connector->dev; 849 struct drm_device *dev = connector->dev;
@@ -1172,7 +1172,7 @@ static void amdgpu_connector_dvi_force(struct drm_connector *connector)
1172 amdgpu_connector->use_digital = true; 1172 amdgpu_connector->use_digital = true;
1173} 1173}
1174 1174
1175static int amdgpu_connector_dvi_mode_valid(struct drm_connector *connector, 1175static enum drm_mode_status amdgpu_connector_dvi_mode_valid(struct drm_connector *connector,
1176 struct drm_display_mode *mode) 1176 struct drm_display_mode *mode)
1177{ 1177{
1178 struct drm_device *dev = connector->dev; 1178 struct drm_device *dev = connector->dev;
@@ -1448,7 +1448,7 @@ out:
1448 return ret; 1448 return ret;
1449} 1449}
1450 1450
1451static int amdgpu_connector_dp_mode_valid(struct drm_connector *connector, 1451static enum drm_mode_status amdgpu_connector_dp_mode_valid(struct drm_connector *connector,
1452 struct drm_display_mode *mode) 1452 struct drm_display_mode *mode)
1453{ 1453{
1454 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); 1454 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index dc34b50e6b29..9c1d491d742e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -382,8 +382,7 @@ retry:
382 382
383 p->bytes_moved += ctx.bytes_moved; 383 p->bytes_moved += ctx.bytes_moved;
384 if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size && 384 if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size &&
385 bo->tbo.mem.mem_type == TTM_PL_VRAM && 385 amdgpu_bo_in_cpu_visible_vram(bo))
386 bo->tbo.mem.start < adev->gmc.visible_vram_size >> PAGE_SHIFT)
387 p->bytes_moved_vis += ctx.bytes_moved; 386 p->bytes_moved_vis += ctx.bytes_moved;
388 387
389 if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) { 388 if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
@@ -411,7 +410,6 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
411 struct amdgpu_bo_list_entry *candidate = p->evictable; 410 struct amdgpu_bo_list_entry *candidate = p->evictable;
412 struct amdgpu_bo *bo = candidate->robj; 411 struct amdgpu_bo *bo = candidate->robj;
413 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 412 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
414 u64 initial_bytes_moved, bytes_moved;
415 bool update_bytes_moved_vis; 413 bool update_bytes_moved_vis;
416 uint32_t other; 414 uint32_t other;
417 415
@@ -435,18 +433,14 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
435 continue; 433 continue;
436 434
437 /* Good we can try to move this BO somewhere else */ 435 /* Good we can try to move this BO somewhere else */
438 amdgpu_ttm_placement_from_domain(bo, other);
439 update_bytes_moved_vis = 436 update_bytes_moved_vis =
440 adev->gmc.visible_vram_size < adev->gmc.real_vram_size && 437 adev->gmc.visible_vram_size < adev->gmc.real_vram_size &&
441 bo->tbo.mem.mem_type == TTM_PL_VRAM && 438 amdgpu_bo_in_cpu_visible_vram(bo);
442 bo->tbo.mem.start < adev->gmc.visible_vram_size >> PAGE_SHIFT; 439 amdgpu_ttm_placement_from_domain(bo, other);
443 initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
444 r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); 440 r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
445 bytes_moved = atomic64_read(&adev->num_bytes_moved) - 441 p->bytes_moved += ctx.bytes_moved;
446 initial_bytes_moved;
447 p->bytes_moved += bytes_moved;
448 if (update_bytes_moved_vis) 442 if (update_bytes_moved_vis)
449 p->bytes_moved_vis += bytes_moved; 443 p->bytes_moved_vis += ctx.bytes_moved;
450 444
451 if (unlikely(r)) 445 if (unlikely(r))
452 break; 446 break;
@@ -536,7 +530,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
536 if (p->bo_list) { 530 if (p->bo_list) {
537 amdgpu_bo_list_get_list(p->bo_list, &p->validated); 531 amdgpu_bo_list_get_list(p->bo_list, &p->validated);
538 if (p->bo_list->first_userptr != p->bo_list->num_entries) 532 if (p->bo_list->first_userptr != p->bo_list->num_entries)
539 p->mn = amdgpu_mn_get(p->adev); 533 p->mn = amdgpu_mn_get(p->adev, AMDGPU_MN_TYPE_GFX);
540 } 534 }
541 535
542 INIT_LIST_HEAD(&duplicates); 536 INIT_LIST_HEAD(&duplicates);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 3fabf9f97022..c5bb36275e93 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -91,7 +91,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
91 continue; 91 continue;
92 92
93 r = drm_sched_entity_init(&ring->sched, &ctx->rings[i].entity, 93 r = drm_sched_entity_init(&ring->sched, &ctx->rings[i].entity,
94 rq, amdgpu_sched_jobs, &ctx->guilty); 94 rq, &ctx->guilty);
95 if (r) 95 if (r)
96 goto failed; 96 goto failed;
97 } 97 }
@@ -111,8 +111,9 @@ failed:
111 return r; 111 return r;
112} 112}
113 113
114static void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) 114static void amdgpu_ctx_fini(struct kref *ref)
115{ 115{
116 struct amdgpu_ctx *ctx = container_of(ref, struct amdgpu_ctx, refcount);
116 struct amdgpu_device *adev = ctx->adev; 117 struct amdgpu_device *adev = ctx->adev;
117 unsigned i, j; 118 unsigned i, j;
118 119
@@ -125,13 +126,11 @@ static void amdgpu_ctx_fini(struct amdgpu_ctx *ctx)
125 kfree(ctx->fences); 126 kfree(ctx->fences);
126 ctx->fences = NULL; 127 ctx->fences = NULL;
127 128
128 for (i = 0; i < adev->num_rings; i++)
129 drm_sched_entity_fini(&adev->rings[i]->sched,
130 &ctx->rings[i].entity);
131
132 amdgpu_queue_mgr_fini(adev, &ctx->queue_mgr); 129 amdgpu_queue_mgr_fini(adev, &ctx->queue_mgr);
133 130
134 mutex_destroy(&ctx->lock); 131 mutex_destroy(&ctx->lock);
132
133 kfree(ctx);
135} 134}
136 135
137static int amdgpu_ctx_alloc(struct amdgpu_device *adev, 136static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
@@ -170,12 +169,20 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
170static void amdgpu_ctx_do_release(struct kref *ref) 169static void amdgpu_ctx_do_release(struct kref *ref)
171{ 170{
172 struct amdgpu_ctx *ctx; 171 struct amdgpu_ctx *ctx;
172 u32 i;
173 173
174 ctx = container_of(ref, struct amdgpu_ctx, refcount); 174 ctx = container_of(ref, struct amdgpu_ctx, refcount);
175 175
176 amdgpu_ctx_fini(ctx); 176 for (i = 0; i < ctx->adev->num_rings; i++) {
177 177
178 kfree(ctx); 178 if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring)
179 continue;
180
181 drm_sched_entity_fini(&ctx->adev->rings[i]->sched,
182 &ctx->rings[i].entity);
183 }
184
185 amdgpu_ctx_fini(ref);
179} 186}
180 187
181static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id) 188static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id)
@@ -437,16 +444,72 @@ void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
437 idr_init(&mgr->ctx_handles); 444 idr_init(&mgr->ctx_handles);
438} 445}
439 446
447void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
448{
449 struct amdgpu_ctx *ctx;
450 struct idr *idp;
451 uint32_t id, i;
452
453 idp = &mgr->ctx_handles;
454
455 idr_for_each_entry(idp, ctx, id) {
456
457 if (!ctx->adev)
458 return;
459
460 for (i = 0; i < ctx->adev->num_rings; i++) {
461
462 if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring)
463 continue;
464
465 if (kref_read(&ctx->refcount) == 1)
466 drm_sched_entity_do_release(&ctx->adev->rings[i]->sched,
467 &ctx->rings[i].entity);
468 else
469 DRM_ERROR("ctx %p is still alive\n", ctx);
470 }
471 }
472}
473
474void amdgpu_ctx_mgr_entity_cleanup(struct amdgpu_ctx_mgr *mgr)
475{
476 struct amdgpu_ctx *ctx;
477 struct idr *idp;
478 uint32_t id, i;
479
480 idp = &mgr->ctx_handles;
481
482 idr_for_each_entry(idp, ctx, id) {
483
484 if (!ctx->adev)
485 return;
486
487 for (i = 0; i < ctx->adev->num_rings; i++) {
488
489 if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring)
490 continue;
491
492 if (kref_read(&ctx->refcount) == 1)
493 drm_sched_entity_cleanup(&ctx->adev->rings[i]->sched,
494 &ctx->rings[i].entity);
495 else
496 DRM_ERROR("ctx %p is still alive\n", ctx);
497 }
498 }
499}
500
440void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr) 501void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
441{ 502{
442 struct amdgpu_ctx *ctx; 503 struct amdgpu_ctx *ctx;
443 struct idr *idp; 504 struct idr *idp;
444 uint32_t id; 505 uint32_t id;
445 506
507 amdgpu_ctx_mgr_entity_cleanup(mgr);
508
446 idp = &mgr->ctx_handles; 509 idp = &mgr->ctx_handles;
447 510
448 idr_for_each_entry(idp, ctx, id) { 511 idr_for_each_entry(idp, ctx, id) {
449 if (kref_put(&ctx->refcount, amdgpu_ctx_do_release) != 1) 512 if (kref_put(&ctx->refcount, amdgpu_ctx_fini) != 1)
450 DRM_ERROR("ctx %p is still alive\n", ctx); 513 DRM_ERROR("ctx %p is still alive\n", ctx);
451 } 514 }
452 515
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index 448d69fe3756..f5fb93795a69 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -28,8 +28,13 @@
28#include <linux/debugfs.h> 28#include <linux/debugfs.h>
29#include "amdgpu.h" 29#include "amdgpu.h"
30 30
31/* 31/**
32 * Debugfs 32 * amdgpu_debugfs_add_files - Add simple debugfs entries
33 *
34 * @adev: Device to attach debugfs entries to
35 * @files: Array of function callbacks that respond to reads
36 * @nfiles: Number of callbacks to register
37 *
33 */ 38 */
34int amdgpu_debugfs_add_files(struct amdgpu_device *adev, 39int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
35 const struct drm_info_list *files, 40 const struct drm_info_list *files,
@@ -64,7 +69,33 @@ int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
64 69
65#if defined(CONFIG_DEBUG_FS) 70#if defined(CONFIG_DEBUG_FS)
66 71
67 72/**
73 * amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes
74 *
75 * @read: True if reading
76 * @f: open file handle
77 * @buf: User buffer to write/read to
78 * @size: Number of bytes to write/read
79 * @pos: Offset to seek to
80 *
81 * This debugfs entry has special meaning on the offset being sought.
82 * Various bits have different meanings:
83 *
84 * Bit 62: Indicates a GRBM bank switch is needed
85 * Bit 61: Indicates a SRBM bank switch is needed (implies bit 62 is
86 * zero)
87 * Bits 24..33: The SE or ME selector if needed
88 * Bits 34..43: The SH (or SA) or PIPE selector if needed
89 * Bits 44..53: The INSTANCE (or CU/WGP) or QUEUE selector if needed
90 *
91 * Bit 23: Indicates that the PM power gating lock should be held
92 * This is necessary to read registers that might be
93 * unreliable during a power gating transistion.
94 *
95 * The lower bits are the BYTE offset of the register to read. This
96 * allows reading multiple registers in a single call and having
97 * the returned size reflect that.
98 */
68static int amdgpu_debugfs_process_reg_op(bool read, struct file *f, 99static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
69 char __user *buf, size_t size, loff_t *pos) 100 char __user *buf, size_t size, loff_t *pos)
70{ 101{
@@ -164,19 +195,37 @@ end:
164 return result; 195 return result;
165} 196}
166 197
167 198/**
199 * amdgpu_debugfs_regs_read - Callback for reading MMIO registers
200 */
168static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, 201static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
169 size_t size, loff_t *pos) 202 size_t size, loff_t *pos)
170{ 203{
171 return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos); 204 return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos);
172} 205}
173 206
207/**
208 * amdgpu_debugfs_regs_write - Callback for writing MMIO registers
209 */
174static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, 210static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
175 size_t size, loff_t *pos) 211 size_t size, loff_t *pos)
176{ 212{
177 return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos); 213 return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos);
178} 214}
179 215
216
217/**
218 * amdgpu_debugfs_regs_pcie_read - Read from a PCIE register
219 *
220 * @f: open file handle
221 * @buf: User buffer to store read data in
222 * @size: Number of bytes to read
223 * @pos: Offset to seek to
224 *
225 * The lower bits are the BYTE offset of the register to read. This
226 * allows reading multiple registers in a single call and having
227 * the returned size reflect that.
228 */
180static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, 229static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
181 size_t size, loff_t *pos) 230 size_t size, loff_t *pos)
182{ 231{
@@ -204,6 +253,18 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
204 return result; 253 return result;
205} 254}
206 255
256/**
257 * amdgpu_debugfs_regs_pcie_write - Write to a PCIE register
258 *
259 * @f: open file handle
260 * @buf: User buffer to write data from
261 * @size: Number of bytes to write
262 * @pos: Offset to seek to
263 *
264 * The lower bits are the BYTE offset of the register to write. This
265 * allows writing multiple registers in a single call and having
266 * the returned size reflect that.
267 */
207static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf, 268static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf,
208 size_t size, loff_t *pos) 269 size_t size, loff_t *pos)
209{ 270{
@@ -232,6 +293,18 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
232 return result; 293 return result;
233} 294}
234 295
296/**
297 * amdgpu_debugfs_regs_didt_read - Read from a DIDT register
298 *
299 * @f: open file handle
300 * @buf: User buffer to store read data in
301 * @size: Number of bytes to read
302 * @pos: Offset to seek to
303 *
304 * The lower bits are the BYTE offset of the register to read. This
305 * allows reading multiple registers in a single call and having
306 * the returned size reflect that.
307 */
235static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, 308static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
236 size_t size, loff_t *pos) 309 size_t size, loff_t *pos)
237{ 310{
@@ -259,6 +332,18 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
259 return result; 332 return result;
260} 333}
261 334
335/**
336 * amdgpu_debugfs_regs_didt_write - Write to a DIDT register
337 *
338 * @f: open file handle
339 * @buf: User buffer to write data from
340 * @size: Number of bytes to write
341 * @pos: Offset to seek to
342 *
343 * The lower bits are the BYTE offset of the register to write. This
344 * allows writing multiple registers in a single call and having
345 * the returned size reflect that.
346 */
262static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf, 347static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf,
263 size_t size, loff_t *pos) 348 size_t size, loff_t *pos)
264{ 349{
@@ -287,6 +372,18 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
287 return result; 372 return result;
288} 373}
289 374
375/**
376 * amdgpu_debugfs_regs_smc_read - Read from a SMC register
377 *
378 * @f: open file handle
379 * @buf: User buffer to store read data in
380 * @size: Number of bytes to read
381 * @pos: Offset to seek to
382 *
383 * The lower bits are the BYTE offset of the register to read. This
384 * allows reading multiple registers in a single call and having
385 * the returned size reflect that.
386 */
290static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, 387static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
291 size_t size, loff_t *pos) 388 size_t size, loff_t *pos)
292{ 389{
@@ -314,6 +411,18 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
314 return result; 411 return result;
315} 412}
316 413
414/**
415 * amdgpu_debugfs_regs_smc_write - Write to a SMC register
416 *
417 * @f: open file handle
418 * @buf: User buffer to write data from
419 * @size: Number of bytes to write
420 * @pos: Offset to seek to
421 *
422 * The lower bits are the BYTE offset of the register to write. This
423 * allows writing multiple registers in a single call and having
424 * the returned size reflect that.
425 */
317static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf, 426static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf,
318 size_t size, loff_t *pos) 427 size_t size, loff_t *pos)
319{ 428{
@@ -342,6 +451,20 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
342 return result; 451 return result;
343} 452}
344 453
454/**
455 * amdgpu_debugfs_gca_config_read - Read from gfx config data
456 *
457 * @f: open file handle
458 * @buf: User buffer to store read data in
459 * @size: Number of bytes to read
460 * @pos: Offset to seek to
461 *
462 * This file is used to access configuration data in a somewhat
463 * stable fashion. The format is a series of DWORDs with the first
464 * indicating which revision it is. New content is appended to the
465 * end so that older software can still read the data.
466 */
467
345static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, 468static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
346 size_t size, loff_t *pos) 469 size_t size, loff_t *pos)
347{ 470{
@@ -418,6 +541,19 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
418 return result; 541 return result;
419} 542}
420 543
544/**
545 * amdgpu_debugfs_sensor_read - Read from the powerplay sensors
546 *
547 * @f: open file handle
548 * @buf: User buffer to store read data in
549 * @size: Number of bytes to read
550 * @pos: Offset to seek to
551 *
552 * The offset is treated as the BYTE address of one of the sensors
553 * enumerated in amd/include/kgd_pp_interface.h under the
554 * 'amd_pp_sensors' enumeration. For instance to read the UVD VCLK
555 * you would use the offset 3 * 4 = 12.
556 */
421static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, 557static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
422 size_t size, loff_t *pos) 558 size_t size, loff_t *pos)
423{ 559{
@@ -428,7 +564,7 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
428 if (size & 3 || *pos & 0x3) 564 if (size & 3 || *pos & 0x3)
429 return -EINVAL; 565 return -EINVAL;
430 566
431 if (amdgpu_dpm == 0) 567 if (!adev->pm.dpm_enabled)
432 return -EINVAL; 568 return -EINVAL;
433 569
434 /* convert offset to sensor number */ 570 /* convert offset to sensor number */
@@ -457,6 +593,27 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
457 return !r ? outsize : r; 593 return !r ? outsize : r;
458} 594}
459 595
596/** amdgpu_debugfs_wave_read - Read WAVE STATUS data
597 *
598 * @f: open file handle
599 * @buf: User buffer to store read data in
600 * @size: Number of bytes to read
601 * @pos: Offset to seek to
602 *
603 * The offset being sought changes which wave that the status data
604 * will be returned for. The bits are used as follows:
605 *
606 * Bits 0..6: Byte offset into data
607 * Bits 7..14: SE selector
608 * Bits 15..22: SH/SA selector
609 * Bits 23..30: CU/{WGP+SIMD} selector
610 * Bits 31..36: WAVE ID selector
611 * Bits 37..44: SIMD ID selector
612 *
613 * The returned data begins with one DWORD of version information
614 * Followed by WAVE STATUS registers relevant to the GFX IP version
615 * being used. See gfx_v8_0_read_wave_data() for an example output.
616 */
460static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, 617static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
461 size_t size, loff_t *pos) 618 size_t size, loff_t *pos)
462{ 619{
@@ -507,6 +664,28 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
507 return result; 664 return result;
508} 665}
509 666
667/** amdgpu_debugfs_gpr_read - Read wave gprs
668 *
669 * @f: open file handle
670 * @buf: User buffer to store read data in
671 * @size: Number of bytes to read
672 * @pos: Offset to seek to
673 *
674 * The offset being sought changes which wave that the status data
675 * will be returned for. The bits are used as follows:
676 *
677 * Bits 0..11: Byte offset into data
678 * Bits 12..19: SE selector
679 * Bits 20..27: SH/SA selector
680 * Bits 28..35: CU/{WGP+SIMD} selector
681 * Bits 36..43: WAVE ID selector
682 * Bits 37..44: SIMD ID selector
683 * Bits 52..59: Thread selector
684 * Bits 60..61: Bank selector (VGPR=0,SGPR=1)
685 *
686 * The return data comes from the SGPR or VGPR register bank for
687 * the selected operational unit.
688 */
510static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, 689static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
511 size_t size, loff_t *pos) 690 size_t size, loff_t *pos)
512{ 691{
@@ -637,6 +816,12 @@ static const char *debugfs_regs_names[] = {
637 "amdgpu_gpr", 816 "amdgpu_gpr",
638}; 817};
639 818
819/**
820 * amdgpu_debugfs_regs_init - Initialize debugfs entries that provide
821 * register access.
822 *
823 * @adev: The device to attach the debugfs entries to
824 */
640int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) 825int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
641{ 826{
642 struct drm_minor *minor = adev->ddev->primary; 827 struct drm_minor *minor = adev->ddev->primary;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 34af664b9f93..290e279abf0d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -83,8 +83,10 @@ static const char *amdgpu_asic_name[] = {
83 "POLARIS10", 83 "POLARIS10",
84 "POLARIS11", 84 "POLARIS11",
85 "POLARIS12", 85 "POLARIS12",
86 "VEGAM",
86 "VEGA10", 87 "VEGA10",
87 "VEGA12", 88 "VEGA12",
89 "VEGA20",
88 "RAVEN", 90 "RAVEN",
89 "LAST", 91 "LAST",
90}; 92};
@@ -690,6 +692,8 @@ void amdgpu_device_gart_location(struct amdgpu_device *adev,
690{ 692{
691 u64 size_af, size_bf; 693 u64 size_af, size_bf;
692 694
695 mc->gart_size += adev->pm.smu_prv_buffer_size;
696
693 size_af = adev->gmc.mc_mask - mc->vram_end; 697 size_af = adev->gmc.mc_mask - mc->vram_end;
694 size_bf = mc->vram_start; 698 size_bf = mc->vram_start;
695 if (size_bf > size_af) { 699 if (size_bf > size_af) {
@@ -907,6 +911,46 @@ static void amdgpu_device_check_vm_size(struct amdgpu_device *adev)
907 } 911 }
908} 912}
909 913
914static void amdgpu_device_check_smu_prv_buffer_size(struct amdgpu_device *adev)
915{
916 struct sysinfo si;
917 bool is_os_64 = (sizeof(void *) == 8) ? true : false;
918 uint64_t total_memory;
919 uint64_t dram_size_seven_GB = 0x1B8000000;
920 uint64_t dram_size_three_GB = 0xB8000000;
921
922 if (amdgpu_smu_memory_pool_size == 0)
923 return;
924
925 if (!is_os_64) {
926 DRM_WARN("Not 64-bit OS, feature not supported\n");
927 goto def_value;
928 }
929 si_meminfo(&si);
930 total_memory = (uint64_t)si.totalram * si.mem_unit;
931
932 if ((amdgpu_smu_memory_pool_size == 1) ||
933 (amdgpu_smu_memory_pool_size == 2)) {
934 if (total_memory < dram_size_three_GB)
935 goto def_value1;
936 } else if ((amdgpu_smu_memory_pool_size == 4) ||
937 (amdgpu_smu_memory_pool_size == 8)) {
938 if (total_memory < dram_size_seven_GB)
939 goto def_value1;
940 } else {
941 DRM_WARN("Smu memory pool size not supported\n");
942 goto def_value;
943 }
944 adev->pm.smu_prv_buffer_size = amdgpu_smu_memory_pool_size << 28;
945
946 return;
947
948def_value1:
949 DRM_WARN("No enough system memory\n");
950def_value:
951 adev->pm.smu_prv_buffer_size = 0;
952}
953
910/** 954/**
911 * amdgpu_device_check_arguments - validate module params 955 * amdgpu_device_check_arguments - validate module params
912 * 956 *
@@ -948,6 +992,8 @@ static void amdgpu_device_check_arguments(struct amdgpu_device *adev)
948 amdgpu_vm_fragment_size = -1; 992 amdgpu_vm_fragment_size = -1;
949 } 993 }
950 994
995 amdgpu_device_check_smu_prv_buffer_size(adev);
996
951 amdgpu_device_check_vm_size(adev); 997 amdgpu_device_check_vm_size(adev);
952 998
953 amdgpu_device_check_block_size(adev); 999 amdgpu_device_check_block_size(adev);
@@ -1039,10 +1085,11 @@ static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = {
1039 * the hardware IP specified. 1085 * the hardware IP specified.
1040 * Returns the error code from the last instance. 1086 * Returns the error code from the last instance.
1041 */ 1087 */
1042int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev, 1088int amdgpu_device_ip_set_clockgating_state(void *dev,
1043 enum amd_ip_block_type block_type, 1089 enum amd_ip_block_type block_type,
1044 enum amd_clockgating_state state) 1090 enum amd_clockgating_state state)
1045{ 1091{
1092 struct amdgpu_device *adev = dev;
1046 int i, r = 0; 1093 int i, r = 0;
1047 1094
1048 for (i = 0; i < adev->num_ip_blocks; i++) { 1095 for (i = 0; i < adev->num_ip_blocks; i++) {
@@ -1072,10 +1119,11 @@ int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev,
1072 * the hardware IP specified. 1119 * the hardware IP specified.
1073 * Returns the error code from the last instance. 1120 * Returns the error code from the last instance.
1074 */ 1121 */
1075int amdgpu_device_ip_set_powergating_state(struct amdgpu_device *adev, 1122int amdgpu_device_ip_set_powergating_state(void *dev,
1076 enum amd_ip_block_type block_type, 1123 enum amd_ip_block_type block_type,
1077 enum amd_powergating_state state) 1124 enum amd_powergating_state state)
1078{ 1125{
1126 struct amdgpu_device *adev = dev;
1079 int i, r = 0; 1127 int i, r = 0;
1080 1128
1081 for (i = 0; i < adev->num_ip_blocks; i++) { 1129 for (i = 0; i < adev->num_ip_blocks; i++) {
@@ -1320,9 +1368,10 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
1320 case CHIP_TOPAZ: 1368 case CHIP_TOPAZ:
1321 case CHIP_TONGA: 1369 case CHIP_TONGA:
1322 case CHIP_FIJI: 1370 case CHIP_FIJI:
1323 case CHIP_POLARIS11:
1324 case CHIP_POLARIS10: 1371 case CHIP_POLARIS10:
1372 case CHIP_POLARIS11:
1325 case CHIP_POLARIS12: 1373 case CHIP_POLARIS12:
1374 case CHIP_VEGAM:
1326 case CHIP_CARRIZO: 1375 case CHIP_CARRIZO:
1327 case CHIP_STONEY: 1376 case CHIP_STONEY:
1328#ifdef CONFIG_DRM_AMDGPU_SI 1377#ifdef CONFIG_DRM_AMDGPU_SI
@@ -1339,6 +1388,7 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
1339 case CHIP_KABINI: 1388 case CHIP_KABINI:
1340 case CHIP_MULLINS: 1389 case CHIP_MULLINS:
1341#endif 1390#endif
1391 case CHIP_VEGA20:
1342 default: 1392 default:
1343 return 0; 1393 return 0;
1344 case CHIP_VEGA10: 1394 case CHIP_VEGA10:
@@ -1428,9 +1478,10 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
1428 case CHIP_TOPAZ: 1478 case CHIP_TOPAZ:
1429 case CHIP_TONGA: 1479 case CHIP_TONGA:
1430 case CHIP_FIJI: 1480 case CHIP_FIJI:
1431 case CHIP_POLARIS11:
1432 case CHIP_POLARIS10: 1481 case CHIP_POLARIS10:
1482 case CHIP_POLARIS11:
1433 case CHIP_POLARIS12: 1483 case CHIP_POLARIS12:
1484 case CHIP_VEGAM:
1434 case CHIP_CARRIZO: 1485 case CHIP_CARRIZO:
1435 case CHIP_STONEY: 1486 case CHIP_STONEY:
1436 if (adev->asic_type == CHIP_CARRIZO || adev->asic_type == CHIP_STONEY) 1487 if (adev->asic_type == CHIP_CARRIZO || adev->asic_type == CHIP_STONEY)
@@ -1472,6 +1523,7 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
1472#endif 1523#endif
1473 case CHIP_VEGA10: 1524 case CHIP_VEGA10:
1474 case CHIP_VEGA12: 1525 case CHIP_VEGA12:
1526 case CHIP_VEGA20:
1475 case CHIP_RAVEN: 1527 case CHIP_RAVEN:
1476 if (adev->asic_type == CHIP_RAVEN) 1528 if (adev->asic_type == CHIP_RAVEN)
1477 adev->family = AMDGPU_FAMILY_RV; 1529 adev->family = AMDGPU_FAMILY_RV;
@@ -1499,6 +1551,8 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
1499 return -EAGAIN; 1551 return -EAGAIN;
1500 } 1552 }
1501 1553
1554 adev->powerplay.pp_feature = amdgpu_pp_feature_mask;
1555
1502 for (i = 0; i < adev->num_ip_blocks; i++) { 1556 for (i = 0; i < adev->num_ip_blocks; i++) {
1503 if ((amdgpu_ip_block_mask & (1 << i)) == 0) { 1557 if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
1504 DRM_ERROR("disabled ip block: %d <%s>\n", 1558 DRM_ERROR("disabled ip block: %d <%s>\n",
@@ -1654,12 +1708,17 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev)
1654 if (amdgpu_emu_mode == 1) 1708 if (amdgpu_emu_mode == 1)
1655 return 0; 1709 return 0;
1656 1710
1711 r = amdgpu_ib_ring_tests(adev);
1712 if (r)
1713 DRM_ERROR("ib ring test failed (%d).\n", r);
1714
1657 for (i = 0; i < adev->num_ip_blocks; i++) { 1715 for (i = 0; i < adev->num_ip_blocks; i++) {
1658 if (!adev->ip_blocks[i].status.valid) 1716 if (!adev->ip_blocks[i].status.valid)
1659 continue; 1717 continue;
1660 /* skip CG for VCE/UVD, it's handled specially */ 1718 /* skip CG for VCE/UVD, it's handled specially */
1661 if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && 1719 if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
1662 adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && 1720 adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
1721 adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN &&
1663 adev->ip_blocks[i].version->funcs->set_clockgating_state) { 1722 adev->ip_blocks[i].version->funcs->set_clockgating_state) {
1664 /* enable clockgating to save power */ 1723 /* enable clockgating to save power */
1665 r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, 1724 r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
@@ -1704,8 +1763,8 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
1704 } 1763 }
1705 } 1764 }
1706 1765
1707 mod_delayed_work(system_wq, &adev->late_init_work, 1766 queue_delayed_work(system_wq, &adev->late_init_work,
1708 msecs_to_jiffies(AMDGPU_RESUME_MS)); 1767 msecs_to_jiffies(AMDGPU_RESUME_MS));
1709 1768
1710 amdgpu_device_fill_reset_magic(adev); 1769 amdgpu_device_fill_reset_magic(adev);
1711 1770
@@ -1759,6 +1818,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
1759 1818
1760 if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && 1819 if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
1761 adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && 1820 adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
1821 adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN &&
1762 adev->ip_blocks[i].version->funcs->set_clockgating_state) { 1822 adev->ip_blocks[i].version->funcs->set_clockgating_state) {
1763 /* ungate blocks before hw fini so that we can shutdown the blocks safely */ 1823 /* ungate blocks before hw fini so that we can shutdown the blocks safely */
1764 r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, 1824 r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
@@ -1850,6 +1910,12 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev)
1850 if (amdgpu_sriov_vf(adev)) 1910 if (amdgpu_sriov_vf(adev))
1851 amdgpu_virt_request_full_gpu(adev, false); 1911 amdgpu_virt_request_full_gpu(adev, false);
1852 1912
1913 /* ungate SMC block powergating */
1914 if (adev->powerplay.pp_feature & PP_GFXOFF_MASK)
1915 amdgpu_device_ip_set_powergating_state(adev,
1916 AMD_IP_BLOCK_TYPE_SMC,
1917 AMD_CG_STATE_UNGATE);
1918
1853 /* ungate SMC block first */ 1919 /* ungate SMC block first */
1854 r = amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_SMC, 1920 r = amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_SMC,
1855 AMD_CG_STATE_UNGATE); 1921 AMD_CG_STATE_UNGATE);
@@ -2086,16 +2152,15 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
2086 case CHIP_MULLINS: 2152 case CHIP_MULLINS:
2087 case CHIP_CARRIZO: 2153 case CHIP_CARRIZO:
2088 case CHIP_STONEY: 2154 case CHIP_STONEY:
2089 case CHIP_POLARIS11:
2090 case CHIP_POLARIS10: 2155 case CHIP_POLARIS10:
2156 case CHIP_POLARIS11:
2091 case CHIP_POLARIS12: 2157 case CHIP_POLARIS12:
2158 case CHIP_VEGAM:
2092 case CHIP_TONGA: 2159 case CHIP_TONGA:
2093 case CHIP_FIJI: 2160 case CHIP_FIJI:
2094#if defined(CONFIG_DRM_AMD_DC_PRE_VEGA)
2095 return amdgpu_dc != 0;
2096#endif
2097 case CHIP_VEGA10: 2161 case CHIP_VEGA10:
2098 case CHIP_VEGA12: 2162 case CHIP_VEGA12:
2163 case CHIP_VEGA20:
2099#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 2164#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
2100 case CHIP_RAVEN: 2165 case CHIP_RAVEN:
2101#endif 2166#endif
@@ -2375,10 +2440,6 @@ fence_driver_init:
2375 goto failed; 2440 goto failed;
2376 } 2441 }
2377 2442
2378 r = amdgpu_ib_ring_tests(adev);
2379 if (r)
2380 DRM_ERROR("ib ring test failed (%d).\n", r);
2381
2382 if (amdgpu_sriov_vf(adev)) 2443 if (amdgpu_sriov_vf(adev))
2383 amdgpu_virt_init_data_exchange(adev); 2444 amdgpu_virt_init_data_exchange(adev);
2384 2445
@@ -2539,7 +2600,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
2539 /* unpin the front buffers and cursors */ 2600 /* unpin the front buffers and cursors */
2540 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 2601 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
2541 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2602 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2542 struct amdgpu_framebuffer *rfb = to_amdgpu_framebuffer(crtc->primary->fb); 2603 struct drm_framebuffer *fb = crtc->primary->fb;
2543 struct amdgpu_bo *robj; 2604 struct amdgpu_bo *robj;
2544 2605
2545 if (amdgpu_crtc->cursor_bo) { 2606 if (amdgpu_crtc->cursor_bo) {
@@ -2551,10 +2612,10 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
2551 } 2612 }
2552 } 2613 }
2553 2614
2554 if (rfb == NULL || rfb->obj == NULL) { 2615 if (fb == NULL || fb->obj[0] == NULL) {
2555 continue; 2616 continue;
2556 } 2617 }
2557 robj = gem_to_amdgpu_bo(rfb->obj); 2618 robj = gem_to_amdgpu_bo(fb->obj[0]);
2558 /* don't unpin kernel fb objects */ 2619 /* don't unpin kernel fb objects */
2559 if (!amdgpu_fbdev_robj_is_fb(adev, robj)) { 2620 if (!amdgpu_fbdev_robj_is_fb(adev, robj)) {
2560 r = amdgpu_bo_reserve(robj, true); 2621 r = amdgpu_bo_reserve(robj, true);
@@ -2640,11 +2701,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
2640 } 2701 }
2641 amdgpu_fence_driver_resume(adev); 2702 amdgpu_fence_driver_resume(adev);
2642 2703
2643 if (resume) {
2644 r = amdgpu_ib_ring_tests(adev);
2645 if (r)
2646 DRM_ERROR("ib ring test failed (%d).\n", r);
2647 }
2648 2704
2649 r = amdgpu_device_ip_late_init(adev); 2705 r = amdgpu_device_ip_late_init(adev);
2650 if (r) 2706 if (r)
@@ -2736,6 +2792,9 @@ static bool amdgpu_device_ip_check_soft_reset(struct amdgpu_device *adev)
2736 if (amdgpu_sriov_vf(adev)) 2792 if (amdgpu_sriov_vf(adev))
2737 return true; 2793 return true;
2738 2794
2795 if (amdgpu_asic_need_full_reset(adev))
2796 return true;
2797
2739 for (i = 0; i < adev->num_ip_blocks; i++) { 2798 for (i = 0; i < adev->num_ip_blocks; i++) {
2740 if (!adev->ip_blocks[i].status.valid) 2799 if (!adev->ip_blocks[i].status.valid)
2741 continue; 2800 continue;
@@ -2792,6 +2851,9 @@ static bool amdgpu_device_ip_need_full_reset(struct amdgpu_device *adev)
2792{ 2851{
2793 int i; 2852 int i;
2794 2853
2854 if (amdgpu_asic_need_full_reset(adev))
2855 return true;
2856
2795 for (i = 0; i < adev->num_ip_blocks; i++) { 2857 for (i = 0; i < adev->num_ip_blocks; i++) {
2796 if (!adev->ip_blocks[i].status.valid) 2858 if (!adev->ip_blocks[i].status.valid)
2797 continue; 2859 continue;
@@ -3087,20 +3149,19 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
3087 3149
3088 /* now we are okay to resume SMC/CP/SDMA */ 3150 /* now we are okay to resume SMC/CP/SDMA */
3089 r = amdgpu_device_ip_reinit_late_sriov(adev); 3151 r = amdgpu_device_ip_reinit_late_sriov(adev);
3090 amdgpu_virt_release_full_gpu(adev, true);
3091 if (r) 3152 if (r)
3092 goto error; 3153 goto error;
3093 3154
3094 amdgpu_irq_gpu_reset_resume_helper(adev); 3155 amdgpu_irq_gpu_reset_resume_helper(adev);
3095 r = amdgpu_ib_ring_tests(adev); 3156 r = amdgpu_ib_ring_tests(adev);
3096 3157
3158error:
3159 amdgpu_virt_release_full_gpu(adev, true);
3097 if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) { 3160 if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
3098 atomic_inc(&adev->vram_lost_counter); 3161 atomic_inc(&adev->vram_lost_counter);
3099 r = amdgpu_device_handle_vram_lost(adev); 3162 r = amdgpu_device_handle_vram_lost(adev);
3100 } 3163 }
3101 3164
3102error:
3103
3104 return r; 3165 return r;
3105} 3166}
3106 3167
@@ -3117,7 +3178,6 @@ error:
3117int amdgpu_device_gpu_recover(struct amdgpu_device *adev, 3178int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
3118 struct amdgpu_job *job, bool force) 3179 struct amdgpu_job *job, bool force)
3119{ 3180{
3120 struct drm_atomic_state *state = NULL;
3121 int i, r, resched; 3181 int i, r, resched;
3122 3182
3123 if (!force && !amdgpu_device_ip_check_soft_reset(adev)) { 3183 if (!force && !amdgpu_device_ip_check_soft_reset(adev)) {
@@ -3140,10 +3200,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
3140 /* block TTM */ 3200 /* block TTM */
3141 resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); 3201 resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
3142 3202
3143 /* store modesetting */
3144 if (amdgpu_device_has_dc_support(adev))
3145 state = drm_atomic_helper_suspend(adev->ddev);
3146
3147 /* block all schedulers and reset given job's ring */ 3203 /* block all schedulers and reset given job's ring */
3148 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { 3204 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
3149 struct amdgpu_ring *ring = adev->rings[i]; 3205 struct amdgpu_ring *ring = adev->rings[i];
@@ -3183,10 +3239,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
3183 kthread_unpark(ring->sched.thread); 3239 kthread_unpark(ring->sched.thread);
3184 } 3240 }
3185 3241
3186 if (amdgpu_device_has_dc_support(adev)) { 3242 if (!amdgpu_device_has_dc_support(adev)) {
3187 if (drm_atomic_helper_resume(adev->ddev, state))
3188 dev_info(adev->dev, "drm resume failed:%d\n", r);
3189 } else {
3190 drm_helper_resume_force_mode(adev->ddev); 3243 drm_helper_resume_force_mode(adev->ddev);
3191 } 3244 }
3192 3245
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 93f700ab1bfb..76ee8e04ff11 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -35,6 +35,7 @@
35#include <linux/pm_runtime.h> 35#include <linux/pm_runtime.h>
36#include <drm/drm_crtc_helper.h> 36#include <drm/drm_crtc_helper.h>
37#include <drm/drm_edid.h> 37#include <drm/drm_edid.h>
38#include <drm/drm_gem_framebuffer_helper.h>
38#include <drm/drm_fb_helper.h> 39#include <drm/drm_fb_helper.h>
39 40
40static void amdgpu_display_flip_callback(struct dma_fence *f, 41static void amdgpu_display_flip_callback(struct dma_fence *f,
@@ -151,8 +152,6 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc,
151 struct drm_device *dev = crtc->dev; 152 struct drm_device *dev = crtc->dev;
152 struct amdgpu_device *adev = dev->dev_private; 153 struct amdgpu_device *adev = dev->dev_private;
153 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 154 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
154 struct amdgpu_framebuffer *old_amdgpu_fb;
155 struct amdgpu_framebuffer *new_amdgpu_fb;
156 struct drm_gem_object *obj; 155 struct drm_gem_object *obj;
157 struct amdgpu_flip_work *work; 156 struct amdgpu_flip_work *work;
158 struct amdgpu_bo *new_abo; 157 struct amdgpu_bo *new_abo;
@@ -174,15 +173,13 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc,
174 work->async = (page_flip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0; 173 work->async = (page_flip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0;
175 174
176 /* schedule unpin of the old buffer */ 175 /* schedule unpin of the old buffer */
177 old_amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); 176 obj = crtc->primary->fb->obj[0];
178 obj = old_amdgpu_fb->obj;
179 177
180 /* take a reference to the old object */ 178 /* take a reference to the old object */
181 work->old_abo = gem_to_amdgpu_bo(obj); 179 work->old_abo = gem_to_amdgpu_bo(obj);
182 amdgpu_bo_ref(work->old_abo); 180 amdgpu_bo_ref(work->old_abo);
183 181
184 new_amdgpu_fb = to_amdgpu_framebuffer(fb); 182 obj = fb->obj[0];
185 obj = new_amdgpu_fb->obj;
186 new_abo = gem_to_amdgpu_bo(obj); 183 new_abo = gem_to_amdgpu_bo(obj);
187 184
188 /* pin the new buffer */ 185 /* pin the new buffer */
@@ -192,7 +189,7 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc,
192 goto cleanup; 189 goto cleanup;
193 } 190 }
194 191
195 r = amdgpu_bo_pin(new_abo, amdgpu_display_framebuffer_domains(adev), &base); 192 r = amdgpu_bo_pin(new_abo, amdgpu_display_supported_domains(adev), &base);
196 if (unlikely(r != 0)) { 193 if (unlikely(r != 0)) {
197 DRM_ERROR("failed to pin new abo buffer before flip\n"); 194 DRM_ERROR("failed to pin new abo buffer before flip\n");
198 goto unreserve; 195 goto unreserve;
@@ -482,31 +479,12 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector,
482 return true; 479 return true;
483} 480}
484 481
485static void amdgpu_display_user_framebuffer_destroy(struct drm_framebuffer *fb)
486{
487 struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
488
489 drm_gem_object_put_unlocked(amdgpu_fb->obj);
490 drm_framebuffer_cleanup(fb);
491 kfree(amdgpu_fb);
492}
493
494static int amdgpu_display_user_framebuffer_create_handle(
495 struct drm_framebuffer *fb,
496 struct drm_file *file_priv,
497 unsigned int *handle)
498{
499 struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
500
501 return drm_gem_handle_create(file_priv, amdgpu_fb->obj, handle);
502}
503
504static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { 482static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
505 .destroy = amdgpu_display_user_framebuffer_destroy, 483 .destroy = drm_gem_fb_destroy,
506 .create_handle = amdgpu_display_user_framebuffer_create_handle, 484 .create_handle = drm_gem_fb_create_handle,
507}; 485};
508 486
509uint32_t amdgpu_display_framebuffer_domains(struct amdgpu_device *adev) 487uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev)
510{ 488{
511 uint32_t domain = AMDGPU_GEM_DOMAIN_VRAM; 489 uint32_t domain = AMDGPU_GEM_DOMAIN_VRAM;
512 490
@@ -526,11 +504,11 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
526 struct drm_gem_object *obj) 504 struct drm_gem_object *obj)
527{ 505{
528 int ret; 506 int ret;
529 rfb->obj = obj; 507 rfb->base.obj[0] = obj;
530 drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd); 508 drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
531 ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); 509 ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
532 if (ret) { 510 if (ret) {
533 rfb->obj = NULL; 511 rfb->base.obj[0] = NULL;
534 return ret; 512 return ret;
535 } 513 }
536 return 0; 514 return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h
index 2b11d808f297..f66e3e3fef0a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h
@@ -23,7 +23,7 @@
23#ifndef __AMDGPU_DISPLAY_H__ 23#ifndef __AMDGPU_DISPLAY_H__
24#define __AMDGPU_DISPLAY_H__ 24#define __AMDGPU_DISPLAY_H__
25 25
26uint32_t amdgpu_display_framebuffer_domains(struct amdgpu_device *adev); 26uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev);
27struct drm_framebuffer * 27struct drm_framebuffer *
28amdgpu_display_user_framebuffer_create(struct drm_device *dev, 28amdgpu_display_user_framebuffer_create(struct drm_device *dev,
29 struct drm_file *file_priv, 29 struct drm_file *file_priv,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
index e997ebbe43ea..def1010ac05e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
@@ -115,6 +115,26 @@ void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
115 pr_cont("\n"); 115 pr_cont("\n");
116} 116}
117 117
118void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev)
119{
120 struct drm_device *ddev = adev->ddev;
121 struct drm_crtc *crtc;
122 struct amdgpu_crtc *amdgpu_crtc;
123
124 adev->pm.dpm.new_active_crtcs = 0;
125 adev->pm.dpm.new_active_crtc_count = 0;
126 if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
127 list_for_each_entry(crtc,
128 &ddev->mode_config.crtc_list, head) {
129 amdgpu_crtc = to_amdgpu_crtc(crtc);
130 if (amdgpu_crtc->enabled) {
131 adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
132 adev->pm.dpm.new_active_crtc_count++;
133 }
134 }
135 }
136}
137
118 138
119u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev) 139u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
120{ 140{
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
index 643d008410c6..dd6203a0a6b7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
@@ -52,8 +52,6 @@ enum amdgpu_dpm_event_src {
52 AMDGPU_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4 52 AMDGPU_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4
53}; 53};
54 54
55#define SCLK_DEEP_SLEEP_MASK 0x8
56
57struct amdgpu_ps { 55struct amdgpu_ps {
58 u32 caps; /* vbios flags */ 56 u32 caps; /* vbios flags */
59 u32 class; /* vbios flags */ 57 u32 class; /* vbios flags */
@@ -349,12 +347,6 @@ enum amdgpu_pcie_gen {
349 ((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\ 347 ((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\
350 (adev)->powerplay.pp_handle, msg_id)) 348 (adev)->powerplay.pp_handle, msg_id))
351 349
352#define amdgpu_dpm_notify_smu_memory_info(adev, virtual_addr_low, \
353 virtual_addr_hi, mc_addr_low, mc_addr_hi, size) \
354 ((adev)->powerplay.pp_funcs->notify_smu_memory_info)( \
355 (adev)->powerplay.pp_handle, virtual_addr_low, \
356 virtual_addr_hi, mc_addr_low, mc_addr_hi, size)
357
358#define amdgpu_dpm_get_power_profile_mode(adev, buf) \ 350#define amdgpu_dpm_get_power_profile_mode(adev, buf) \
359 ((adev)->powerplay.pp_funcs->get_power_profile_mode(\ 351 ((adev)->powerplay.pp_funcs->get_power_profile_mode(\
360 (adev)->powerplay.pp_handle, buf)) 352 (adev)->powerplay.pp_handle, buf))
@@ -445,6 +437,8 @@ struct amdgpu_pm {
445 uint32_t pcie_gen_mask; 437 uint32_t pcie_gen_mask;
446 uint32_t pcie_mlw_mask; 438 uint32_t pcie_mlw_mask;
447 struct amd_pp_display_configuration pm_display_cfg;/* set by dc */ 439 struct amd_pp_display_configuration pm_display_cfg;/* set by dc */
440 uint32_t smu_prv_buffer_size;
441 struct amdgpu_bo *smu_prv_buffer;
448}; 442};
449 443
450#define R600_SSTU_DFLT 0 444#define R600_SSTU_DFLT 0
@@ -482,6 +476,7 @@ void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
482 struct amdgpu_ps *rps); 476 struct amdgpu_ps *rps);
483u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev); 477u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev);
484u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev); 478u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev);
479void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev);
485bool amdgpu_is_uvd_state(u32 class, u32 class2); 480bool amdgpu_is_uvd_state(u32 class, u32 class2);
486void amdgpu_calculate_u_and_p(u32 i, u32 r_c, u32 p_b, 481void amdgpu_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
487 u32 *p, u32 *u); 482 u32 *p, u32 *u);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 0b19482b36b8..b0bf2f24da48 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -75,9 +75,10 @@
75 * - 3.23.0 - Add query for VRAM lost counter 75 * - 3.23.0 - Add query for VRAM lost counter
76 * - 3.24.0 - Add high priority compute support for gfx9 76 * - 3.24.0 - Add high priority compute support for gfx9
77 * - 3.25.0 - Add support for sensor query info (stable pstate sclk/mclk). 77 * - 3.25.0 - Add support for sensor query info (stable pstate sclk/mclk).
78 * - 3.26.0 - GFX9: Process AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE.
78 */ 79 */
79#define KMS_DRIVER_MAJOR 3 80#define KMS_DRIVER_MAJOR 3
80#define KMS_DRIVER_MINOR 25 81#define KMS_DRIVER_MINOR 26
81#define KMS_DRIVER_PATCHLEVEL 0 82#define KMS_DRIVER_PATCHLEVEL 0
82 83
83int amdgpu_vram_limit = 0; 84int amdgpu_vram_limit = 0;
@@ -121,7 +122,7 @@ uint amdgpu_pg_mask = 0xffffffff;
121uint amdgpu_sdma_phase_quantum = 32; 122uint amdgpu_sdma_phase_quantum = 32;
122char *amdgpu_disable_cu = NULL; 123char *amdgpu_disable_cu = NULL;
123char *amdgpu_virtual_display = NULL; 124char *amdgpu_virtual_display = NULL;
124uint amdgpu_pp_feature_mask = 0xffffbfff; 125uint amdgpu_pp_feature_mask = 0xffff3fff; /* gfxoff (bit 15) disabled by default */
125int amdgpu_ngg = 0; 126int amdgpu_ngg = 0;
126int amdgpu_prim_buf_per_se = 0; 127int amdgpu_prim_buf_per_se = 0;
127int amdgpu_pos_buf_per_se = 0; 128int amdgpu_pos_buf_per_se = 0;
@@ -132,6 +133,7 @@ int amdgpu_lbpw = -1;
132int amdgpu_compute_multipipe = -1; 133int amdgpu_compute_multipipe = -1;
133int amdgpu_gpu_recovery = -1; /* auto */ 134int amdgpu_gpu_recovery = -1; /* auto */
134int amdgpu_emu_mode = 0; 135int amdgpu_emu_mode = 0;
136uint amdgpu_smu_memory_pool_size = 0;
135 137
136MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); 138MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
137module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); 139module_param_named(vramlimit, amdgpu_vram_limit, int, 0600);
@@ -316,6 +318,11 @@ MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)
316module_param_named(cik_support, amdgpu_cik_support, int, 0444); 318module_param_named(cik_support, amdgpu_cik_support, int, 0444);
317#endif 319#endif
318 320
321MODULE_PARM_DESC(smu_memory_pool_size,
322 "reserve gtt for smu debug usage, 0 = disable,"
323 "0x1 = 256Mbyte, 0x2 = 512Mbyte, 0x4 = 1 Gbyte, 0x8 = 2GByte");
324module_param_named(smu_memory_pool_size, amdgpu_smu_memory_pool_size, uint, 0444);
325
319static const struct pci_device_id pciidlist[] = { 326static const struct pci_device_id pciidlist[] = {
320#ifdef CONFIG_DRM_AMDGPU_SI 327#ifdef CONFIG_DRM_AMDGPU_SI
321 {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI}, 328 {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
@@ -534,6 +541,9 @@ static const struct pci_device_id pciidlist[] = {
534 {0x1002, 0x6995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, 541 {0x1002, 0x6995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
535 {0x1002, 0x6997, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, 542 {0x1002, 0x6997, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
536 {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, 543 {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
544 /* VEGAM */
545 {0x1002, 0x694C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGAM},
546 {0x1002, 0x694E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGAM},
537 /* Vega 10 */ 547 /* Vega 10 */
538 {0x1002, 0x6860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 548 {0x1002, 0x6860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
539 {0x1002, 0x6861, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 549 {0x1002, 0x6861, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
@@ -550,6 +560,13 @@ static const struct pci_device_id pciidlist[] = {
550 {0x1002, 0x69A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, 560 {0x1002, 0x69A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
551 {0x1002, 0x69A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, 561 {0x1002, 0x69A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
552 {0x1002, 0x69AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, 562 {0x1002, 0x69AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
563 /* Vega 20 */
564 {0x1002, 0x66A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT},
565 {0x1002, 0x66A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT},
566 {0x1002, 0x66A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT},
567 {0x1002, 0x66A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT},
568 {0x1002, 0x66A7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT},
569 {0x1002, 0x66AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT},
553 /* Raven */ 570 /* Raven */
554 {0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU}, 571 {0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU},
555 572
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 12063019751b..bc5fd8ebab5d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -137,7 +137,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
137 /* need to align pitch with crtc limits */ 137 /* need to align pitch with crtc limits */
138 mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp, 138 mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp,
139 fb_tiled); 139 fb_tiled);
140 domain = amdgpu_display_framebuffer_domains(adev); 140 domain = amdgpu_display_supported_domains(adev);
141 141
142 height = ALIGN(mode_cmd->height, 8); 142 height = ALIGN(mode_cmd->height, 8);
143 size = mode_cmd->pitches[0] * height; 143 size = mode_cmd->pitches[0] * height;
@@ -292,9 +292,9 @@ static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfb
292 292
293 drm_fb_helper_unregister_fbi(&rfbdev->helper); 293 drm_fb_helper_unregister_fbi(&rfbdev->helper);
294 294
295 if (rfb->obj) { 295 if (rfb->base.obj[0]) {
296 amdgpufb_destroy_pinned_object(rfb->obj); 296 amdgpufb_destroy_pinned_object(rfb->base.obj[0]);
297 rfb->obj = NULL; 297 rfb->base.obj[0] = NULL;
298 drm_framebuffer_unregister_private(&rfb->base); 298 drm_framebuffer_unregister_private(&rfb->base);
299 drm_framebuffer_cleanup(&rfb->base); 299 drm_framebuffer_cleanup(&rfb->base);
300 } 300 }
@@ -377,7 +377,7 @@ int amdgpu_fbdev_total_size(struct amdgpu_device *adev)
377 if (!adev->mode_info.rfbdev) 377 if (!adev->mode_info.rfbdev)
378 return 0; 378 return 0;
379 379
380 robj = gem_to_amdgpu_bo(adev->mode_info.rfbdev->rfb.obj); 380 robj = gem_to_amdgpu_bo(adev->mode_info.rfbdev->rfb.base.obj[0]);
381 size += amdgpu_bo_size(robj); 381 size += amdgpu_bo_size(robj);
382 return size; 382 return size;
383} 383}
@@ -386,7 +386,7 @@ bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
386{ 386{
387 if (!adev->mode_info.rfbdev) 387 if (!adev->mode_info.rfbdev)
388 return false; 388 return false;
389 if (robj == gem_to_amdgpu_bo(adev->mode_info.rfbdev->rfb.obj)) 389 if (robj == gem_to_amdgpu_bo(adev->mode_info.rfbdev->rfb.base.obj[0]))
390 return true; 390 return true;
391 return false; 391 return false;
392} 392}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 97449e06a242..39ec6b8890a1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -131,7 +131,8 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring)
131 * Emits a fence command on the requested ring (all asics). 131 * Emits a fence command on the requested ring (all asics).
132 * Returns 0 on success, -ENOMEM on failure. 132 * Returns 0 on success, -ENOMEM on failure.
133 */ 133 */
134int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f) 134int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
135 unsigned flags)
135{ 136{
136 struct amdgpu_device *adev = ring->adev; 137 struct amdgpu_device *adev = ring->adev;
137 struct amdgpu_fence *fence; 138 struct amdgpu_fence *fence;
@@ -149,7 +150,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f)
149 adev->fence_context + ring->idx, 150 adev->fence_context + ring->idx,
150 seq); 151 seq);
151 amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, 152 amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
152 seq, AMDGPU_FENCE_FLAG_INT); 153 seq, flags | AMDGPU_FENCE_FLAG_INT);
153 154
154 ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask]; 155 ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
155 /* This function can't be called concurrently anyway, otherwise 156 /* This function can't be called concurrently anyway, otherwise
@@ -375,14 +376,14 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
375 struct amdgpu_device *adev = ring->adev; 376 struct amdgpu_device *adev = ring->adev;
376 uint64_t index; 377 uint64_t index;
377 378
378 if (ring != &adev->uvd.ring) { 379 if (ring != &adev->uvd.inst[ring->me].ring) {
379 ring->fence_drv.cpu_addr = &adev->wb.wb[ring->fence_offs]; 380 ring->fence_drv.cpu_addr = &adev->wb.wb[ring->fence_offs];
380 ring->fence_drv.gpu_addr = adev->wb.gpu_addr + (ring->fence_offs * 4); 381 ring->fence_drv.gpu_addr = adev->wb.gpu_addr + (ring->fence_offs * 4);
381 } else { 382 } else {
382 /* put fence directly behind firmware */ 383 /* put fence directly behind firmware */
383 index = ALIGN(adev->uvd.fw->size, 8); 384 index = ALIGN(adev->uvd.fw->size, 8);
384 ring->fence_drv.cpu_addr = adev->uvd.cpu_addr + index; 385 ring->fence_drv.cpu_addr = adev->uvd.inst[ring->me].cpu_addr + index;
385 ring->fence_drv.gpu_addr = adev->uvd.gpu_addr + index; 386 ring->fence_drv.gpu_addr = adev->uvd.inst[ring->me].gpu_addr + index;
386 } 387 }
387 amdgpu_fence_write(ring, atomic_read(&ring->fence_drv.last_seq)); 388 amdgpu_fence_write(ring, atomic_read(&ring->fence_drv.last_seq));
388 amdgpu_irq_get(adev, irq_src, irq_type); 389 amdgpu_irq_get(adev, irq_src, irq_type);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
index cf0f186c6092..17d6b9fb6d77 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -113,12 +113,17 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
113 int r; 113 int r;
114 114
115 if (adev->gart.robj == NULL) { 115 if (adev->gart.robj == NULL) {
116 r = amdgpu_bo_create(adev, adev->gart.table_size, PAGE_SIZE, 116 struct amdgpu_bo_param bp;
117 AMDGPU_GEM_DOMAIN_VRAM, 117
118 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | 118 memset(&bp, 0, sizeof(bp));
119 AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, 119 bp.size = adev->gart.table_size;
120 ttm_bo_type_kernel, NULL, 120 bp.byte_align = PAGE_SIZE;
121 &adev->gart.robj); 121 bp.domain = AMDGPU_GEM_DOMAIN_VRAM;
122 bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
123 AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
124 bp.type = ttm_bo_type_kernel;
125 bp.resv = NULL;
126 r = amdgpu_bo_create(adev, &bp, &adev->gart.robj);
122 if (r) { 127 if (r) {
123 return r; 128 return r;
124 } 129 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 46b9ea4e6103..2c8e27370284 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -48,17 +48,25 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
48 struct drm_gem_object **obj) 48 struct drm_gem_object **obj)
49{ 49{
50 struct amdgpu_bo *bo; 50 struct amdgpu_bo *bo;
51 struct amdgpu_bo_param bp;
51 int r; 52 int r;
52 53
54 memset(&bp, 0, sizeof(bp));
53 *obj = NULL; 55 *obj = NULL;
54 /* At least align on page size */ 56 /* At least align on page size */
55 if (alignment < PAGE_SIZE) { 57 if (alignment < PAGE_SIZE) {
56 alignment = PAGE_SIZE; 58 alignment = PAGE_SIZE;
57 } 59 }
58 60
61 bp.size = size;
62 bp.byte_align = alignment;
63 bp.type = type;
64 bp.resv = resv;
65 bp.preferred_domain = initial_domain;
59retry: 66retry:
60 r = amdgpu_bo_create(adev, size, alignment, initial_domain, 67 bp.flags = flags;
61 flags, type, resv, &bo); 68 bp.domain = initial_domain;
69 r = amdgpu_bo_create(adev, &bp, &bo);
62 if (r) { 70 if (r) {
63 if (r != -ERESTARTSYS) { 71 if (r != -ERESTARTSYS) {
64 if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) { 72 if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
@@ -221,12 +229,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
221 return -EINVAL; 229 return -EINVAL;
222 230
223 /* reject invalid gem domains */ 231 /* reject invalid gem domains */
224 if (args->in.domains & ~(AMDGPU_GEM_DOMAIN_CPU | 232 if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
225 AMDGPU_GEM_DOMAIN_GTT |
226 AMDGPU_GEM_DOMAIN_VRAM |
227 AMDGPU_GEM_DOMAIN_GDS |
228 AMDGPU_GEM_DOMAIN_GWS |
229 AMDGPU_GEM_DOMAIN_OA))
230 return -EINVAL; 233 return -EINVAL;
231 234
232 /* create a gem object to contain this object in */ 235 /* create a gem object to contain this object in */
@@ -771,16 +774,23 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
771} 774}
772 775
773#if defined(CONFIG_DEBUG_FS) 776#if defined(CONFIG_DEBUG_FS)
777
778#define amdgpu_debugfs_gem_bo_print_flag(m, bo, flag) \
779 if (bo->flags & (AMDGPU_GEM_CREATE_ ## flag)) { \
780 seq_printf((m), " " #flag); \
781 }
782
774static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data) 783static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
775{ 784{
776 struct drm_gem_object *gobj = ptr; 785 struct drm_gem_object *gobj = ptr;
777 struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); 786 struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
778 struct seq_file *m = data; 787 struct seq_file *m = data;
779 788
789 struct dma_buf_attachment *attachment;
790 struct dma_buf *dma_buf;
780 unsigned domain; 791 unsigned domain;
781 const char *placement; 792 const char *placement;
782 unsigned pin_count; 793 unsigned pin_count;
783 uint64_t offset;
784 794
785 domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); 795 domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
786 switch (domain) { 796 switch (domain) {
@@ -798,13 +808,27 @@ static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
798 seq_printf(m, "\t0x%08x: %12ld byte %s", 808 seq_printf(m, "\t0x%08x: %12ld byte %s",
799 id, amdgpu_bo_size(bo), placement); 809 id, amdgpu_bo_size(bo), placement);
800 810
801 offset = READ_ONCE(bo->tbo.mem.start);
802 if (offset != AMDGPU_BO_INVALID_OFFSET)
803 seq_printf(m, " @ 0x%010Lx", offset);
804
805 pin_count = READ_ONCE(bo->pin_count); 811 pin_count = READ_ONCE(bo->pin_count);
806 if (pin_count) 812 if (pin_count)
807 seq_printf(m, " pin count %d", pin_count); 813 seq_printf(m, " pin count %d", pin_count);
814
815 dma_buf = READ_ONCE(bo->gem_base.dma_buf);
816 attachment = READ_ONCE(bo->gem_base.import_attach);
817
818 if (attachment)
819 seq_printf(m, " imported from %p", dma_buf);
820 else if (dma_buf)
821 seq_printf(m, " exported as %p", dma_buf);
822
823 amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_ACCESS_REQUIRED);
824 amdgpu_debugfs_gem_bo_print_flag(m, bo, NO_CPU_ACCESS);
825 amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_GTT_USWC);
826 amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CLEARED);
827 amdgpu_debugfs_gem_bo_print_flag(m, bo, SHADOW);
828 amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CONTIGUOUS);
829 amdgpu_debugfs_gem_bo_print_flag(m, bo, VM_ALWAYS_VALID);
830 amdgpu_debugfs_gem_bo_print_flag(m, bo, EXPLICIT_SYNC);
831
808 seq_printf(m, "\n"); 832 seq_printf(m, "\n");
809 833
810 return 0; 834 return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index 311589e02d17..f70eeed9ed76 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -127,6 +127,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
127 struct amdgpu_vm *vm; 127 struct amdgpu_vm *vm;
128 uint64_t fence_ctx; 128 uint64_t fence_ctx;
129 uint32_t status = 0, alloc_size; 129 uint32_t status = 0, alloc_size;
130 unsigned fence_flags = 0;
130 131
131 unsigned i; 132 unsigned i;
132 int r = 0; 133 int r = 0;
@@ -227,7 +228,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
227#endif 228#endif
228 amdgpu_asic_invalidate_hdp(adev, ring); 229 amdgpu_asic_invalidate_hdp(adev, ring);
229 230
230 r = amdgpu_fence_emit(ring, f); 231 if (ib->flags & AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE)
232 fence_flags |= AMDGPU_FENCE_FLAG_TC_WB_ONLY;
233
234 r = amdgpu_fence_emit(ring, f, fence_flags);
231 if (r) { 235 if (r) {
232 dev_err(adev->dev, "failed to emit fence (%d)\n", r); 236 dev_err(adev->dev, "failed to emit fence (%d)\n", r);
233 if (job && job->vmid) 237 if (job && job->vmid)
@@ -242,7 +246,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
242 /* wrap the last IB with fence */ 246 /* wrap the last IB with fence */
243 if (job && job->uf_addr) { 247 if (job && job->uf_addr) {
244 amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence, 248 amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence,
245 AMDGPU_FENCE_FLAG_64BIT); 249 fence_flags | AMDGPU_FENCE_FLAG_64BIT);
246 } 250 }
247 251
248 if (patch_offset != ~0 && ring->funcs->patch_cond_exec) 252 if (patch_offset != ~0 && ring->funcs->patch_cond_exec)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 4b7824d30e73..91517b166a3b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -31,6 +31,7 @@
31#include "amdgpu_sched.h" 31#include "amdgpu_sched.h"
32#include "amdgpu_uvd.h" 32#include "amdgpu_uvd.h"
33#include "amdgpu_vce.h" 33#include "amdgpu_vce.h"
34#include "atom.h"
34 35
35#include <linux/vga_switcheroo.h> 36#include <linux/vga_switcheroo.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
@@ -214,6 +215,18 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
214 fw_info->ver = adev->gfx.rlc_fw_version; 215 fw_info->ver = adev->gfx.rlc_fw_version;
215 fw_info->feature = adev->gfx.rlc_feature_version; 216 fw_info->feature = adev->gfx.rlc_feature_version;
216 break; 217 break;
218 case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL:
219 fw_info->ver = adev->gfx.rlc_srlc_fw_version;
220 fw_info->feature = adev->gfx.rlc_srlc_feature_version;
221 break;
222 case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM:
223 fw_info->ver = adev->gfx.rlc_srlg_fw_version;
224 fw_info->feature = adev->gfx.rlc_srlg_feature_version;
225 break;
226 case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM:
227 fw_info->ver = adev->gfx.rlc_srls_fw_version;
228 fw_info->feature = adev->gfx.rlc_srls_feature_version;
229 break;
217 case AMDGPU_INFO_FW_GFX_MEC: 230 case AMDGPU_INFO_FW_GFX_MEC:
218 if (query_fw->index == 0) { 231 if (query_fw->index == 0) {
219 fw_info->ver = adev->gfx.mec_fw_version; 232 fw_info->ver = adev->gfx.mec_fw_version;
@@ -273,12 +286,15 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
273 struct drm_crtc *crtc; 286 struct drm_crtc *crtc;
274 uint32_t ui32 = 0; 287 uint32_t ui32 = 0;
275 uint64_t ui64 = 0; 288 uint64_t ui64 = 0;
276 int i, found; 289 int i, j, found;
277 int ui32_size = sizeof(ui32); 290 int ui32_size = sizeof(ui32);
278 291
279 if (!info->return_size || !info->return_pointer) 292 if (!info->return_size || !info->return_pointer)
280 return -EINVAL; 293 return -EINVAL;
281 294
295 /* Ensure IB tests are run on ring */
296 flush_delayed_work(&adev->late_init_work);
297
282 switch (info->query) { 298 switch (info->query) {
283 case AMDGPU_INFO_ACCEL_WORKING: 299 case AMDGPU_INFO_ACCEL_WORKING:
284 ui32 = adev->accel_working; 300 ui32 = adev->accel_working;
@@ -332,7 +348,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
332 break; 348 break;
333 case AMDGPU_HW_IP_UVD: 349 case AMDGPU_HW_IP_UVD:
334 type = AMD_IP_BLOCK_TYPE_UVD; 350 type = AMD_IP_BLOCK_TYPE_UVD;
335 ring_mask = adev->uvd.ring.ready ? 1 : 0; 351 for (i = 0; i < adev->uvd.num_uvd_inst; i++)
352 ring_mask |= ((adev->uvd.inst[i].ring.ready ? 1 : 0) << i);
336 ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 353 ib_start_alignment = AMDGPU_GPU_PAGE_SIZE;
337 ib_size_alignment = 16; 354 ib_size_alignment = 16;
338 break; 355 break;
@@ -345,8 +362,11 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
345 break; 362 break;
346 case AMDGPU_HW_IP_UVD_ENC: 363 case AMDGPU_HW_IP_UVD_ENC:
347 type = AMD_IP_BLOCK_TYPE_UVD; 364 type = AMD_IP_BLOCK_TYPE_UVD;
348 for (i = 0; i < adev->uvd.num_enc_rings; i++) 365 for (i = 0; i < adev->uvd.num_uvd_inst; i++)
349 ring_mask |= ((adev->uvd.ring_enc[i].ready ? 1 : 0) << i); 366 for (j = 0; j < adev->uvd.num_enc_rings; j++)
367 ring_mask |=
368 ((adev->uvd.inst[i].ring_enc[j].ready ? 1 : 0) <<
369 (j + i * adev->uvd.num_enc_rings));
350 ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 370 ib_start_alignment = AMDGPU_GPU_PAGE_SIZE;
351 ib_size_alignment = 1; 371 ib_size_alignment = 1;
352 break; 372 break;
@@ -701,10 +721,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
701 } 721 }
702 } 722 }
703 case AMDGPU_INFO_SENSOR: { 723 case AMDGPU_INFO_SENSOR: {
704 struct pp_gpu_power query = {0}; 724 if (!adev->pm.dpm_enabled)
705 int query_size = sizeof(query);
706
707 if (amdgpu_dpm == 0)
708 return -ENOENT; 725 return -ENOENT;
709 726
710 switch (info->sensor_info.type) { 727 switch (info->sensor_info.type) {
@@ -746,10 +763,10 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
746 /* get average GPU power */ 763 /* get average GPU power */
747 if (amdgpu_dpm_read_sensor(adev, 764 if (amdgpu_dpm_read_sensor(adev,
748 AMDGPU_PP_SENSOR_GPU_POWER, 765 AMDGPU_PP_SENSOR_GPU_POWER,
749 (void *)&query, &query_size)) { 766 (void *)&ui32, &ui32_size)) {
750 return -EINVAL; 767 return -EINVAL;
751 } 768 }
752 ui32 = query.average_gpu_power >> 8; 769 ui32 >>= 8;
753 break; 770 break;
754 case AMDGPU_INFO_SENSOR_VDDNB: 771 case AMDGPU_INFO_SENSOR_VDDNB:
755 /* get VDDNB in millivolts */ 772 /* get VDDNB in millivolts */
@@ -913,8 +930,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
913 return; 930 return;
914 931
915 pm_runtime_get_sync(dev->dev); 932 pm_runtime_get_sync(dev->dev);
916 933 amdgpu_ctx_mgr_entity_fini(&fpriv->ctx_mgr);
917 amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
918 934
919 if (adev->asic_type != CHIP_RAVEN) { 935 if (adev->asic_type != CHIP_RAVEN) {
920 amdgpu_uvd_free_handles(adev, file_priv); 936 amdgpu_uvd_free_handles(adev, file_priv);
@@ -935,6 +951,8 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
935 pd = amdgpu_bo_ref(fpriv->vm.root.base.bo); 951 pd = amdgpu_bo_ref(fpriv->vm.root.base.bo);
936 952
937 amdgpu_vm_fini(adev, &fpriv->vm); 953 amdgpu_vm_fini(adev, &fpriv->vm);
954 amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
955
938 if (pasid) 956 if (pasid)
939 amdgpu_pasid_free_delayed(pd->tbo.resv, pasid); 957 amdgpu_pasid_free_delayed(pd->tbo.resv, pasid);
940 amdgpu_bo_unref(&pd); 958 amdgpu_bo_unref(&pd);
@@ -1088,6 +1106,7 @@ static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data)
1088 struct amdgpu_device *adev = dev->dev_private; 1106 struct amdgpu_device *adev = dev->dev_private;
1089 struct drm_amdgpu_info_firmware fw_info; 1107 struct drm_amdgpu_info_firmware fw_info;
1090 struct drm_amdgpu_query_fw query_fw; 1108 struct drm_amdgpu_query_fw query_fw;
1109 struct atom_context *ctx = adev->mode_info.atom_context;
1091 int ret, i; 1110 int ret, i;
1092 1111
1093 /* VCE */ 1112 /* VCE */
@@ -1146,6 +1165,30 @@ static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data)
1146 seq_printf(m, "RLC feature version: %u, firmware version: 0x%08x\n", 1165 seq_printf(m, "RLC feature version: %u, firmware version: 0x%08x\n",
1147 fw_info.feature, fw_info.ver); 1166 fw_info.feature, fw_info.ver);
1148 1167
1168 /* RLC SAVE RESTORE LIST CNTL */
1169 query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL;
1170 ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
1171 if (ret)
1172 return ret;
1173 seq_printf(m, "RLC SRLC feature version: %u, firmware version: 0x%08x\n",
1174 fw_info.feature, fw_info.ver);
1175
1176 /* RLC SAVE RESTORE LIST GPM MEM */
1177 query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM;
1178 ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
1179 if (ret)
1180 return ret;
1181 seq_printf(m, "RLC SRLG feature version: %u, firmware version: 0x%08x\n",
1182 fw_info.feature, fw_info.ver);
1183
1184 /* RLC SAVE RESTORE LIST SRM MEM */
1185 query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM;
1186 ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
1187 if (ret)
1188 return ret;
1189 seq_printf(m, "RLC SRLS feature version: %u, firmware version: 0x%08x\n",
1190 fw_info.feature, fw_info.ver);
1191
1149 /* MEC */ 1192 /* MEC */
1150 query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC; 1193 query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC;
1151 query_fw.index = 0; 1194 query_fw.index = 0;
@@ -1210,6 +1253,9 @@ static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data)
1210 seq_printf(m, "VCN feature version: %u, firmware version: 0x%08x\n", 1253 seq_printf(m, "VCN feature version: %u, firmware version: 0x%08x\n",
1211 fw_info.feature, fw_info.ver); 1254 fw_info.feature, fw_info.ver);
1212 1255
1256
1257 seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version);
1258
1213 return 0; 1259 return 0;
1214} 1260}
1215 1261
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index bd67f4cb8e6c..83e344fbb50a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -36,12 +36,14 @@
36#include <drm/drm.h> 36#include <drm/drm.h>
37 37
38#include "amdgpu.h" 38#include "amdgpu.h"
39#include "amdgpu_amdkfd.h"
39 40
40struct amdgpu_mn { 41struct amdgpu_mn {
41 /* constant after initialisation */ 42 /* constant after initialisation */
42 struct amdgpu_device *adev; 43 struct amdgpu_device *adev;
43 struct mm_struct *mm; 44 struct mm_struct *mm;
44 struct mmu_notifier mn; 45 struct mmu_notifier mn;
46 enum amdgpu_mn_type type;
45 47
46 /* only used on destruction */ 48 /* only used on destruction */
47 struct work_struct work; 49 struct work_struct work;
@@ -185,7 +187,7 @@ static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node,
185} 187}
186 188
187/** 189/**
188 * amdgpu_mn_invalidate_range_start - callback to notify about mm change 190 * amdgpu_mn_invalidate_range_start_gfx - callback to notify about mm change
189 * 191 *
190 * @mn: our notifier 192 * @mn: our notifier
191 * @mn: the mm this callback is about 193 * @mn: the mm this callback is about
@@ -195,10 +197,10 @@ static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node,
195 * We block for all BOs between start and end to be idle and 197 * We block for all BOs between start and end to be idle and
196 * unmap them by move them into system domain again. 198 * unmap them by move them into system domain again.
197 */ 199 */
198static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn, 200static void amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn,
199 struct mm_struct *mm, 201 struct mm_struct *mm,
200 unsigned long start, 202 unsigned long start,
201 unsigned long end) 203 unsigned long end)
202{ 204{
203 struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn); 205 struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn);
204 struct interval_tree_node *it; 206 struct interval_tree_node *it;
@@ -220,6 +222,49 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn,
220} 222}
221 223
222/** 224/**
225 * amdgpu_mn_invalidate_range_start_hsa - callback to notify about mm change
226 *
227 * @mn: our notifier
228 * @mn: the mm this callback is about
229 * @start: start of updated range
230 * @end: end of updated range
231 *
232 * We temporarily evict all BOs between start and end. This
233 * necessitates evicting all user-mode queues of the process. The BOs
234 * are restorted in amdgpu_mn_invalidate_range_end_hsa.
235 */
236static void amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn,
237 struct mm_struct *mm,
238 unsigned long start,
239 unsigned long end)
240{
241 struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn);
242 struct interval_tree_node *it;
243
244 /* notification is exclusive, but interval is inclusive */
245 end -= 1;
246
247 amdgpu_mn_read_lock(rmn);
248
249 it = interval_tree_iter_first(&rmn->objects, start, end);
250 while (it) {
251 struct amdgpu_mn_node *node;
252 struct amdgpu_bo *bo;
253
254 node = container_of(it, struct amdgpu_mn_node, it);
255 it = interval_tree_iter_next(it, start, end);
256
257 list_for_each_entry(bo, &node->bos, mn_list) {
258 struct kgd_mem *mem = bo->kfd_bo;
259
260 if (amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm,
261 start, end))
262 amdgpu_amdkfd_evict_userptr(mem, mm);
263 }
264 }
265}
266
267/**
223 * amdgpu_mn_invalidate_range_end - callback to notify about mm change 268 * amdgpu_mn_invalidate_range_end - callback to notify about mm change
224 * 269 *
225 * @mn: our notifier 270 * @mn: our notifier
@@ -239,23 +284,39 @@ static void amdgpu_mn_invalidate_range_end(struct mmu_notifier *mn,
239 amdgpu_mn_read_unlock(rmn); 284 amdgpu_mn_read_unlock(rmn);
240} 285}
241 286
242static const struct mmu_notifier_ops amdgpu_mn_ops = { 287static const struct mmu_notifier_ops amdgpu_mn_ops[] = {
243 .release = amdgpu_mn_release, 288 [AMDGPU_MN_TYPE_GFX] = {
244 .invalidate_range_start = amdgpu_mn_invalidate_range_start, 289 .release = amdgpu_mn_release,
245 .invalidate_range_end = amdgpu_mn_invalidate_range_end, 290 .invalidate_range_start = amdgpu_mn_invalidate_range_start_gfx,
291 .invalidate_range_end = amdgpu_mn_invalidate_range_end,
292 },
293 [AMDGPU_MN_TYPE_HSA] = {
294 .release = amdgpu_mn_release,
295 .invalidate_range_start = amdgpu_mn_invalidate_range_start_hsa,
296 .invalidate_range_end = amdgpu_mn_invalidate_range_end,
297 },
246}; 298};
247 299
300/* Low bits of any reasonable mm pointer will be unused due to struct
301 * alignment. Use these bits to make a unique key from the mm pointer
302 * and notifier type.
303 */
304#define AMDGPU_MN_KEY(mm, type) ((unsigned long)(mm) + (type))
305
248/** 306/**
249 * amdgpu_mn_get - create notifier context 307 * amdgpu_mn_get - create notifier context
250 * 308 *
251 * @adev: amdgpu device pointer 309 * @adev: amdgpu device pointer
310 * @type: type of MMU notifier context
252 * 311 *
253 * Creates a notifier context for current->mm. 312 * Creates a notifier context for current->mm.
254 */ 313 */
255struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) 314struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev,
315 enum amdgpu_mn_type type)
256{ 316{
257 struct mm_struct *mm = current->mm; 317 struct mm_struct *mm = current->mm;
258 struct amdgpu_mn *rmn; 318 struct amdgpu_mn *rmn;
319 unsigned long key = AMDGPU_MN_KEY(mm, type);
259 int r; 320 int r;
260 321
261 mutex_lock(&adev->mn_lock); 322 mutex_lock(&adev->mn_lock);
@@ -264,8 +325,8 @@ struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev)
264 return ERR_PTR(-EINTR); 325 return ERR_PTR(-EINTR);
265 } 326 }
266 327
267 hash_for_each_possible(adev->mn_hash, rmn, node, (unsigned long)mm) 328 hash_for_each_possible(adev->mn_hash, rmn, node, key)
268 if (rmn->mm == mm) 329 if (AMDGPU_MN_KEY(rmn->mm, rmn->type) == key)
269 goto release_locks; 330 goto release_locks;
270 331
271 rmn = kzalloc(sizeof(*rmn), GFP_KERNEL); 332 rmn = kzalloc(sizeof(*rmn), GFP_KERNEL);
@@ -276,8 +337,9 @@ struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev)
276 337
277 rmn->adev = adev; 338 rmn->adev = adev;
278 rmn->mm = mm; 339 rmn->mm = mm;
279 rmn->mn.ops = &amdgpu_mn_ops;
280 init_rwsem(&rmn->lock); 340 init_rwsem(&rmn->lock);
341 rmn->type = type;
342 rmn->mn.ops = &amdgpu_mn_ops[type];
281 rmn->objects = RB_ROOT_CACHED; 343 rmn->objects = RB_ROOT_CACHED;
282 mutex_init(&rmn->read_lock); 344 mutex_init(&rmn->read_lock);
283 atomic_set(&rmn->recursion, 0); 345 atomic_set(&rmn->recursion, 0);
@@ -286,7 +348,7 @@ struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev)
286 if (r) 348 if (r)
287 goto free_rmn; 349 goto free_rmn;
288 350
289 hash_add(adev->mn_hash, &rmn->node, (unsigned long)mm); 351 hash_add(adev->mn_hash, &rmn->node, AMDGPU_MN_KEY(mm, type));
290 352
291release_locks: 353release_locks:
292 up_write(&mm->mmap_sem); 354 up_write(&mm->mmap_sem);
@@ -315,15 +377,21 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
315{ 377{
316 unsigned long end = addr + amdgpu_bo_size(bo) - 1; 378 unsigned long end = addr + amdgpu_bo_size(bo) - 1;
317 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 379 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
380 enum amdgpu_mn_type type =
381 bo->kfd_bo ? AMDGPU_MN_TYPE_HSA : AMDGPU_MN_TYPE_GFX;
318 struct amdgpu_mn *rmn; 382 struct amdgpu_mn *rmn;
319 struct amdgpu_mn_node *node = NULL; 383 struct amdgpu_mn_node *node = NULL, *new_node;
320 struct list_head bos; 384 struct list_head bos;
321 struct interval_tree_node *it; 385 struct interval_tree_node *it;
322 386
323 rmn = amdgpu_mn_get(adev); 387 rmn = amdgpu_mn_get(adev, type);
324 if (IS_ERR(rmn)) 388 if (IS_ERR(rmn))
325 return PTR_ERR(rmn); 389 return PTR_ERR(rmn);
326 390
391 new_node = kmalloc(sizeof(*new_node), GFP_KERNEL);
392 if (!new_node)
393 return -ENOMEM;
394
327 INIT_LIST_HEAD(&bos); 395 INIT_LIST_HEAD(&bos);
328 396
329 down_write(&rmn->lock); 397 down_write(&rmn->lock);
@@ -337,13 +405,10 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
337 list_splice(&node->bos, &bos); 405 list_splice(&node->bos, &bos);
338 } 406 }
339 407
340 if (!node) { 408 if (!node)
341 node = kmalloc(sizeof(struct amdgpu_mn_node), GFP_KERNEL); 409 node = new_node;
342 if (!node) { 410 else
343 up_write(&rmn->lock); 411 kfree(new_node);
344 return -ENOMEM;
345 }
346 }
347 412
348 bo->mn = rmn; 413 bo->mn = rmn;
349 414
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
index d0095a3793b8..eb0f432f78fe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
@@ -29,16 +29,23 @@
29 */ 29 */
30struct amdgpu_mn; 30struct amdgpu_mn;
31 31
32enum amdgpu_mn_type {
33 AMDGPU_MN_TYPE_GFX,
34 AMDGPU_MN_TYPE_HSA,
35};
36
32#if defined(CONFIG_MMU_NOTIFIER) 37#if defined(CONFIG_MMU_NOTIFIER)
33void amdgpu_mn_lock(struct amdgpu_mn *mn); 38void amdgpu_mn_lock(struct amdgpu_mn *mn);
34void amdgpu_mn_unlock(struct amdgpu_mn *mn); 39void amdgpu_mn_unlock(struct amdgpu_mn *mn);
35struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev); 40struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev,
41 enum amdgpu_mn_type type);
36int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr); 42int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr);
37void amdgpu_mn_unregister(struct amdgpu_bo *bo); 43void amdgpu_mn_unregister(struct amdgpu_bo *bo);
38#else 44#else
39static inline void amdgpu_mn_lock(struct amdgpu_mn *mn) {} 45static inline void amdgpu_mn_lock(struct amdgpu_mn *mn) {}
40static inline void amdgpu_mn_unlock(struct amdgpu_mn *mn) {} 46static inline void amdgpu_mn_unlock(struct amdgpu_mn *mn) {}
41static inline struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) 47static inline struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev,
48 enum amdgpu_mn_type type)
42{ 49{
43 return NULL; 50 return NULL;
44} 51}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index d6416ee52e32..b9e9e8b02fb7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -308,7 +308,6 @@ struct amdgpu_display_funcs {
308 308
309struct amdgpu_framebuffer { 309struct amdgpu_framebuffer {
310 struct drm_framebuffer base; 310 struct drm_framebuffer base;
311 struct drm_gem_object *obj;
312 311
313 /* caching for later use */ 312 /* caching for later use */
314 uint64_t address; 313 uint64_t address;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 6d08cde8443c..6a9e46ae7f0a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -191,14 +191,21 @@ int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
191 u32 domain, struct amdgpu_bo **bo_ptr, 191 u32 domain, struct amdgpu_bo **bo_ptr,
192 u64 *gpu_addr, void **cpu_addr) 192 u64 *gpu_addr, void **cpu_addr)
193{ 193{
194 struct amdgpu_bo_param bp;
194 bool free = false; 195 bool free = false;
195 int r; 196 int r;
196 197
198 memset(&bp, 0, sizeof(bp));
199 bp.size = size;
200 bp.byte_align = align;
201 bp.domain = domain;
202 bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
203 AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
204 bp.type = ttm_bo_type_kernel;
205 bp.resv = NULL;
206
197 if (!*bo_ptr) { 207 if (!*bo_ptr) {
198 r = amdgpu_bo_create(adev, size, align, domain, 208 r = amdgpu_bo_create(adev, &bp, bo_ptr);
199 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
200 AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
201 ttm_bo_type_kernel, NULL, bo_ptr);
202 if (r) { 209 if (r) {
203 dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", 210 dev_err(adev->dev, "(%d) failed to allocate kernel bo\n",
204 r); 211 r);
@@ -341,27 +348,25 @@ fail:
341 return false; 348 return false;
342} 349}
343 350
344static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size, 351static int amdgpu_bo_do_create(struct amdgpu_device *adev,
345 int byte_align, u32 domain, 352 struct amdgpu_bo_param *bp,
346 u64 flags, enum ttm_bo_type type,
347 struct reservation_object *resv,
348 struct amdgpu_bo **bo_ptr) 353 struct amdgpu_bo **bo_ptr)
349{ 354{
350 struct ttm_operation_ctx ctx = { 355 struct ttm_operation_ctx ctx = {
351 .interruptible = (type != ttm_bo_type_kernel), 356 .interruptible = (bp->type != ttm_bo_type_kernel),
352 .no_wait_gpu = false, 357 .no_wait_gpu = false,
353 .resv = resv, 358 .resv = bp->resv,
354 .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT 359 .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT
355 }; 360 };
356 struct amdgpu_bo *bo; 361 struct amdgpu_bo *bo;
357 unsigned long page_align; 362 unsigned long page_align, size = bp->size;
358 size_t acc_size; 363 size_t acc_size;
359 int r; 364 int r;
360 365
361 page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; 366 page_align = roundup(bp->byte_align, PAGE_SIZE) >> PAGE_SHIFT;
362 size = ALIGN(size, PAGE_SIZE); 367 size = ALIGN(size, PAGE_SIZE);
363 368
364 if (!amdgpu_bo_validate_size(adev, size, domain)) 369 if (!amdgpu_bo_validate_size(adev, size, bp->domain))
365 return -ENOMEM; 370 return -ENOMEM;
366 371
367 *bo_ptr = NULL; 372 *bo_ptr = NULL;
@@ -375,18 +380,14 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,
375 drm_gem_private_object_init(adev->ddev, &bo->gem_base, size); 380 drm_gem_private_object_init(adev->ddev, &bo->gem_base, size);
376 INIT_LIST_HEAD(&bo->shadow_list); 381 INIT_LIST_HEAD(&bo->shadow_list);
377 INIT_LIST_HEAD(&bo->va); 382 INIT_LIST_HEAD(&bo->va);
378 bo->preferred_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM | 383 bo->preferred_domains = bp->preferred_domain ? bp->preferred_domain :
379 AMDGPU_GEM_DOMAIN_GTT | 384 bp->domain;
380 AMDGPU_GEM_DOMAIN_CPU |
381 AMDGPU_GEM_DOMAIN_GDS |
382 AMDGPU_GEM_DOMAIN_GWS |
383 AMDGPU_GEM_DOMAIN_OA);
384 bo->allowed_domains = bo->preferred_domains; 385 bo->allowed_domains = bo->preferred_domains;
385 if (type != ttm_bo_type_kernel && 386 if (bp->type != ttm_bo_type_kernel &&
386 bo->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM) 387 bo->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
387 bo->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; 388 bo->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT;
388 389
389 bo->flags = flags; 390 bo->flags = bp->flags;
390 391
391#ifdef CONFIG_X86_32 392#ifdef CONFIG_X86_32
392 /* XXX: Write-combined CPU mappings of GTT seem broken on 32-bit 393 /* XXX: Write-combined CPU mappings of GTT seem broken on 32-bit
@@ -417,11 +418,13 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,
417#endif 418#endif
418 419
419 bo->tbo.bdev = &adev->mman.bdev; 420 bo->tbo.bdev = &adev->mman.bdev;
420 amdgpu_ttm_placement_from_domain(bo, domain); 421 amdgpu_ttm_placement_from_domain(bo, bp->domain);
422 if (bp->type == ttm_bo_type_kernel)
423 bo->tbo.priority = 1;
421 424
422 r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type, 425 r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, bp->type,
423 &bo->placement, page_align, &ctx, acc_size, 426 &bo->placement, page_align, &ctx, acc_size,
424 NULL, resv, &amdgpu_ttm_bo_destroy); 427 NULL, bp->resv, &amdgpu_ttm_bo_destroy);
425 if (unlikely(r != 0)) 428 if (unlikely(r != 0))
426 return r; 429 return r;
427 430
@@ -433,10 +436,7 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,
433 else 436 else
434 amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved, 0); 437 amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved, 0);
435 438
436 if (type == ttm_bo_type_kernel) 439 if (bp->flags & AMDGPU_GEM_CREATE_VRAM_CLEARED &&
437 bo->tbo.priority = 1;
438
439 if (flags & AMDGPU_GEM_CREATE_VRAM_CLEARED &&
440 bo->tbo.mem.placement & TTM_PL_FLAG_VRAM) { 440 bo->tbo.mem.placement & TTM_PL_FLAG_VRAM) {
441 struct dma_fence *fence; 441 struct dma_fence *fence;
442 442
@@ -449,20 +449,20 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,
449 bo->tbo.moving = dma_fence_get(fence); 449 bo->tbo.moving = dma_fence_get(fence);
450 dma_fence_put(fence); 450 dma_fence_put(fence);
451 } 451 }
452 if (!resv) 452 if (!bp->resv)
453 amdgpu_bo_unreserve(bo); 453 amdgpu_bo_unreserve(bo);
454 *bo_ptr = bo; 454 *bo_ptr = bo;
455 455
456 trace_amdgpu_bo_create(bo); 456 trace_amdgpu_bo_create(bo);
457 457
458 /* Treat CPU_ACCESS_REQUIRED only as a hint if given by UMD */ 458 /* Treat CPU_ACCESS_REQUIRED only as a hint if given by UMD */
459 if (type == ttm_bo_type_device) 459 if (bp->type == ttm_bo_type_device)
460 bo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; 460 bo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
461 461
462 return 0; 462 return 0;
463 463
464fail_unreserve: 464fail_unreserve:
465 if (!resv) 465 if (!bp->resv)
466 ww_mutex_unlock(&bo->tbo.resv->lock); 466 ww_mutex_unlock(&bo->tbo.resv->lock);
467 amdgpu_bo_unref(&bo); 467 amdgpu_bo_unref(&bo);
468 return r; 468 return r;
@@ -472,16 +472,22 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
472 unsigned long size, int byte_align, 472 unsigned long size, int byte_align,
473 struct amdgpu_bo *bo) 473 struct amdgpu_bo *bo)
474{ 474{
475 struct amdgpu_bo_param bp;
475 int r; 476 int r;
476 477
477 if (bo->shadow) 478 if (bo->shadow)
478 return 0; 479 return 0;
479 480
480 r = amdgpu_bo_do_create(adev, size, byte_align, AMDGPU_GEM_DOMAIN_GTT, 481 memset(&bp, 0, sizeof(bp));
481 AMDGPU_GEM_CREATE_CPU_GTT_USWC | 482 bp.size = size;
482 AMDGPU_GEM_CREATE_SHADOW, 483 bp.byte_align = byte_align;
483 ttm_bo_type_kernel, 484 bp.domain = AMDGPU_GEM_DOMAIN_GTT;
484 bo->tbo.resv, &bo->shadow); 485 bp.flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC |
486 AMDGPU_GEM_CREATE_SHADOW;
487 bp.type = ttm_bo_type_kernel;
488 bp.resv = bo->tbo.resv;
489
490 r = amdgpu_bo_do_create(adev, &bp, &bo->shadow);
485 if (!r) { 491 if (!r) {
486 bo->shadow->parent = amdgpu_bo_ref(bo); 492 bo->shadow->parent = amdgpu_bo_ref(bo);
487 mutex_lock(&adev->shadow_list_lock); 493 mutex_lock(&adev->shadow_list_lock);
@@ -492,28 +498,26 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
492 return r; 498 return r;
493} 499}
494 500
495int amdgpu_bo_create(struct amdgpu_device *adev, unsigned long size, 501int amdgpu_bo_create(struct amdgpu_device *adev,
496 int byte_align, u32 domain, 502 struct amdgpu_bo_param *bp,
497 u64 flags, enum ttm_bo_type type,
498 struct reservation_object *resv,
499 struct amdgpu_bo **bo_ptr) 503 struct amdgpu_bo **bo_ptr)
500{ 504{
501 uint64_t parent_flags = flags & ~AMDGPU_GEM_CREATE_SHADOW; 505 u64 flags = bp->flags;
502 int r; 506 int r;
503 507
504 r = amdgpu_bo_do_create(adev, size, byte_align, domain, 508 bp->flags = bp->flags & ~AMDGPU_GEM_CREATE_SHADOW;
505 parent_flags, type, resv, bo_ptr); 509 r = amdgpu_bo_do_create(adev, bp, bo_ptr);
506 if (r) 510 if (r)
507 return r; 511 return r;
508 512
509 if ((flags & AMDGPU_GEM_CREATE_SHADOW) && amdgpu_need_backup(adev)) { 513 if ((flags & AMDGPU_GEM_CREATE_SHADOW) && amdgpu_need_backup(adev)) {
510 if (!resv) 514 if (!bp->resv)
511 WARN_ON(reservation_object_lock((*bo_ptr)->tbo.resv, 515 WARN_ON(reservation_object_lock((*bo_ptr)->tbo.resv,
512 NULL)); 516 NULL));
513 517
514 r = amdgpu_bo_create_shadow(adev, size, byte_align, (*bo_ptr)); 518 r = amdgpu_bo_create_shadow(adev, bp->size, bp->byte_align, (*bo_ptr));
515 519
516 if (!resv) 520 if (!bp->resv)
517 reservation_object_unlock((*bo_ptr)->tbo.resv); 521 reservation_object_unlock((*bo_ptr)->tbo.resv);
518 522
519 if (r) 523 if (r)
@@ -689,8 +693,21 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
689 return -EINVAL; 693 return -EINVAL;
690 694
691 /* A shared bo cannot be migrated to VRAM */ 695 /* A shared bo cannot be migrated to VRAM */
692 if (bo->prime_shared_count && (domain == AMDGPU_GEM_DOMAIN_VRAM)) 696 if (bo->prime_shared_count) {
693 return -EINVAL; 697 if (domain & AMDGPU_GEM_DOMAIN_GTT)
698 domain = AMDGPU_GEM_DOMAIN_GTT;
699 else
700 return -EINVAL;
701 }
702
703 /* This assumes only APU display buffers are pinned with (VRAM|GTT).
704 * See function amdgpu_display_supported_domains()
705 */
706 if (domain == (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT)) {
707 domain = AMDGPU_GEM_DOMAIN_VRAM;
708 if (adev->gmc.real_vram_size <= AMDGPU_SG_THRESHOLD)
709 domain = AMDGPU_GEM_DOMAIN_GTT;
710 }
694 711
695 if (bo->pin_count) { 712 if (bo->pin_count) {
696 uint32_t mem_type = bo->tbo.mem.mem_type; 713 uint32_t mem_type = bo->tbo.mem.mem_type;
@@ -838,6 +855,13 @@ int amdgpu_bo_init(struct amdgpu_device *adev)
838 return amdgpu_ttm_init(adev); 855 return amdgpu_ttm_init(adev);
839} 856}
840 857
858int amdgpu_bo_late_init(struct amdgpu_device *adev)
859{
860 amdgpu_ttm_late_init(adev);
861
862 return 0;
863}
864
841void amdgpu_bo_fini(struct amdgpu_device *adev) 865void amdgpu_bo_fini(struct amdgpu_device *adev)
842{ 866{
843 amdgpu_ttm_fini(adev); 867 amdgpu_ttm_fini(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 546f77cb7882..540e03fa159f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -33,6 +33,16 @@
33 33
34#define AMDGPU_BO_INVALID_OFFSET LONG_MAX 34#define AMDGPU_BO_INVALID_OFFSET LONG_MAX
35 35
36struct amdgpu_bo_param {
37 unsigned long size;
38 int byte_align;
39 u32 domain;
40 u32 preferred_domain;
41 u64 flags;
42 enum ttm_bo_type type;
43 struct reservation_object *resv;
44};
45
36/* bo virtual addresses in a vm */ 46/* bo virtual addresses in a vm */
37struct amdgpu_bo_va_mapping { 47struct amdgpu_bo_va_mapping {
38 struct amdgpu_bo_va *bo_va; 48 struct amdgpu_bo_va *bo_va;
@@ -196,6 +206,27 @@ static inline bool amdgpu_bo_gpu_accessible(struct amdgpu_bo *bo)
196} 206}
197 207
198/** 208/**
209 * amdgpu_bo_in_cpu_visible_vram - check if BO is (partly) in visible VRAM
210 */
211static inline bool amdgpu_bo_in_cpu_visible_vram(struct amdgpu_bo *bo)
212{
213 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
214 unsigned fpfn = adev->gmc.visible_vram_size >> PAGE_SHIFT;
215 struct drm_mm_node *node = bo->tbo.mem.mm_node;
216 unsigned long pages_left;
217
218 if (bo->tbo.mem.mem_type != TTM_PL_VRAM)
219 return false;
220
221 for (pages_left = bo->tbo.mem.num_pages; pages_left;
222 pages_left -= node->size, node++)
223 if (node->start < fpfn)
224 return true;
225
226 return false;
227}
228
229/**
199 * amdgpu_bo_explicit_sync - return whether the bo is explicitly synced 230 * amdgpu_bo_explicit_sync - return whether the bo is explicitly synced
200 */ 231 */
201static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo) 232static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo)
@@ -203,10 +234,8 @@ static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo)
203 return bo->flags & AMDGPU_GEM_CREATE_EXPLICIT_SYNC; 234 return bo->flags & AMDGPU_GEM_CREATE_EXPLICIT_SYNC;
204} 235}
205 236
206int amdgpu_bo_create(struct amdgpu_device *adev, unsigned long size, 237int amdgpu_bo_create(struct amdgpu_device *adev,
207 int byte_align, u32 domain, 238 struct amdgpu_bo_param *bp,
208 u64 flags, enum ttm_bo_type type,
209 struct reservation_object *resv,
210 struct amdgpu_bo **bo_ptr); 239 struct amdgpu_bo **bo_ptr);
211int amdgpu_bo_create_reserved(struct amdgpu_device *adev, 240int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
212 unsigned long size, int align, 241 unsigned long size, int align,
@@ -230,6 +259,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
230int amdgpu_bo_unpin(struct amdgpu_bo *bo); 259int amdgpu_bo_unpin(struct amdgpu_bo *bo);
231int amdgpu_bo_evict_vram(struct amdgpu_device *adev); 260int amdgpu_bo_evict_vram(struct amdgpu_device *adev);
232int amdgpu_bo_init(struct amdgpu_device *adev); 261int amdgpu_bo_init(struct amdgpu_device *adev);
262int amdgpu_bo_late_init(struct amdgpu_device *adev);
233void amdgpu_bo_fini(struct amdgpu_device *adev); 263void amdgpu_bo_fini(struct amdgpu_device *adev);
234int amdgpu_bo_fbdev_mmap(struct amdgpu_bo *bo, 264int amdgpu_bo_fbdev_mmap(struct amdgpu_bo *bo,
235 struct vm_area_struct *vma); 265 struct vm_area_struct *vma);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 361975cf45a9..b455da487782 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -77,6 +77,37 @@ void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
77 } 77 }
78} 78}
79 79
80/**
81 * DOC: power_dpm_state
82 *
83 * This is a legacy interface and is only provided for backwards compatibility.
84 * The amdgpu driver provides a sysfs API for adjusting certain power
85 * related parameters. The file power_dpm_state is used for this.
86 * It accepts the following arguments:
87 * - battery
88 * - balanced
89 * - performance
90 *
91 * battery
92 *
93 * On older GPUs, the vbios provided a special power state for battery
94 * operation. Selecting battery switched to this state. This is no
95 * longer provided on newer GPUs so the option does nothing in that case.
96 *
97 * balanced
98 *
99 * On older GPUs, the vbios provided a special power state for balanced
100 * operation. Selecting balanced switched to this state. This is no
101 * longer provided on newer GPUs so the option does nothing in that case.
102 *
103 * performance
104 *
105 * On older GPUs, the vbios provided a special power state for performance
106 * operation. Selecting performance switched to this state. This is no
107 * longer provided on newer GPUs so the option does nothing in that case.
108 *
109 */
110
80static ssize_t amdgpu_get_dpm_state(struct device *dev, 111static ssize_t amdgpu_get_dpm_state(struct device *dev,
81 struct device_attribute *attr, 112 struct device_attribute *attr,
82 char *buf) 113 char *buf)
@@ -131,6 +162,59 @@ fail:
131 return count; 162 return count;
132} 163}
133 164
165
166/**
167 * DOC: power_dpm_force_performance_level
168 *
169 * The amdgpu driver provides a sysfs API for adjusting certain power
170 * related parameters. The file power_dpm_force_performance_level is
171 * used for this. It accepts the following arguments:
172 * - auto
173 * - low
174 * - high
175 * - manual
176 * - GPU fan
177 * - profile_standard
178 * - profile_min_sclk
179 * - profile_min_mclk
180 * - profile_peak
181 *
182 * auto
183 *
184 * When auto is selected, the driver will attempt to dynamically select
185 * the optimal power profile for current conditions in the driver.
186 *
187 * low
188 *
189 * When low is selected, the clocks are forced to the lowest power state.
190 *
191 * high
192 *
193 * When high is selected, the clocks are forced to the highest power state.
194 *
195 * manual
196 *
197 * When manual is selected, the user can manually adjust which power states
198 * are enabled for each clock domain via the sysfs pp_dpm_mclk, pp_dpm_sclk,
199 * and pp_dpm_pcie files and adjust the power state transition heuristics
200 * via the pp_power_profile_mode sysfs file.
201 *
202 * profile_standard
203 * profile_min_sclk
204 * profile_min_mclk
205 * profile_peak
206 *
207 * When the profiling modes are selected, clock and power gating are
208 * disabled and the clocks are set for different profiling cases. This
209 * mode is recommended for profiling specific work loads where you do
210 * not want clock or power gating for clock fluctuation to interfere
211 * with your results. profile_standard sets the clocks to a fixed clock
212 * level which varies from asic to asic. profile_min_sclk forces the sclk
213 * to the lowest level. profile_min_mclk forces the mclk to the lowest level.
214 * profile_peak sets all clocks (mclk, sclk, pcie) to the highest levels.
215 *
216 */
217
134static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev, 218static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,
135 struct device_attribute *attr, 219 struct device_attribute *attr,
136 char *buf) 220 char *buf)
@@ -324,6 +408,17 @@ fail:
324 return count; 408 return count;
325} 409}
326 410
411/**
412 * DOC: pp_table
413 *
414 * The amdgpu driver provides a sysfs API for uploading new powerplay
415 * tables. The file pp_table is used for this. Reading the file
416 * will dump the current power play table. Writing to the file
417 * will attempt to upload a new powerplay table and re-initialize
418 * powerplay using that new table.
419 *
420 */
421
327static ssize_t amdgpu_get_pp_table(struct device *dev, 422static ssize_t amdgpu_get_pp_table(struct device *dev,
328 struct device_attribute *attr, 423 struct device_attribute *attr,
329 char *buf) 424 char *buf)
@@ -360,6 +455,29 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
360 return count; 455 return count;
361} 456}
362 457
458/**
459 * DOC: pp_od_clk_voltage
460 *
461 * The amdgpu driver provides a sysfs API for adjusting the clocks and voltages
462 * in each power level within a power state. The pp_od_clk_voltage is used for
463 * this.
464 *
465 * Reading the file will display:
466 * - a list of engine clock levels and voltages labeled OD_SCLK
467 * - a list of memory clock levels and voltages labeled OD_MCLK
468 * - a list of valid ranges for sclk, mclk, and voltage labeled OD_RANGE
469 *
470 * To manually adjust these settings, first select manual using
471 * power_dpm_force_performance_level. Enter a new value for each
472 * level by writing a string that contains "s/m level clock voltage" to
473 * the file. E.g., "s 1 500 820" will update sclk level 1 to be 500 MHz
474 * at 820 mV; "m 0 350 810" will update mclk level 0 to be 350 MHz at
475 * 810 mV. When you have edited all of the states as needed, write
476 * "c" (commit) to the file to commit your changes. If you want to reset to the
477 * default power levels, write "r" (reset) to the file to reset them.
478 *
479 */
480
363static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, 481static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
364 struct device_attribute *attr, 482 struct device_attribute *attr,
365 const char *buf, 483 const char *buf,
@@ -437,6 +555,7 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
437 if (adev->powerplay.pp_funcs->print_clock_levels) { 555 if (adev->powerplay.pp_funcs->print_clock_levels) {
438 size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf); 556 size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf);
439 size += amdgpu_dpm_print_clock_levels(adev, OD_MCLK, buf+size); 557 size += amdgpu_dpm_print_clock_levels(adev, OD_MCLK, buf+size);
558 size += amdgpu_dpm_print_clock_levels(adev, OD_RANGE, buf+size);
440 return size; 559 return size;
441 } else { 560 } else {
442 return snprintf(buf, PAGE_SIZE, "\n"); 561 return snprintf(buf, PAGE_SIZE, "\n");
@@ -444,6 +563,23 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
444 563
445} 564}
446 565
566/**
567 * DOC: pp_dpm_sclk pp_dpm_mclk pp_dpm_pcie
568 *
569 * The amdgpu driver provides a sysfs API for adjusting what power levels
570 * are enabled for a given power state. The files pp_dpm_sclk, pp_dpm_mclk,
571 * and pp_dpm_pcie are used for this.
572 *
573 * Reading back the files will show you the available power levels within
574 * the power state and the clock information for those levels.
575 *
576 * To manually adjust these states, first select manual using
577 * power_dpm_force_performance_level.
578 * Secondly,Enter a new value for each level by inputing a string that
579 * contains " echo xx xx xx > pp_dpm_sclk/mclk/pcie"
580 * E.g., echo 4 5 6 to > pp_dpm_sclk will enable sclk levels 4, 5, and 6.
581 */
582
447static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, 583static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev,
448 struct device_attribute *attr, 584 struct device_attribute *attr,
449 char *buf) 585 char *buf)
@@ -466,23 +602,27 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev,
466 struct amdgpu_device *adev = ddev->dev_private; 602 struct amdgpu_device *adev = ddev->dev_private;
467 int ret; 603 int ret;
468 long level; 604 long level;
469 uint32_t i, mask = 0; 605 uint32_t mask = 0;
470 char sub_str[2]; 606 char *sub_str = NULL;
607 char *tmp;
608 char buf_cpy[count];
609 const char delimiter[3] = {' ', '\n', '\0'};
471 610
472 for (i = 0; i < strlen(buf); i++) { 611 memcpy(buf_cpy, buf, count+1);
473 if (*(buf + i) == '\n') 612 tmp = buf_cpy;
474 continue; 613 while (tmp[0]) {
475 sub_str[0] = *(buf + i); 614 sub_str = strsep(&tmp, delimiter);
476 sub_str[1] = '\0'; 615 if (strlen(sub_str)) {
477 ret = kstrtol(sub_str, 0, &level); 616 ret = kstrtol(sub_str, 0, &level);
478 617
479 if (ret) { 618 if (ret) {
480 count = -EINVAL; 619 count = -EINVAL;
481 goto fail; 620 goto fail;
482 } 621 }
483 mask |= 1 << level; 622 mask |= 1 << level;
623 } else
624 break;
484 } 625 }
485
486 if (adev->powerplay.pp_funcs->force_clock_level) 626 if (adev->powerplay.pp_funcs->force_clock_level)
487 amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); 627 amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask);
488 628
@@ -512,21 +652,26 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev,
512 struct amdgpu_device *adev = ddev->dev_private; 652 struct amdgpu_device *adev = ddev->dev_private;
513 int ret; 653 int ret;
514 long level; 654 long level;
515 uint32_t i, mask = 0; 655 uint32_t mask = 0;
516 char sub_str[2]; 656 char *sub_str = NULL;
657 char *tmp;
658 char buf_cpy[count];
659 const char delimiter[3] = {' ', '\n', '\0'};
517 660
518 for (i = 0; i < strlen(buf); i++) { 661 memcpy(buf_cpy, buf, count+1);
519 if (*(buf + i) == '\n') 662 tmp = buf_cpy;
520 continue; 663 while (tmp[0]) {
521 sub_str[0] = *(buf + i); 664 sub_str = strsep(&tmp, delimiter);
522 sub_str[1] = '\0'; 665 if (strlen(sub_str)) {
523 ret = kstrtol(sub_str, 0, &level); 666 ret = kstrtol(sub_str, 0, &level);
524 667
525 if (ret) { 668 if (ret) {
526 count = -EINVAL; 669 count = -EINVAL;
527 goto fail; 670 goto fail;
528 } 671 }
529 mask |= 1 << level; 672 mask |= 1 << level;
673 } else
674 break;
530 } 675 }
531 if (adev->powerplay.pp_funcs->force_clock_level) 676 if (adev->powerplay.pp_funcs->force_clock_level)
532 amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); 677 amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask);
@@ -557,21 +702,27 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev,
557 struct amdgpu_device *adev = ddev->dev_private; 702 struct amdgpu_device *adev = ddev->dev_private;
558 int ret; 703 int ret;
559 long level; 704 long level;
560 uint32_t i, mask = 0; 705 uint32_t mask = 0;
561 char sub_str[2]; 706 char *sub_str = NULL;
707 char *tmp;
708 char buf_cpy[count];
709 const char delimiter[3] = {' ', '\n', '\0'};
562 710
563 for (i = 0; i < strlen(buf); i++) { 711 memcpy(buf_cpy, buf, count+1);
564 if (*(buf + i) == '\n') 712 tmp = buf_cpy;
565 continue;
566 sub_str[0] = *(buf + i);
567 sub_str[1] = '\0';
568 ret = kstrtol(sub_str, 0, &level);
569 713
570 if (ret) { 714 while (tmp[0]) {
571 count = -EINVAL; 715 sub_str = strsep(&tmp, delimiter);
572 goto fail; 716 if (strlen(sub_str)) {
573 } 717 ret = kstrtol(sub_str, 0, &level);
574 mask |= 1 << level; 718
719 if (ret) {
720 count = -EINVAL;
721 goto fail;
722 }
723 mask |= 1 << level;
724 } else
725 break;
575 } 726 }
576 if (adev->powerplay.pp_funcs->force_clock_level) 727 if (adev->powerplay.pp_funcs->force_clock_level)
577 amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); 728 amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask);
@@ -668,6 +819,26 @@ fail:
668 return count; 819 return count;
669} 820}
670 821
822/**
823 * DOC: pp_power_profile_mode
824 *
825 * The amdgpu driver provides a sysfs API for adjusting the heuristics
826 * related to switching between power levels in a power state. The file
827 * pp_power_profile_mode is used for this.
828 *
829 * Reading this file outputs a list of all of the predefined power profiles
830 * and the relevant heuristics settings for that profile.
831 *
832 * To select a profile or create a custom profile, first select manual using
833 * power_dpm_force_performance_level. Writing the number of a predefined
834 * profile to pp_power_profile_mode will enable those heuristics. To
835 * create a custom set of heuristics, write a string of numbers to the file
836 * starting with the number of the custom profile along with a setting
837 * for each heuristic parameter. Due to differences across asic families
838 * the heuristic parameters vary from family to family.
839 *
840 */
841
671static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev, 842static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,
672 struct device_attribute *attr, 843 struct device_attribute *attr,
673 char *buf) 844 char *buf)
@@ -1020,8 +1191,8 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,
1020{ 1191{
1021 struct amdgpu_device *adev = dev_get_drvdata(dev); 1192 struct amdgpu_device *adev = dev_get_drvdata(dev);
1022 struct drm_device *ddev = adev->ddev; 1193 struct drm_device *ddev = adev->ddev;
1023 struct pp_gpu_power query = {0}; 1194 u32 query = 0;
1024 int r, size = sizeof(query); 1195 int r, size = sizeof(u32);
1025 unsigned uw; 1196 unsigned uw;
1026 1197
1027 /* Can't get power when the card is off */ 1198 /* Can't get power when the card is off */
@@ -1041,7 +1212,7 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,
1041 return r; 1212 return r;
1042 1213
1043 /* convert to microwatts */ 1214 /* convert to microwatts */
1044 uw = (query.average_gpu_power >> 8) * 1000000; 1215 uw = (query >> 8) * 1000000 + (query & 0xff) * 1000;
1045 1216
1046 return snprintf(buf, PAGE_SIZE, "%u\n", uw); 1217 return snprintf(buf, PAGE_SIZE, "%u\n", uw);
1047} 1218}
@@ -1109,6 +1280,46 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev,
1109 return count; 1280 return count;
1110} 1281}
1111 1282
1283
1284/**
1285 * DOC: hwmon
1286 *
1287 * The amdgpu driver exposes the following sensor interfaces:
1288 * - GPU temperature (via the on-die sensor)
1289 * - GPU voltage
1290 * - Northbridge voltage (APUs only)
1291 * - GPU power
1292 * - GPU fan
1293 *
1294 * hwmon interfaces for GPU temperature:
1295 * - temp1_input: the on die GPU temperature in millidegrees Celsius
1296 * - temp1_crit: temperature critical max value in millidegrees Celsius
1297 * - temp1_crit_hyst: temperature hysteresis for critical limit in millidegrees Celsius
1298 *
1299 * hwmon interfaces for GPU voltage:
1300 * - in0_input: the voltage on the GPU in millivolts
1301 * - in1_input: the voltage on the Northbridge in millivolts
1302 *
1303 * hwmon interfaces for GPU power:
1304 * - power1_average: average power used by the GPU in microWatts
1305 * - power1_cap_min: minimum cap supported in microWatts
1306 * - power1_cap_max: maximum cap supported in microWatts
1307 * - power1_cap: selected power cap in microWatts
1308 *
1309 * hwmon interfaces for GPU fan:
1310 * - pwm1: pulse width modulation fan level (0-255)
1311 * - pwm1_enable: pulse width modulation fan control method
1312 * 0: no fan speed control
1313 * 1: manual fan speed control using pwm interface
1314 * 2: automatic fan speed control
1315 * - pwm1_min: pulse width modulation fan control minimum level (0)
1316 * - pwm1_max: pulse width modulation fan control maximum level (255)
1317 * - fan1_input: fan speed in RPM
1318 *
1319 * You can use hwmon tools like sensors to view this information on your system.
1320 *
1321 */
1322
1112static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, amdgpu_hwmon_show_temp, NULL, 0); 1323static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, amdgpu_hwmon_show_temp, NULL, 0);
1113static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 0); 1324static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 0);
1114static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 1); 1325static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, amdgpu_hwmon_show_temp_thresh, NULL, 1);
@@ -1153,19 +1364,14 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
1153 struct amdgpu_device *adev = dev_get_drvdata(dev); 1364 struct amdgpu_device *adev = dev_get_drvdata(dev);
1154 umode_t effective_mode = attr->mode; 1365 umode_t effective_mode = attr->mode;
1155 1366
1156 /* handle non-powerplay limitations */ 1367
1157 if (!adev->powerplay.pp_handle) { 1368 /* Skip fan attributes if fan is not present */
1158 /* Skip fan attributes if fan is not present */ 1369 if (adev->pm.no_fan && (attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
1159 if (adev->pm.no_fan && 1370 attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
1160 (attr == &sensor_dev_attr_pwm1.dev_attr.attr || 1371 attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
1161 attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr || 1372 attr == &sensor_dev_attr_pwm1_min.dev_attr.attr ||
1162 attr == &sensor_dev_attr_pwm1_max.dev_attr.attr || 1373 attr == &sensor_dev_attr_fan1_input.dev_attr.attr))
1163 attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) 1374 return 0;
1164 return 0;
1165 /* requires powerplay */
1166 if (attr == &sensor_dev_attr_fan1_input.dev_attr.attr)
1167 return 0;
1168 }
1169 1375
1170 /* Skip limit attributes if DPM is not enabled */ 1376 /* Skip limit attributes if DPM is not enabled */
1171 if (!adev->pm.dpm_enabled && 1377 if (!adev->pm.dpm_enabled &&
@@ -1658,9 +1864,6 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
1658 1864
1659void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) 1865void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
1660{ 1866{
1661 struct drm_device *ddev = adev->ddev;
1662 struct drm_crtc *crtc;
1663 struct amdgpu_crtc *amdgpu_crtc;
1664 int i = 0; 1867 int i = 0;
1665 1868
1666 if (!adev->pm.dpm_enabled) 1869 if (!adev->pm.dpm_enabled)
@@ -1676,21 +1879,25 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
1676 } 1879 }
1677 1880
1678 if (adev->powerplay.pp_funcs->dispatch_tasks) { 1881 if (adev->powerplay.pp_funcs->dispatch_tasks) {
1882 if (!amdgpu_device_has_dc_support(adev)) {
1883 mutex_lock(&adev->pm.mutex);
1884 amdgpu_dpm_get_active_displays(adev);
1885 adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtcs;
1886 adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev);
1887 adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev);
1888 /* we have issues with mclk switching with refresh rates over 120 hz on the non-DC code. */
1889 if (adev->pm.pm_display_cfg.vrefresh > 120)
1890 adev->pm.pm_display_cfg.min_vblank_time = 0;
1891 if (adev->powerplay.pp_funcs->display_configuration_change)
1892 adev->powerplay.pp_funcs->display_configuration_change(
1893 adev->powerplay.pp_handle,
1894 &adev->pm.pm_display_cfg);
1895 mutex_unlock(&adev->pm.mutex);
1896 }
1679 amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, NULL); 1897 amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, NULL);
1680 } else { 1898 } else {
1681 mutex_lock(&adev->pm.mutex); 1899 mutex_lock(&adev->pm.mutex);
1682 adev->pm.dpm.new_active_crtcs = 0; 1900 amdgpu_dpm_get_active_displays(adev);
1683 adev->pm.dpm.new_active_crtc_count = 0;
1684 if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
1685 list_for_each_entry(crtc,
1686 &ddev->mode_config.crtc_list, head) {
1687 amdgpu_crtc = to_amdgpu_crtc(crtc);
1688 if (amdgpu_crtc->enabled) {
1689 adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
1690 adev->pm.dpm.new_active_crtc_count++;
1691 }
1692 }
1693 }
1694 /* update battery/ac status */ 1901 /* update battery/ac status */
1695 if (power_supply_is_system_supplied() > 0) 1902 if (power_supply_is_system_supplied() > 0)
1696 adev->pm.dpm.ac_power = true; 1903 adev->pm.dpm.ac_power = true;
@@ -1711,7 +1918,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
1711static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *adev) 1918static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *adev)
1712{ 1919{
1713 uint32_t value; 1920 uint32_t value;
1714 struct pp_gpu_power query = {0}; 1921 uint32_t query = 0;
1715 int size; 1922 int size;
1716 1923
1717 /* sanity check PP is enabled */ 1924 /* sanity check PP is enabled */
@@ -1734,17 +1941,9 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
1734 seq_printf(m, "\t%u mV (VDDGFX)\n", value); 1941 seq_printf(m, "\t%u mV (VDDGFX)\n", value);
1735 if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, (void *)&value, &size)) 1942 if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, (void *)&value, &size))
1736 seq_printf(m, "\t%u mV (VDDNB)\n", value); 1943 seq_printf(m, "\t%u mV (VDDNB)\n", value);
1737 size = sizeof(query); 1944 size = sizeof(uint32_t);
1738 if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER, (void *)&query, &size)) { 1945 if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER, (void *)&query, &size))
1739 seq_printf(m, "\t%u.%u W (VDDC)\n", query.vddc_power >> 8, 1946 seq_printf(m, "\t%u.%u W (average GPU)\n", query >> 8, query & 0xff);
1740 query.vddc_power & 0xff);
1741 seq_printf(m, "\t%u.%u W (VDDCI)\n", query.vddci_power >> 8,
1742 query.vddci_power & 0xff);
1743 seq_printf(m, "\t%u.%u W (max GPU)\n", query.max_gpu_power >> 8,
1744 query.max_gpu_power & 0xff);
1745 seq_printf(m, "\t%u.%u W (average GPU)\n", query.average_gpu_power >> 8,
1746 query.average_gpu_power & 0xff);
1747 }
1748 size = sizeof(value); 1947 size = sizeof(value);
1749 seq_printf(m, "\n"); 1948 seq_printf(m, "\n");
1750 1949
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
index 4b584cb75bf4..4683626b065f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
@@ -102,12 +102,18 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
102 struct reservation_object *resv = attach->dmabuf->resv; 102 struct reservation_object *resv = attach->dmabuf->resv;
103 struct amdgpu_device *adev = dev->dev_private; 103 struct amdgpu_device *adev = dev->dev_private;
104 struct amdgpu_bo *bo; 104 struct amdgpu_bo *bo;
105 struct amdgpu_bo_param bp;
105 int ret; 106 int ret;
106 107
108 memset(&bp, 0, sizeof(bp));
109 bp.size = attach->dmabuf->size;
110 bp.byte_align = PAGE_SIZE;
111 bp.domain = AMDGPU_GEM_DOMAIN_CPU;
112 bp.flags = 0;
113 bp.type = ttm_bo_type_sg;
114 bp.resv = resv;
107 ww_mutex_lock(&resv->lock, NULL); 115 ww_mutex_lock(&resv->lock, NULL);
108 ret = amdgpu_bo_create(adev, attach->dmabuf->size, PAGE_SIZE, 116 ret = amdgpu_bo_create(adev, &bp, &bo);
109 AMDGPU_GEM_DOMAIN_CPU, 0, ttm_bo_type_sg,
110 resv, &bo);
111 if (ret) 117 if (ret)
112 goto error; 118 goto error;
113 119
@@ -209,7 +215,7 @@ static int amdgpu_gem_begin_cpu_access(struct dma_buf *dma_buf,
209 struct amdgpu_bo *bo = gem_to_amdgpu_bo(dma_buf->priv); 215 struct amdgpu_bo *bo = gem_to_amdgpu_bo(dma_buf->priv);
210 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 216 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
211 struct ttm_operation_ctx ctx = { true, false }; 217 struct ttm_operation_ctx ctx = { true, false };
212 u32 domain = amdgpu_display_framebuffer_domains(adev); 218 u32 domain = amdgpu_display_supported_domains(adev);
213 int ret; 219 int ret;
214 bool reads = (direction == DMA_BIDIRECTIONAL || 220 bool reads = (direction == DMA_BIDIRECTIONAL ||
215 direction == DMA_FROM_DEVICE); 221 direction == DMA_FROM_DEVICE);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index c7d43e064fc7..9f1a5bd39ae8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -52,6 +52,7 @@ static int psp_sw_init(void *handle)
52 switch (adev->asic_type) { 52 switch (adev->asic_type) {
53 case CHIP_VEGA10: 53 case CHIP_VEGA10:
54 case CHIP_VEGA12: 54 case CHIP_VEGA12:
55 case CHIP_VEGA20:
55 psp_v3_1_set_psp_funcs(psp); 56 psp_v3_1_set_psp_funcs(psp);
56 break; 57 break;
57 case CHIP_RAVEN: 58 case CHIP_RAVEN:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
index 262c1267249e..8af16e81c7d4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
@@ -66,6 +66,8 @@ static int amdgpu_identity_map(struct amdgpu_device *adev,
66 u32 ring, 66 u32 ring,
67 struct amdgpu_ring **out_ring) 67 struct amdgpu_ring **out_ring)
68{ 68{
69 u32 instance;
70
69 switch (mapper->hw_ip) { 71 switch (mapper->hw_ip) {
70 case AMDGPU_HW_IP_GFX: 72 case AMDGPU_HW_IP_GFX:
71 *out_ring = &adev->gfx.gfx_ring[ring]; 73 *out_ring = &adev->gfx.gfx_ring[ring];
@@ -77,13 +79,16 @@ static int amdgpu_identity_map(struct amdgpu_device *adev,
77 *out_ring = &adev->sdma.instance[ring].ring; 79 *out_ring = &adev->sdma.instance[ring].ring;
78 break; 80 break;
79 case AMDGPU_HW_IP_UVD: 81 case AMDGPU_HW_IP_UVD:
80 *out_ring = &adev->uvd.ring; 82 instance = ring;
83 *out_ring = &adev->uvd.inst[instance].ring;
81 break; 84 break;
82 case AMDGPU_HW_IP_VCE: 85 case AMDGPU_HW_IP_VCE:
83 *out_ring = &adev->vce.ring[ring]; 86 *out_ring = &adev->vce.ring[ring];
84 break; 87 break;
85 case AMDGPU_HW_IP_UVD_ENC: 88 case AMDGPU_HW_IP_UVD_ENC:
86 *out_ring = &adev->uvd.ring_enc[ring]; 89 instance = ring / adev->uvd.num_enc_rings;
90 *out_ring =
91 &adev->uvd.inst[instance].ring_enc[ring%adev->uvd.num_enc_rings];
87 break; 92 break;
88 case AMDGPU_HW_IP_VCN_DEC: 93 case AMDGPU_HW_IP_VCN_DEC:
89 *out_ring = &adev->vcn.ring_dec; 94 *out_ring = &adev->vcn.ring_dec;
@@ -240,13 +245,14 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev,
240 ip_num_rings = adev->sdma.num_instances; 245 ip_num_rings = adev->sdma.num_instances;
241 break; 246 break;
242 case AMDGPU_HW_IP_UVD: 247 case AMDGPU_HW_IP_UVD:
243 ip_num_rings = 1; 248 ip_num_rings = adev->uvd.num_uvd_inst;
244 break; 249 break;
245 case AMDGPU_HW_IP_VCE: 250 case AMDGPU_HW_IP_VCE:
246 ip_num_rings = adev->vce.num_rings; 251 ip_num_rings = adev->vce.num_rings;
247 break; 252 break;
248 case AMDGPU_HW_IP_UVD_ENC: 253 case AMDGPU_HW_IP_UVD_ENC:
249 ip_num_rings = adev->uvd.num_enc_rings; 254 ip_num_rings =
255 adev->uvd.num_enc_rings * adev->uvd.num_uvd_inst;
250 break; 256 break;
251 case AMDGPU_HW_IP_VCN_DEC: 257 case AMDGPU_HW_IP_VCN_DEC:
252 ip_num_rings = 1; 258 ip_num_rings = 1;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index d5f526f38e50..c6850b629d0e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -362,6 +362,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
362 362
363 dma_fence_put(ring->vmid_wait); 363 dma_fence_put(ring->vmid_wait);
364 ring->vmid_wait = NULL; 364 ring->vmid_wait = NULL;
365 ring->me = 0;
365 366
366 ring->adev->rings[ring->idx] = NULL; 367 ring->adev->rings[ring->idx] = NULL;
367} 368}
@@ -459,6 +460,26 @@ void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring)
459 spin_unlock(&adev->ring_lru_list_lock); 460 spin_unlock(&adev->ring_lru_list_lock);
460} 461}
461 462
463/**
464 * amdgpu_ring_emit_reg_write_reg_wait_helper - ring helper
465 *
466 * @adev: amdgpu_device pointer
467 * @reg0: register to write
468 * @reg1: register to wait on
469 * @ref: reference value to write/wait on
470 * @mask: mask to wait on
471 *
472 * Helper for rings that don't support write and wait in a
473 * single oneshot packet.
474 */
475void amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring,
476 uint32_t reg0, uint32_t reg1,
477 uint32_t ref, uint32_t mask)
478{
479 amdgpu_ring_emit_wreg(ring, reg0, ref);
480 amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);
481}
482
462/* 483/*
463 * Debugfs info 484 * Debugfs info
464 */ 485 */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 1a5911882657..1513124c5659 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -29,7 +29,7 @@
29#include <drm/drm_print.h> 29#include <drm/drm_print.h>
30 30
31/* max number of rings */ 31/* max number of rings */
32#define AMDGPU_MAX_RINGS 18 32#define AMDGPU_MAX_RINGS 21
33#define AMDGPU_MAX_GFX_RINGS 1 33#define AMDGPU_MAX_GFX_RINGS 1
34#define AMDGPU_MAX_COMPUTE_RINGS 8 34#define AMDGPU_MAX_COMPUTE_RINGS 8
35#define AMDGPU_MAX_VCE_RINGS 3 35#define AMDGPU_MAX_VCE_RINGS 3
@@ -42,6 +42,7 @@
42 42
43#define AMDGPU_FENCE_FLAG_64BIT (1 << 0) 43#define AMDGPU_FENCE_FLAG_64BIT (1 << 0)
44#define AMDGPU_FENCE_FLAG_INT (1 << 1) 44#define AMDGPU_FENCE_FLAG_INT (1 << 1)
45#define AMDGPU_FENCE_FLAG_TC_WB_ONLY (1 << 2)
45 46
46enum amdgpu_ring_type { 47enum amdgpu_ring_type {
47 AMDGPU_RING_TYPE_GFX, 48 AMDGPU_RING_TYPE_GFX,
@@ -90,7 +91,8 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
90 unsigned irq_type); 91 unsigned irq_type);
91void amdgpu_fence_driver_suspend(struct amdgpu_device *adev); 92void amdgpu_fence_driver_suspend(struct amdgpu_device *adev);
92void amdgpu_fence_driver_resume(struct amdgpu_device *adev); 93void amdgpu_fence_driver_resume(struct amdgpu_device *adev);
93int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence); 94int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence,
95 unsigned flags);
94int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s); 96int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s);
95void amdgpu_fence_process(struct amdgpu_ring *ring); 97void amdgpu_fence_process(struct amdgpu_ring *ring);
96int amdgpu_fence_wait_empty(struct amdgpu_ring *ring); 98int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
@@ -154,6 +156,9 @@ struct amdgpu_ring_funcs {
154 void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val); 156 void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val);
155 void (*emit_reg_wait)(struct amdgpu_ring *ring, uint32_t reg, 157 void (*emit_reg_wait)(struct amdgpu_ring *ring, uint32_t reg,
156 uint32_t val, uint32_t mask); 158 uint32_t val, uint32_t mask);
159 void (*emit_reg_write_reg_wait)(struct amdgpu_ring *ring,
160 uint32_t reg0, uint32_t reg1,
161 uint32_t ref, uint32_t mask);
157 void (*emit_tmz)(struct amdgpu_ring *ring, bool start); 162 void (*emit_tmz)(struct amdgpu_ring *ring, bool start);
158 /* priority functions */ 163 /* priority functions */
159 void (*set_priority) (struct amdgpu_ring *ring, 164 void (*set_priority) (struct amdgpu_ring *ring,
@@ -228,6 +233,10 @@ int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type,
228 int *blacklist, int num_blacklist, 233 int *blacklist, int num_blacklist,
229 bool lru_pipe_order, struct amdgpu_ring **ring); 234 bool lru_pipe_order, struct amdgpu_ring **ring);
230void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring); 235void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring);
236void amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring,
237 uint32_t reg0, uint32_t val0,
238 uint32_t reg1, uint32_t val1);
239
231static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) 240static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
232{ 241{
233 int i = 0; 242 int i = 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
index 2dbe87591f81..d167e8ab76d3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
@@ -33,6 +33,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
33 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; 33 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
34 struct amdgpu_bo *vram_obj = NULL; 34 struct amdgpu_bo *vram_obj = NULL;
35 struct amdgpu_bo **gtt_obj = NULL; 35 struct amdgpu_bo **gtt_obj = NULL;
36 struct amdgpu_bo_param bp;
36 uint64_t gart_addr, vram_addr; 37 uint64_t gart_addr, vram_addr;
37 unsigned n, size; 38 unsigned n, size;
38 int i, r; 39 int i, r;
@@ -58,9 +59,15 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
58 r = 1; 59 r = 1;
59 goto out_cleanup; 60 goto out_cleanup;
60 } 61 }
61 62 memset(&bp, 0, sizeof(bp));
62 r = amdgpu_bo_create(adev, size, PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, 0, 63 bp.size = size;
63 ttm_bo_type_kernel, NULL, &vram_obj); 64 bp.byte_align = PAGE_SIZE;
65 bp.domain = AMDGPU_GEM_DOMAIN_VRAM;
66 bp.flags = 0;
67 bp.type = ttm_bo_type_kernel;
68 bp.resv = NULL;
69
70 r = amdgpu_bo_create(adev, &bp, &vram_obj);
64 if (r) { 71 if (r) {
65 DRM_ERROR("Failed to create VRAM object\n"); 72 DRM_ERROR("Failed to create VRAM object\n");
66 goto out_cleanup; 73 goto out_cleanup;
@@ -79,9 +86,8 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
79 void **vram_start, **vram_end; 86 void **vram_start, **vram_end;
80 struct dma_fence *fence = NULL; 87 struct dma_fence *fence = NULL;
81 88
82 r = amdgpu_bo_create(adev, size, PAGE_SIZE, 89 bp.domain = AMDGPU_GEM_DOMAIN_GTT;
83 AMDGPU_GEM_DOMAIN_GTT, 0, 90 r = amdgpu_bo_create(adev, &bp, gtt_obj + i);
84 ttm_bo_type_kernel, NULL, gtt_obj + i);
85 if (r) { 91 if (r) {
86 DRM_ERROR("Failed to create GTT object %d\n", i); 92 DRM_ERROR("Failed to create GTT object %d\n", i);
87 goto out_lclean; 93 goto out_lclean;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
index 532263ab6e16..e96e26d3f3b0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
@@ -275,7 +275,7 @@ TRACE_EVENT(amdgpu_vm_bo_unmap,
275 ), 275 ),
276 276
277 TP_fast_assign( 277 TP_fast_assign(
278 __entry->bo = bo_va->base.bo; 278 __entry->bo = bo_va ? bo_va->base.bo : NULL;
279 __entry->start = mapping->start; 279 __entry->start = mapping->start;
280 __entry->last = mapping->last; 280 __entry->last = mapping->last;
281 __entry->offset = mapping->offset; 281 __entry->offset = mapping->offset;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 205da3ff9cd0..e93a0a237dc3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -63,16 +63,44 @@ static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev);
63/* 63/*
64 * Global memory. 64 * Global memory.
65 */ 65 */
66
67/**
68 * amdgpu_ttm_mem_global_init - Initialize and acquire reference to
69 * memory object
70 *
71 * @ref: Object for initialization.
72 *
73 * This is called by drm_global_item_ref() when an object is being
74 * initialized.
75 */
66static int amdgpu_ttm_mem_global_init(struct drm_global_reference *ref) 76static int amdgpu_ttm_mem_global_init(struct drm_global_reference *ref)
67{ 77{
68 return ttm_mem_global_init(ref->object); 78 return ttm_mem_global_init(ref->object);
69} 79}
70 80
81/**
82 * amdgpu_ttm_mem_global_release - Drop reference to a memory object
83 *
84 * @ref: Object being removed
85 *
86 * This is called by drm_global_item_unref() when an object is being
87 * released.
88 */
71static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref) 89static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref)
72{ 90{
73 ttm_mem_global_release(ref->object); 91 ttm_mem_global_release(ref->object);
74} 92}
75 93
94/**
95 * amdgpu_ttm_global_init - Initialize global TTM memory reference
96 * structures.
97 *
98 * @adev: AMDGPU device for which the global structures need to be
99 * registered.
100 *
101 * This is called as part of the AMDGPU ttm init from amdgpu_ttm_init()
102 * during bring up.
103 */
76static int amdgpu_ttm_global_init(struct amdgpu_device *adev) 104static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
77{ 105{
78 struct drm_global_reference *global_ref; 106 struct drm_global_reference *global_ref;
@@ -80,7 +108,9 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
80 struct drm_sched_rq *rq; 108 struct drm_sched_rq *rq;
81 int r; 109 int r;
82 110
111 /* ensure reference is false in case init fails */
83 adev->mman.mem_global_referenced = false; 112 adev->mman.mem_global_referenced = false;
113
84 global_ref = &adev->mman.mem_global_ref; 114 global_ref = &adev->mman.mem_global_ref;
85 global_ref->global_type = DRM_GLOBAL_TTM_MEM; 115 global_ref->global_type = DRM_GLOBAL_TTM_MEM;
86 global_ref->size = sizeof(struct ttm_mem_global); 116 global_ref->size = sizeof(struct ttm_mem_global);
@@ -111,7 +141,7 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
111 ring = adev->mman.buffer_funcs_ring; 141 ring = adev->mman.buffer_funcs_ring;
112 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_KERNEL]; 142 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_KERNEL];
113 r = drm_sched_entity_init(&ring->sched, &adev->mman.entity, 143 r = drm_sched_entity_init(&ring->sched, &adev->mman.entity,
114 rq, amdgpu_sched_jobs, NULL); 144 rq, NULL);
115 if (r) { 145 if (r) {
116 DRM_ERROR("Failed setting up TTM BO move run queue.\n"); 146 DRM_ERROR("Failed setting up TTM BO move run queue.\n");
117 goto error_entity; 147 goto error_entity;
@@ -146,6 +176,18 @@ static int amdgpu_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
146 return 0; 176 return 0;
147} 177}
148 178
179/**
180 * amdgpu_init_mem_type - Initialize a memory manager for a specific
181 * type of memory request.
182 *
183 * @bdev: The TTM BO device object (contains a reference to
184 * amdgpu_device)
185 * @type: The type of memory requested
186 * @man:
187 *
188 * This is called by ttm_bo_init_mm() when a buffer object is being
189 * initialized.
190 */
149static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, 191static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
150 struct ttm_mem_type_manager *man) 192 struct ttm_mem_type_manager *man)
151{ 193{
@@ -161,6 +203,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
161 man->default_caching = TTM_PL_FLAG_CACHED; 203 man->default_caching = TTM_PL_FLAG_CACHED;
162 break; 204 break;
163 case TTM_PL_TT: 205 case TTM_PL_TT:
206 /* GTT memory */
164 man->func = &amdgpu_gtt_mgr_func; 207 man->func = &amdgpu_gtt_mgr_func;
165 man->gpu_offset = adev->gmc.gart_start; 208 man->gpu_offset = adev->gmc.gart_start;
166 man->available_caching = TTM_PL_MASK_CACHING; 209 man->available_caching = TTM_PL_MASK_CACHING;
@@ -193,6 +236,14 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
193 return 0; 236 return 0;
194} 237}
195 238
239/**
240 * amdgpu_evict_flags - Compute placement flags
241 *
242 * @bo: The buffer object to evict
243 * @placement: Possible destination(s) for evicted BO
244 *
245 * Fill in placement data when ttm_bo_evict() is called
246 */
196static void amdgpu_evict_flags(struct ttm_buffer_object *bo, 247static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
197 struct ttm_placement *placement) 248 struct ttm_placement *placement)
198{ 249{
@@ -204,12 +255,14 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
204 .flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM 255 .flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM
205 }; 256 };
206 257
258 /* Don't handle scatter gather BOs */
207 if (bo->type == ttm_bo_type_sg) { 259 if (bo->type == ttm_bo_type_sg) {
208 placement->num_placement = 0; 260 placement->num_placement = 0;
209 placement->num_busy_placement = 0; 261 placement->num_busy_placement = 0;
210 return; 262 return;
211 } 263 }
212 264
265 /* Object isn't an AMDGPU object so ignore */
213 if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) { 266 if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) {
214 placement->placement = &placements; 267 placement->placement = &placements;
215 placement->busy_placement = &placements; 268 placement->busy_placement = &placements;
@@ -217,26 +270,16 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
217 placement->num_busy_placement = 1; 270 placement->num_busy_placement = 1;
218 return; 271 return;
219 } 272 }
273
220 abo = ttm_to_amdgpu_bo(bo); 274 abo = ttm_to_amdgpu_bo(bo);
221 switch (bo->mem.mem_type) { 275 switch (bo->mem.mem_type) {
222 case TTM_PL_VRAM: 276 case TTM_PL_VRAM:
223 if (!adev->mman.buffer_funcs_enabled) { 277 if (!adev->mman.buffer_funcs_enabled) {
278 /* Move to system memory */
224 amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU); 279 amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU);
225 } else if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size && 280 } else if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size &&
226 !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) { 281 !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) &&
227 unsigned fpfn = adev->gmc.visible_vram_size >> PAGE_SHIFT; 282 amdgpu_bo_in_cpu_visible_vram(abo)) {
228 struct drm_mm_node *node = bo->mem.mm_node;
229 unsigned long pages_left;
230
231 for (pages_left = bo->mem.num_pages;
232 pages_left;
233 pages_left -= node->size, node++) {
234 if (node->start < fpfn)
235 break;
236 }
237
238 if (!pages_left)
239 goto gtt;
240 283
241 /* Try evicting to the CPU inaccessible part of VRAM 284 /* Try evicting to the CPU inaccessible part of VRAM
242 * first, but only set GTT as busy placement, so this 285 * first, but only set GTT as busy placement, so this
@@ -245,12 +288,12 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
245 */ 288 */
246 amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM | 289 amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM |
247 AMDGPU_GEM_DOMAIN_GTT); 290 AMDGPU_GEM_DOMAIN_GTT);
248 abo->placements[0].fpfn = fpfn; 291 abo->placements[0].fpfn = adev->gmc.visible_vram_size >> PAGE_SHIFT;
249 abo->placements[0].lpfn = 0; 292 abo->placements[0].lpfn = 0;
250 abo->placement.busy_placement = &abo->placements[1]; 293 abo->placement.busy_placement = &abo->placements[1];
251 abo->placement.num_busy_placement = 1; 294 abo->placement.num_busy_placement = 1;
252 } else { 295 } else {
253gtt: 296 /* Move to GTT memory */
254 amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT); 297 amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT);
255 } 298 }
256 break; 299 break;
@@ -261,6 +304,15 @@ gtt:
261 *placement = abo->placement; 304 *placement = abo->placement;
262} 305}
263 306
307/**
308 * amdgpu_verify_access - Verify access for a mmap call
309 *
310 * @bo: The buffer object to map
311 * @filp: The file pointer from the process performing the mmap
312 *
313 * This is called by ttm_bo_mmap() to verify whether a process
314 * has the right to mmap a BO to their process space.
315 */
264static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) 316static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp)
265{ 317{
266 struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); 318 struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);
@@ -278,6 +330,15 @@ static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp)
278 filp->private_data); 330 filp->private_data);
279} 331}
280 332
333/**
334 * amdgpu_move_null - Register memory for a buffer object
335 *
336 * @bo: The bo to assign the memory to
337 * @new_mem: The memory to be assigned.
338 *
339 * Assign the memory from new_mem to the memory of the buffer object
340 * bo.
341 */
281static void amdgpu_move_null(struct ttm_buffer_object *bo, 342static void amdgpu_move_null(struct ttm_buffer_object *bo,
282 struct ttm_mem_reg *new_mem) 343 struct ttm_mem_reg *new_mem)
283{ 344{
@@ -288,6 +349,10 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo,
288 new_mem->mm_node = NULL; 349 new_mem->mm_node = NULL;
289} 350}
290 351
352/**
353 * amdgpu_mm_node_addr - Compute the GPU relative offset of a GTT
354 * buffer.
355 */
291static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, 356static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
292 struct drm_mm_node *mm_node, 357 struct drm_mm_node *mm_node,
293 struct ttm_mem_reg *mem) 358 struct ttm_mem_reg *mem)
@@ -302,9 +367,10 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
302} 367}
303 368
304/** 369/**
305 * amdgpu_find_mm_node - Helper function finds the drm_mm_node 370 * amdgpu_find_mm_node - Helper function finds the drm_mm_node
306 * corresponding to @offset. It also modifies the offset to be 371 * corresponding to @offset. It also modifies
307 * within the drm_mm_node returned 372 * the offset to be within the drm_mm_node
373 * returned
308 */ 374 */
309static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem, 375static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem,
310 unsigned long *offset) 376 unsigned long *offset)
@@ -443,7 +509,12 @@ error:
443 return r; 509 return r;
444} 510}
445 511
446 512/**
513 * amdgpu_move_blit - Copy an entire buffer to another buffer
514 *
515 * This is a helper called by amdgpu_bo_move() and
516 * amdgpu_move_vram_ram() to help move buffers to and from VRAM.
517 */
447static int amdgpu_move_blit(struct ttm_buffer_object *bo, 518static int amdgpu_move_blit(struct ttm_buffer_object *bo,
448 bool evict, bool no_wait_gpu, 519 bool evict, bool no_wait_gpu,
449 struct ttm_mem_reg *new_mem, 520 struct ttm_mem_reg *new_mem,
@@ -478,6 +549,11 @@ error:
478 return r; 549 return r;
479} 550}
480 551
552/**
553 * amdgpu_move_vram_ram - Copy VRAM buffer to RAM buffer
554 *
555 * Called by amdgpu_bo_move().
556 */
481static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict, 557static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,
482 struct ttm_operation_ctx *ctx, 558 struct ttm_operation_ctx *ctx,
483 struct ttm_mem_reg *new_mem) 559 struct ttm_mem_reg *new_mem)
@@ -490,6 +566,8 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,
490 int r; 566 int r;
491 567
492 adev = amdgpu_ttm_adev(bo->bdev); 568 adev = amdgpu_ttm_adev(bo->bdev);
569
570 /* create space/pages for new_mem in GTT space */
493 tmp_mem = *new_mem; 571 tmp_mem = *new_mem;
494 tmp_mem.mm_node = NULL; 572 tmp_mem.mm_node = NULL;
495 placement.num_placement = 1; 573 placement.num_placement = 1;
@@ -504,25 +582,36 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,
504 return r; 582 return r;
505 } 583 }
506 584
585 /* set caching flags */
507 r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement); 586 r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement);
508 if (unlikely(r)) { 587 if (unlikely(r)) {
509 goto out_cleanup; 588 goto out_cleanup;
510 } 589 }
511 590
591 /* Bind the memory to the GTT space */
512 r = ttm_tt_bind(bo->ttm, &tmp_mem, ctx); 592 r = ttm_tt_bind(bo->ttm, &tmp_mem, ctx);
513 if (unlikely(r)) { 593 if (unlikely(r)) {
514 goto out_cleanup; 594 goto out_cleanup;
515 } 595 }
596
597 /* blit VRAM to GTT */
516 r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, &tmp_mem, old_mem); 598 r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, &tmp_mem, old_mem);
517 if (unlikely(r)) { 599 if (unlikely(r)) {
518 goto out_cleanup; 600 goto out_cleanup;
519 } 601 }
602
603 /* move BO (in tmp_mem) to new_mem */
520 r = ttm_bo_move_ttm(bo, ctx, new_mem); 604 r = ttm_bo_move_ttm(bo, ctx, new_mem);
521out_cleanup: 605out_cleanup:
522 ttm_bo_mem_put(bo, &tmp_mem); 606 ttm_bo_mem_put(bo, &tmp_mem);
523 return r; 607 return r;
524} 608}
525 609
610/**
611 * amdgpu_move_ram_vram - Copy buffer from RAM to VRAM
612 *
613 * Called by amdgpu_bo_move().
614 */
526static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict, 615static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict,
527 struct ttm_operation_ctx *ctx, 616 struct ttm_operation_ctx *ctx,
528 struct ttm_mem_reg *new_mem) 617 struct ttm_mem_reg *new_mem)
@@ -535,6 +624,8 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict,
535 int r; 624 int r;
536 625
537 adev = amdgpu_ttm_adev(bo->bdev); 626 adev = amdgpu_ttm_adev(bo->bdev);
627
628 /* make space in GTT for old_mem buffer */
538 tmp_mem = *new_mem; 629 tmp_mem = *new_mem;
539 tmp_mem.mm_node = NULL; 630 tmp_mem.mm_node = NULL;
540 placement.num_placement = 1; 631 placement.num_placement = 1;
@@ -548,10 +639,14 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict,
548 if (unlikely(r)) { 639 if (unlikely(r)) {
549 return r; 640 return r;
550 } 641 }
642
643 /* move/bind old memory to GTT space */
551 r = ttm_bo_move_ttm(bo, ctx, &tmp_mem); 644 r = ttm_bo_move_ttm(bo, ctx, &tmp_mem);
552 if (unlikely(r)) { 645 if (unlikely(r)) {
553 goto out_cleanup; 646 goto out_cleanup;
554 } 647 }
648
649 /* copy to VRAM */
555 r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, new_mem, old_mem); 650 r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, new_mem, old_mem);
556 if (unlikely(r)) { 651 if (unlikely(r)) {
557 goto out_cleanup; 652 goto out_cleanup;
@@ -561,6 +656,11 @@ out_cleanup:
561 return r; 656 return r;
562} 657}
563 658
659/**
660 * amdgpu_bo_move - Move a buffer object to a new memory location
661 *
662 * Called by ttm_bo_handle_move_mem()
663 */
564static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict, 664static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
565 struct ttm_operation_ctx *ctx, 665 struct ttm_operation_ctx *ctx,
566 struct ttm_mem_reg *new_mem) 666 struct ttm_mem_reg *new_mem)
@@ -626,6 +726,11 @@ memcpy:
626 return 0; 726 return 0;
627} 727}
628 728
729/**
730 * amdgpu_ttm_io_mem_reserve - Reserve a block of memory during a fault
731 *
732 * Called by ttm_mem_io_reserve() ultimately via ttm_bo_vm_fault()
733 */
629static int amdgpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) 734static int amdgpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
630{ 735{
631 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; 736 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
@@ -695,7 +800,7 @@ struct amdgpu_ttm_tt {
695 struct ttm_dma_tt ttm; 800 struct ttm_dma_tt ttm;
696 u64 offset; 801 u64 offset;
697 uint64_t userptr; 802 uint64_t userptr;
698 struct mm_struct *usermm; 803 struct task_struct *usertask;
699 uint32_t userflags; 804 uint32_t userflags;
700 spinlock_t guptasklock; 805 spinlock_t guptasklock;
701 struct list_head guptasks; 806 struct list_head guptasks;
@@ -703,17 +808,29 @@ struct amdgpu_ttm_tt {
703 uint32_t last_set_pages; 808 uint32_t last_set_pages;
704}; 809};
705 810
811/**
812 * amdgpu_ttm_tt_get_user_pages - Pin pages of memory pointed to
813 * by a USERPTR pointer to memory
814 *
815 * Called by amdgpu_gem_userptr_ioctl() and amdgpu_cs_parser_bos().
816 * This provides a wrapper around the get_user_pages() call to provide
817 * device accessible pages that back user memory.
818 */
706int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages) 819int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
707{ 820{
708 struct amdgpu_ttm_tt *gtt = (void *)ttm; 821 struct amdgpu_ttm_tt *gtt = (void *)ttm;
822 struct mm_struct *mm = gtt->usertask->mm;
709 unsigned int flags = 0; 823 unsigned int flags = 0;
710 unsigned pinned = 0; 824 unsigned pinned = 0;
711 int r; 825 int r;
712 826
827 if (!mm) /* Happens during process shutdown */
828 return -ESRCH;
829
713 if (!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY)) 830 if (!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY))
714 flags |= FOLL_WRITE; 831 flags |= FOLL_WRITE;
715 832
716 down_read(&current->mm->mmap_sem); 833 down_read(&mm->mmap_sem);
717 834
718 if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) { 835 if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) {
719 /* check that we only use anonymous memory 836 /* check that we only use anonymous memory
@@ -721,13 +838,14 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
721 unsigned long end = gtt->userptr + ttm->num_pages * PAGE_SIZE; 838 unsigned long end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
722 struct vm_area_struct *vma; 839 struct vm_area_struct *vma;
723 840
724 vma = find_vma(gtt->usermm, gtt->userptr); 841 vma = find_vma(mm, gtt->userptr);
725 if (!vma || vma->vm_file || vma->vm_end < end) { 842 if (!vma || vma->vm_file || vma->vm_end < end) {
726 up_read(&current->mm->mmap_sem); 843 up_read(&mm->mmap_sem);
727 return -EPERM; 844 return -EPERM;
728 } 845 }
729 } 846 }
730 847
848 /* loop enough times using contiguous pages of memory */
731 do { 849 do {
732 unsigned num_pages = ttm->num_pages - pinned; 850 unsigned num_pages = ttm->num_pages - pinned;
733 uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE; 851 uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE;
@@ -739,7 +857,12 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
739 list_add(&guptask.list, &gtt->guptasks); 857 list_add(&guptask.list, &gtt->guptasks);
740 spin_unlock(&gtt->guptasklock); 858 spin_unlock(&gtt->guptasklock);
741 859
742 r = get_user_pages(userptr, num_pages, flags, p, NULL); 860 if (mm == current->mm)
861 r = get_user_pages(userptr, num_pages, flags, p, NULL);
862 else
863 r = get_user_pages_remote(gtt->usertask,
864 mm, userptr, num_pages,
865 flags, p, NULL, NULL);
743 866
744 spin_lock(&gtt->guptasklock); 867 spin_lock(&gtt->guptasklock);
745 list_del(&guptask.list); 868 list_del(&guptask.list);
@@ -752,15 +875,23 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
752 875
753 } while (pinned < ttm->num_pages); 876 } while (pinned < ttm->num_pages);
754 877
755 up_read(&current->mm->mmap_sem); 878 up_read(&mm->mmap_sem);
756 return 0; 879 return 0;
757 880
758release_pages: 881release_pages:
759 release_pages(pages, pinned); 882 release_pages(pages, pinned);
760 up_read(&current->mm->mmap_sem); 883 up_read(&mm->mmap_sem);
761 return r; 884 return r;
762} 885}
763 886
887/**
888 * amdgpu_ttm_tt_set_user_pages - Copy pages in, putting old pages
889 * as necessary.
890 *
891 * Called by amdgpu_cs_list_validate(). This creates the page list
892 * that backs user memory and will ultimately be mapped into the device
893 * address space.
894 */
764void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages) 895void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages)
765{ 896{
766 struct amdgpu_ttm_tt *gtt = (void *)ttm; 897 struct amdgpu_ttm_tt *gtt = (void *)ttm;
@@ -775,6 +906,11 @@ void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages)
775 } 906 }
776} 907}
777 908
909/**
910 * amdgpu_ttm_tt_mark_user_page - Mark pages as dirty
911 *
912 * Called while unpinning userptr pages
913 */
778void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm) 914void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm)
779{ 915{
780 struct amdgpu_ttm_tt *gtt = (void *)ttm; 916 struct amdgpu_ttm_tt *gtt = (void *)ttm;
@@ -793,7 +929,12 @@ void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm)
793 } 929 }
794} 930}
795 931
796/* prepare the sg table with the user pages */ 932/**
933 * amdgpu_ttm_tt_pin_userptr - prepare the sg table with the
934 * user pages
935 *
936 * Called by amdgpu_ttm_backend_bind()
937 **/
797static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) 938static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
798{ 939{
799 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); 940 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
@@ -805,17 +946,20 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
805 enum dma_data_direction direction = write ? 946 enum dma_data_direction direction = write ?
806 DMA_BIDIRECTIONAL : DMA_TO_DEVICE; 947 DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
807 948
949 /* Allocate an SG array and squash pages into it */
808 r = sg_alloc_table_from_pages(ttm->sg, ttm->pages, ttm->num_pages, 0, 950 r = sg_alloc_table_from_pages(ttm->sg, ttm->pages, ttm->num_pages, 0,
809 ttm->num_pages << PAGE_SHIFT, 951 ttm->num_pages << PAGE_SHIFT,
810 GFP_KERNEL); 952 GFP_KERNEL);
811 if (r) 953 if (r)
812 goto release_sg; 954 goto release_sg;
813 955
956 /* Map SG to device */
814 r = -ENOMEM; 957 r = -ENOMEM;
815 nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); 958 nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
816 if (nents != ttm->sg->nents) 959 if (nents != ttm->sg->nents)
817 goto release_sg; 960 goto release_sg;
818 961
962 /* convert SG to linear array of pages and dma addresses */
819 drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, 963 drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
820 gtt->ttm.dma_address, ttm->num_pages); 964 gtt->ttm.dma_address, ttm->num_pages);
821 965
@@ -826,6 +970,9 @@ release_sg:
826 return r; 970 return r;
827} 971}
828 972
973/**
974 * amdgpu_ttm_tt_unpin_userptr - Unpin and unmap userptr pages
975 */
829static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm) 976static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
830{ 977{
831 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); 978 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
@@ -839,14 +986,60 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
839 if (!ttm->sg->sgl) 986 if (!ttm->sg->sgl)
840 return; 987 return;
841 988
842 /* free the sg table and pages again */ 989 /* unmap the pages mapped to the device */
843 dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); 990 dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
844 991
992 /* mark the pages as dirty */
845 amdgpu_ttm_tt_mark_user_pages(ttm); 993 amdgpu_ttm_tt_mark_user_pages(ttm);
846 994
847 sg_free_table(ttm->sg); 995 sg_free_table(ttm->sg);
848} 996}
849 997
998int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
999 struct ttm_buffer_object *tbo,
1000 uint64_t flags)
1001{
1002 struct amdgpu_bo *abo = ttm_to_amdgpu_bo(tbo);
1003 struct ttm_tt *ttm = tbo->ttm;
1004 struct amdgpu_ttm_tt *gtt = (void *)ttm;
1005 int r;
1006
1007 if (abo->flags & AMDGPU_GEM_CREATE_MQD_GFX9) {
1008 uint64_t page_idx = 1;
1009
1010 r = amdgpu_gart_bind(adev, gtt->offset, page_idx,
1011 ttm->pages, gtt->ttm.dma_address, flags);
1012 if (r)
1013 goto gart_bind_fail;
1014
1015 /* Patch mtype of the second part BO */
1016 flags &= ~AMDGPU_PTE_MTYPE_MASK;
1017 flags |= AMDGPU_PTE_MTYPE(AMDGPU_MTYPE_NC);
1018
1019 r = amdgpu_gart_bind(adev,
1020 gtt->offset + (page_idx << PAGE_SHIFT),
1021 ttm->num_pages - page_idx,
1022 &ttm->pages[page_idx],
1023 &(gtt->ttm.dma_address[page_idx]), flags);
1024 } else {
1025 r = amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
1026 ttm->pages, gtt->ttm.dma_address, flags);
1027 }
1028
1029gart_bind_fail:
1030 if (r)
1031 DRM_ERROR("failed to bind %lu pages at 0x%08llX\n",
1032 ttm->num_pages, gtt->offset);
1033
1034 return r;
1035}
1036
1037/**
1038 * amdgpu_ttm_backend_bind - Bind GTT memory
1039 *
1040 * Called by ttm_tt_bind() on behalf of ttm_bo_handle_move_mem().
1041 * This handles binding GTT memory to the device address space.
1042 */
850static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, 1043static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
851 struct ttm_mem_reg *bo_mem) 1044 struct ttm_mem_reg *bo_mem)
852{ 1045{
@@ -877,7 +1070,10 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
877 return 0; 1070 return 0;
878 } 1071 }
879 1072
1073 /* compute PTE flags relevant to this BO memory */
880 flags = amdgpu_ttm_tt_pte_flags(adev, ttm, bo_mem); 1074 flags = amdgpu_ttm_tt_pte_flags(adev, ttm, bo_mem);
1075
1076 /* bind pages into GART page tables */
881 gtt->offset = (u64)bo_mem->start << PAGE_SHIFT; 1077 gtt->offset = (u64)bo_mem->start << PAGE_SHIFT;
882 r = amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages, 1078 r = amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
883 ttm->pages, gtt->ttm.dma_address, flags); 1079 ttm->pages, gtt->ttm.dma_address, flags);
@@ -888,6 +1084,9 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
888 return r; 1084 return r;
889} 1085}
890 1086
1087/**
1088 * amdgpu_ttm_alloc_gart - Allocate GART memory for buffer object
1089 */
891int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) 1090int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
892{ 1091{
893 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); 1092 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
@@ -903,6 +1102,7 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
903 amdgpu_gtt_mgr_has_gart_addr(&bo->mem)) 1102 amdgpu_gtt_mgr_has_gart_addr(&bo->mem))
904 return 0; 1103 return 0;
905 1104
1105 /* allocate GTT space */
906 tmp = bo->mem; 1106 tmp = bo->mem;
907 tmp.mm_node = NULL; 1107 tmp.mm_node = NULL;
908 placement.num_placement = 1; 1108 placement.num_placement = 1;
@@ -918,10 +1118,12 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
918 if (unlikely(r)) 1118 if (unlikely(r))
919 return r; 1119 return r;
920 1120
1121 /* compute PTE flags for this buffer object */
921 flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, &tmp); 1122 flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, &tmp);
1123
1124 /* Bind pages */
922 gtt->offset = (u64)tmp.start << PAGE_SHIFT; 1125 gtt->offset = (u64)tmp.start << PAGE_SHIFT;
923 r = amdgpu_gart_bind(adev, gtt->offset, bo->ttm->num_pages, 1126 r = amdgpu_ttm_gart_bind(adev, bo, flags);
924 bo->ttm->pages, gtt->ttm.dma_address, flags);
925 if (unlikely(r)) { 1127 if (unlikely(r)) {
926 ttm_bo_mem_put(bo, &tmp); 1128 ttm_bo_mem_put(bo, &tmp);
927 return r; 1129 return r;
@@ -935,31 +1137,40 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
935 return 0; 1137 return 0;
936} 1138}
937 1139
1140/**
1141 * amdgpu_ttm_recover_gart - Rebind GTT pages
1142 *
1143 * Called by amdgpu_gtt_mgr_recover() from amdgpu_device_reset() to
1144 * rebind GTT pages during a GPU reset.
1145 */
938int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo) 1146int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo)
939{ 1147{
940 struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); 1148 struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
941 struct amdgpu_ttm_tt *gtt = (void *)tbo->ttm;
942 uint64_t flags; 1149 uint64_t flags;
943 int r; 1150 int r;
944 1151
945 if (!gtt) 1152 if (!tbo->ttm)
946 return 0; 1153 return 0;
947 1154
948 flags = amdgpu_ttm_tt_pte_flags(adev, &gtt->ttm.ttm, &tbo->mem); 1155 flags = amdgpu_ttm_tt_pte_flags(adev, tbo->ttm, &tbo->mem);
949 r = amdgpu_gart_bind(adev, gtt->offset, gtt->ttm.ttm.num_pages, 1156 r = amdgpu_ttm_gart_bind(adev, tbo, flags);
950 gtt->ttm.ttm.pages, gtt->ttm.dma_address, flags); 1157
951 if (r)
952 DRM_ERROR("failed to bind %lu pages at 0x%08llX\n",
953 gtt->ttm.ttm.num_pages, gtt->offset);
954 return r; 1158 return r;
955} 1159}
956 1160
1161/**
1162 * amdgpu_ttm_backend_unbind - Unbind GTT mapped pages
1163 *
1164 * Called by ttm_tt_unbind() on behalf of ttm_bo_move_ttm() and
1165 * ttm_tt_destroy().
1166 */
957static int amdgpu_ttm_backend_unbind(struct ttm_tt *ttm) 1167static int amdgpu_ttm_backend_unbind(struct ttm_tt *ttm)
958{ 1168{
959 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); 1169 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
960 struct amdgpu_ttm_tt *gtt = (void *)ttm; 1170 struct amdgpu_ttm_tt *gtt = (void *)ttm;
961 int r; 1171 int r;
962 1172
1173 /* if the pages have userptr pinning then clear that first */
963 if (gtt->userptr) 1174 if (gtt->userptr)
964 amdgpu_ttm_tt_unpin_userptr(ttm); 1175 amdgpu_ttm_tt_unpin_userptr(ttm);
965 1176
@@ -978,6 +1189,9 @@ static void amdgpu_ttm_backend_destroy(struct ttm_tt *ttm)
978{ 1189{
979 struct amdgpu_ttm_tt *gtt = (void *)ttm; 1190 struct amdgpu_ttm_tt *gtt = (void *)ttm;
980 1191
1192 if (gtt->usertask)
1193 put_task_struct(gtt->usertask);
1194
981 ttm_dma_tt_fini(&gtt->ttm); 1195 ttm_dma_tt_fini(&gtt->ttm);
982 kfree(gtt); 1196 kfree(gtt);
983} 1197}
@@ -988,6 +1202,13 @@ static struct ttm_backend_func amdgpu_backend_func = {
988 .destroy = &amdgpu_ttm_backend_destroy, 1202 .destroy = &amdgpu_ttm_backend_destroy,
989}; 1203};
990 1204
1205/**
1206 * amdgpu_ttm_tt_create - Create a ttm_tt object for a given BO
1207 *
1208 * @bo: The buffer object to create a GTT ttm_tt object around
1209 *
1210 * Called by ttm_tt_create().
1211 */
991static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo, 1212static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo,
992 uint32_t page_flags) 1213 uint32_t page_flags)
993{ 1214{
@@ -1001,6 +1222,8 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo,
1001 return NULL; 1222 return NULL;
1002 } 1223 }
1003 gtt->ttm.ttm.func = &amdgpu_backend_func; 1224 gtt->ttm.ttm.func = &amdgpu_backend_func;
1225
1226 /* allocate space for the uninitialized page entries */
1004 if (ttm_sg_tt_init(&gtt->ttm, bo, page_flags)) { 1227 if (ttm_sg_tt_init(&gtt->ttm, bo, page_flags)) {
1005 kfree(gtt); 1228 kfree(gtt);
1006 return NULL; 1229 return NULL;
@@ -1008,6 +1231,12 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo,
1008 return &gtt->ttm.ttm; 1231 return &gtt->ttm.ttm;
1009} 1232}
1010 1233
1234/**
1235 * amdgpu_ttm_tt_populate - Map GTT pages visible to the device
1236 *
1237 * Map the pages of a ttm_tt object to an address space visible
1238 * to the underlying device.
1239 */
1011static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm, 1240static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,
1012 struct ttm_operation_ctx *ctx) 1241 struct ttm_operation_ctx *ctx)
1013{ 1242{
@@ -1015,6 +1244,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,
1015 struct amdgpu_ttm_tt *gtt = (void *)ttm; 1244 struct amdgpu_ttm_tt *gtt = (void *)ttm;
1016 bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); 1245 bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
1017 1246
1247 /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */
1018 if (gtt && gtt->userptr) { 1248 if (gtt && gtt->userptr) {
1019 ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); 1249 ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
1020 if (!ttm->sg) 1250 if (!ttm->sg)
@@ -1039,9 +1269,17 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,
1039 } 1269 }
1040#endif 1270#endif
1041 1271
1272 /* fall back to generic helper to populate the page array
1273 * and map them to the device */
1042 return ttm_populate_and_map_pages(adev->dev, &gtt->ttm, ctx); 1274 return ttm_populate_and_map_pages(adev->dev, &gtt->ttm, ctx);
1043} 1275}
1044 1276
1277/**
1278 * amdgpu_ttm_tt_unpopulate - unmap GTT pages and unpopulate page arrays
1279 *
1280 * Unmaps pages of a ttm_tt object from the device address space and
1281 * unpopulates the page array backing it.
1282 */
1045static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) 1283static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
1046{ 1284{
1047 struct amdgpu_device *adev; 1285 struct amdgpu_device *adev;
@@ -1067,9 +1305,21 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
1067 } 1305 }
1068#endif 1306#endif
1069 1307
1308 /* fall back to generic helper to unmap and unpopulate array */
1070 ttm_unmap_and_unpopulate_pages(adev->dev, &gtt->ttm); 1309 ttm_unmap_and_unpopulate_pages(adev->dev, &gtt->ttm);
1071} 1310}
1072 1311
1312/**
1313 * amdgpu_ttm_tt_set_userptr - Initialize userptr GTT ttm_tt
1314 * for the current task
1315 *
1316 * @ttm: The ttm_tt object to bind this userptr object to
1317 * @addr: The address in the current tasks VM space to use
1318 * @flags: Requirements of userptr object.
1319 *
1320 * Called by amdgpu_gem_userptr_ioctl() to bind userptr pages
1321 * to current task
1322 */
1073int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, 1323int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
1074 uint32_t flags) 1324 uint32_t flags)
1075{ 1325{
@@ -1079,8 +1329,13 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
1079 return -EINVAL; 1329 return -EINVAL;
1080 1330
1081 gtt->userptr = addr; 1331 gtt->userptr = addr;
1082 gtt->usermm = current->mm;
1083 gtt->userflags = flags; 1332 gtt->userflags = flags;
1333
1334 if (gtt->usertask)
1335 put_task_struct(gtt->usertask);
1336 gtt->usertask = current->group_leader;
1337 get_task_struct(gtt->usertask);
1338
1084 spin_lock_init(&gtt->guptasklock); 1339 spin_lock_init(&gtt->guptasklock);
1085 INIT_LIST_HEAD(&gtt->guptasks); 1340 INIT_LIST_HEAD(&gtt->guptasks);
1086 atomic_set(&gtt->mmu_invalidations, 0); 1341 atomic_set(&gtt->mmu_invalidations, 0);
@@ -1089,6 +1344,9 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
1089 return 0; 1344 return 0;
1090} 1345}
1091 1346
1347/**
1348 * amdgpu_ttm_tt_get_usermm - Return memory manager for ttm_tt object
1349 */
1092struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm) 1350struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)
1093{ 1351{
1094 struct amdgpu_ttm_tt *gtt = (void *)ttm; 1352 struct amdgpu_ttm_tt *gtt = (void *)ttm;
@@ -1096,9 +1354,18 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)
1096 if (gtt == NULL) 1354 if (gtt == NULL)
1097 return NULL; 1355 return NULL;
1098 1356
1099 return gtt->usermm; 1357 if (gtt->usertask == NULL)
1358 return NULL;
1359
1360 return gtt->usertask->mm;
1100} 1361}
1101 1362
1363/**
1364 * amdgpu_ttm_tt_affect_userptr - Determine if a ttm_tt object lays
1365 * inside an address range for the
1366 * current task.
1367 *
1368 */
1102bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, 1369bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
1103 unsigned long end) 1370 unsigned long end)
1104{ 1371{
@@ -1109,10 +1376,16 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
1109 if (gtt == NULL || !gtt->userptr) 1376 if (gtt == NULL || !gtt->userptr)
1110 return false; 1377 return false;
1111 1378
1379 /* Return false if no part of the ttm_tt object lies within
1380 * the range
1381 */
1112 size = (unsigned long)gtt->ttm.ttm.num_pages * PAGE_SIZE; 1382 size = (unsigned long)gtt->ttm.ttm.num_pages * PAGE_SIZE;
1113 if (gtt->userptr > end || gtt->userptr + size <= start) 1383 if (gtt->userptr > end || gtt->userptr + size <= start)
1114 return false; 1384 return false;
1115 1385
1386 /* Search the lists of tasks that hold this mapping and see
1387 * if current is one of them. If it is return false.
1388 */
1116 spin_lock(&gtt->guptasklock); 1389 spin_lock(&gtt->guptasklock);
1117 list_for_each_entry(entry, &gtt->guptasks, list) { 1390 list_for_each_entry(entry, &gtt->guptasks, list) {
1118 if (entry->task == current) { 1391 if (entry->task == current) {
@@ -1127,6 +1400,10 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
1127 return true; 1400 return true;
1128} 1401}
1129 1402
1403/**
1404 * amdgpu_ttm_tt_userptr_invalidated - Has the ttm_tt object been
1405 * invalidated?
1406 */
1130bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, 1407bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm,
1131 int *last_invalidated) 1408 int *last_invalidated)
1132{ 1409{
@@ -1137,6 +1414,12 @@ bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm,
1137 return prev_invalidated != *last_invalidated; 1414 return prev_invalidated != *last_invalidated;
1138} 1415}
1139 1416
1417/**
1418 * amdgpu_ttm_tt_userptr_needs_pages - Have the pages backing this
1419 * ttm_tt object been invalidated
1420 * since the last time they've
1421 * been set?
1422 */
1140bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm) 1423bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm)
1141{ 1424{
1142 struct amdgpu_ttm_tt *gtt = (void *)ttm; 1425 struct amdgpu_ttm_tt *gtt = (void *)ttm;
@@ -1147,6 +1430,9 @@ bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm)
1147 return atomic_read(&gtt->mmu_invalidations) != gtt->last_set_pages; 1430 return atomic_read(&gtt->mmu_invalidations) != gtt->last_set_pages;
1148} 1431}
1149 1432
1433/**
1434 * amdgpu_ttm_tt_is_readonly - Is the ttm_tt object read only?
1435 */
1150bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) 1436bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm)
1151{ 1437{
1152 struct amdgpu_ttm_tt *gtt = (void *)ttm; 1438 struct amdgpu_ttm_tt *gtt = (void *)ttm;
@@ -1157,6 +1443,12 @@ bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm)
1157 return !!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); 1443 return !!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
1158} 1444}
1159 1445
1446/**
1447 * amdgpu_ttm_tt_pte_flags - Compute PTE flags for ttm_tt object
1448 *
1449 * @ttm: The ttm_tt object to compute the flags for
1450 * @mem: The memory registry backing this ttm_tt object
1451 */
1160uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, 1452uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
1161 struct ttm_mem_reg *mem) 1453 struct ttm_mem_reg *mem)
1162{ 1454{
@@ -1181,6 +1473,16 @@ uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
1181 return flags; 1473 return flags;
1182} 1474}
1183 1475
1476/**
1477 * amdgpu_ttm_bo_eviction_valuable - Check to see if we can evict
1478 * a buffer object.
1479 *
1480 * Return true if eviction is sensible. Called by
1481 * ttm_mem_evict_first() on behalf of ttm_bo_mem_force_space()
1482 * which tries to evict buffer objects until it can find space
1483 * for a new object and by ttm_bo_force_list_clean() which is
1484 * used to clean out a memory space.
1485 */
1184static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, 1486static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
1185 const struct ttm_place *place) 1487 const struct ttm_place *place)
1186{ 1488{
@@ -1227,6 +1529,19 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
1227 return ttm_bo_eviction_valuable(bo, place); 1529 return ttm_bo_eviction_valuable(bo, place);
1228} 1530}
1229 1531
1532/**
1533 * amdgpu_ttm_access_memory - Read or Write memory that backs a
1534 * buffer object.
1535 *
1536 * @bo: The buffer object to read/write
1537 * @offset: Offset into buffer object
1538 * @buf: Secondary buffer to write/read from
1539 * @len: Length in bytes of access
1540 * @write: true if writing
1541 *
1542 * This is used to access VRAM that backs a buffer object via MMIO
1543 * access for debugging purposes.
1544 */
1230static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, 1545static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
1231 unsigned long offset, 1546 unsigned long offset,
1232 void *buf, int len, int write) 1547 void *buf, int len, int write)
@@ -1329,6 +1644,7 @@ static void amdgpu_ttm_fw_reserve_vram_fini(struct amdgpu_device *adev)
1329static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev) 1644static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev)
1330{ 1645{
1331 struct ttm_operation_ctx ctx = { false, false }; 1646 struct ttm_operation_ctx ctx = { false, false };
1647 struct amdgpu_bo_param bp;
1332 int r = 0; 1648 int r = 0;
1333 int i; 1649 int i;
1334 u64 vram_size = adev->gmc.visible_vram_size; 1650 u64 vram_size = adev->gmc.visible_vram_size;
@@ -1336,17 +1652,21 @@ static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev)
1336 u64 size = adev->fw_vram_usage.size; 1652 u64 size = adev->fw_vram_usage.size;
1337 struct amdgpu_bo *bo; 1653 struct amdgpu_bo *bo;
1338 1654
1655 memset(&bp, 0, sizeof(bp));
1656 bp.size = adev->fw_vram_usage.size;
1657 bp.byte_align = PAGE_SIZE;
1658 bp.domain = AMDGPU_GEM_DOMAIN_VRAM;
1659 bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
1660 AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
1661 bp.type = ttm_bo_type_kernel;
1662 bp.resv = NULL;
1339 adev->fw_vram_usage.va = NULL; 1663 adev->fw_vram_usage.va = NULL;
1340 adev->fw_vram_usage.reserved_bo = NULL; 1664 adev->fw_vram_usage.reserved_bo = NULL;
1341 1665
1342 if (adev->fw_vram_usage.size > 0 && 1666 if (adev->fw_vram_usage.size > 0 &&
1343 adev->fw_vram_usage.size <= vram_size) { 1667 adev->fw_vram_usage.size <= vram_size) {
1344 1668
1345 r = amdgpu_bo_create(adev, adev->fw_vram_usage.size, PAGE_SIZE, 1669 r = amdgpu_bo_create(adev, &bp,
1346 AMDGPU_GEM_DOMAIN_VRAM,
1347 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
1348 AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
1349 ttm_bo_type_kernel, NULL,
1350 &adev->fw_vram_usage.reserved_bo); 1670 &adev->fw_vram_usage.reserved_bo);
1351 if (r) 1671 if (r)
1352 goto error_create; 1672 goto error_create;
@@ -1398,13 +1718,22 @@ error_create:
1398 adev->fw_vram_usage.reserved_bo = NULL; 1718 adev->fw_vram_usage.reserved_bo = NULL;
1399 return r; 1719 return r;
1400} 1720}
1401 1721/**
1722 * amdgpu_ttm_init - Init the memory management (ttm) as well as
1723 * various gtt/vram related fields.
1724 *
1725 * This initializes all of the memory space pools that the TTM layer
1726 * will need such as the GTT space (system memory mapped to the device),
1727 * VRAM (on-board memory), and on-chip memories (GDS, GWS, OA) which
1728 * can be mapped per VMID.
1729 */
1402int amdgpu_ttm_init(struct amdgpu_device *adev) 1730int amdgpu_ttm_init(struct amdgpu_device *adev)
1403{ 1731{
1404 uint64_t gtt_size; 1732 uint64_t gtt_size;
1405 int r; 1733 int r;
1406 u64 vis_vram_limit; 1734 u64 vis_vram_limit;
1407 1735
1736 /* initialize global references for vram/gtt */
1408 r = amdgpu_ttm_global_init(adev); 1737 r = amdgpu_ttm_global_init(adev);
1409 if (r) { 1738 if (r) {
1410 return r; 1739 return r;
@@ -1425,6 +1754,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1425 /* We opt to avoid OOM on system pages allocations */ 1754 /* We opt to avoid OOM on system pages allocations */
1426 adev->mman.bdev.no_retry = true; 1755 adev->mman.bdev.no_retry = true;
1427 1756
1757 /* Initialize VRAM pool with all of VRAM divided into pages */
1428 r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM, 1758 r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM,
1429 adev->gmc.real_vram_size >> PAGE_SHIFT); 1759 adev->gmc.real_vram_size >> PAGE_SHIFT);
1430 if (r) { 1760 if (r) {
@@ -1454,15 +1784,23 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1454 return r; 1784 return r;
1455 } 1785 }
1456 1786
1457 r = amdgpu_bo_create_kernel(adev, adev->gmc.stolen_size, PAGE_SIZE, 1787 /* allocate memory as required for VGA
1458 AMDGPU_GEM_DOMAIN_VRAM, 1788 * This is used for VGA emulation and pre-OS scanout buffers to
1459 &adev->stolen_vga_memory, 1789 * avoid display artifacts while transitioning between pre-OS
1460 NULL, NULL); 1790 * and driver. */
1461 if (r) 1791 if (adev->gmc.stolen_size) {
1462 return r; 1792 r = amdgpu_bo_create_kernel(adev, adev->gmc.stolen_size, PAGE_SIZE,
1793 AMDGPU_GEM_DOMAIN_VRAM,
1794 &adev->stolen_vga_memory,
1795 NULL, NULL);
1796 if (r)
1797 return r;
1798 }
1463 DRM_INFO("amdgpu: %uM of VRAM memory ready\n", 1799 DRM_INFO("amdgpu: %uM of VRAM memory ready\n",
1464 (unsigned) (adev->gmc.real_vram_size / (1024 * 1024))); 1800 (unsigned) (adev->gmc.real_vram_size / (1024 * 1024)));
1465 1801
1802 /* Compute GTT size, either bsaed on 3/4th the size of RAM size
1803 * or whatever the user passed on module init */
1466 if (amdgpu_gtt_size == -1) { 1804 if (amdgpu_gtt_size == -1) {
1467 struct sysinfo si; 1805 struct sysinfo si;
1468 1806
@@ -1473,6 +1811,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1473 } 1811 }
1474 else 1812 else
1475 gtt_size = (uint64_t)amdgpu_gtt_size << 20; 1813 gtt_size = (uint64_t)amdgpu_gtt_size << 20;
1814
1815 /* Initialize GTT memory pool */
1476 r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT); 1816 r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT);
1477 if (r) { 1817 if (r) {
1478 DRM_ERROR("Failed initializing GTT heap.\n"); 1818 DRM_ERROR("Failed initializing GTT heap.\n");
@@ -1481,6 +1821,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1481 DRM_INFO("amdgpu: %uM of GTT memory ready.\n", 1821 DRM_INFO("amdgpu: %uM of GTT memory ready.\n",
1482 (unsigned)(gtt_size / (1024 * 1024))); 1822 (unsigned)(gtt_size / (1024 * 1024)));
1483 1823
1824 /* Initialize various on-chip memory pools */
1484 adev->gds.mem.total_size = adev->gds.mem.total_size << AMDGPU_GDS_SHIFT; 1825 adev->gds.mem.total_size = adev->gds.mem.total_size << AMDGPU_GDS_SHIFT;
1485 adev->gds.mem.gfx_partition_size = adev->gds.mem.gfx_partition_size << AMDGPU_GDS_SHIFT; 1826 adev->gds.mem.gfx_partition_size = adev->gds.mem.gfx_partition_size << AMDGPU_GDS_SHIFT;
1486 adev->gds.mem.cs_partition_size = adev->gds.mem.cs_partition_size << AMDGPU_GDS_SHIFT; 1827 adev->gds.mem.cs_partition_size = adev->gds.mem.cs_partition_size << AMDGPU_GDS_SHIFT;
@@ -1520,6 +1861,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1520 } 1861 }
1521 } 1862 }
1522 1863
1864 /* Register debugfs entries for amdgpu_ttm */
1523 r = amdgpu_ttm_debugfs_init(adev); 1865 r = amdgpu_ttm_debugfs_init(adev);
1524 if (r) { 1866 if (r) {
1525 DRM_ERROR("Failed to init debugfs\n"); 1867 DRM_ERROR("Failed to init debugfs\n");
@@ -1528,13 +1870,25 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1528 return 0; 1870 return 0;
1529} 1871}
1530 1872
1873/**
1874 * amdgpu_ttm_late_init - Handle any late initialization for
1875 * amdgpu_ttm
1876 */
1877void amdgpu_ttm_late_init(struct amdgpu_device *adev)
1878{
1879 /* return the VGA stolen memory (if any) back to VRAM */
1880 amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
1881}
1882
1883/**
1884 * amdgpu_ttm_fini - De-initialize the TTM memory pools
1885 */
1531void amdgpu_ttm_fini(struct amdgpu_device *adev) 1886void amdgpu_ttm_fini(struct amdgpu_device *adev)
1532{ 1887{
1533 if (!adev->mman.initialized) 1888 if (!adev->mman.initialized)
1534 return; 1889 return;
1535 1890
1536 amdgpu_ttm_debugfs_fini(adev); 1891 amdgpu_ttm_debugfs_fini(adev);
1537 amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
1538 amdgpu_ttm_fw_reserve_vram_fini(adev); 1892 amdgpu_ttm_fw_reserve_vram_fini(adev);
1539 if (adev->mman.aper_base_kaddr) 1893 if (adev->mman.aper_base_kaddr)
1540 iounmap(adev->mman.aper_base_kaddr); 1894 iounmap(adev->mman.aper_base_kaddr);
@@ -1856,6 +2210,11 @@ static const struct drm_info_list amdgpu_ttm_debugfs_list[] = {
1856#endif 2210#endif
1857}; 2211};
1858 2212
2213/**
2214 * amdgpu_ttm_vram_read - Linear read access to VRAM
2215 *
2216 * Accesses VRAM via MMIO for debugging purposes.
2217 */
1859static ssize_t amdgpu_ttm_vram_read(struct file *f, char __user *buf, 2218static ssize_t amdgpu_ttm_vram_read(struct file *f, char __user *buf,
1860 size_t size, loff_t *pos) 2219 size_t size, loff_t *pos)
1861{ 2220{
@@ -1895,6 +2254,11 @@ static ssize_t amdgpu_ttm_vram_read(struct file *f, char __user *buf,
1895 return result; 2254 return result;
1896} 2255}
1897 2256
2257/**
2258 * amdgpu_ttm_vram_write - Linear write access to VRAM
2259 *
2260 * Accesses VRAM via MMIO for debugging purposes.
2261 */
1898static ssize_t amdgpu_ttm_vram_write(struct file *f, const char __user *buf, 2262static ssize_t amdgpu_ttm_vram_write(struct file *f, const char __user *buf,
1899 size_t size, loff_t *pos) 2263 size_t size, loff_t *pos)
1900{ 2264{
@@ -1943,6 +2307,9 @@ static const struct file_operations amdgpu_ttm_vram_fops = {
1943 2307
1944#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS 2308#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
1945 2309
2310/**
2311 * amdgpu_ttm_gtt_read - Linear read access to GTT memory
2312 */
1946static ssize_t amdgpu_ttm_gtt_read(struct file *f, char __user *buf, 2313static ssize_t amdgpu_ttm_gtt_read(struct file *f, char __user *buf,
1947 size_t size, loff_t *pos) 2314 size_t size, loff_t *pos)
1948{ 2315{
@@ -1990,6 +2357,13 @@ static const struct file_operations amdgpu_ttm_gtt_fops = {
1990 2357
1991#endif 2358#endif
1992 2359
2360/**
2361 * amdgpu_iomem_read - Virtual read access to GPU mapped memory
2362 *
2363 * This function is used to read memory that has been mapped to the
2364 * GPU and the known addresses are not physical addresses but instead
2365 * bus addresses (e.g., what you'd put in an IB or ring buffer).
2366 */
1993static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf, 2367static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf,
1994 size_t size, loff_t *pos) 2368 size_t size, loff_t *pos)
1995{ 2369{
@@ -1998,6 +2372,7 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf,
1998 ssize_t result = 0; 2372 ssize_t result = 0;
1999 int r; 2373 int r;
2000 2374
2375 /* retrieve the IOMMU domain if any for this device */
2001 dom = iommu_get_domain_for_dev(adev->dev); 2376 dom = iommu_get_domain_for_dev(adev->dev);
2002 2377
2003 while (size) { 2378 while (size) {
@@ -2010,6 +2385,10 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf,
2010 2385
2011 bytes = bytes < size ? bytes : size; 2386 bytes = bytes < size ? bytes : size;
2012 2387
2388 /* Translate the bus address to a physical address. If
2389 * the domain is NULL it means there is no IOMMU active
2390 * and the address translation is the identity
2391 */
2013 addr = dom ? iommu_iova_to_phys(dom, addr) : addr; 2392 addr = dom ? iommu_iova_to_phys(dom, addr) : addr;
2014 2393
2015 pfn = addr >> PAGE_SHIFT; 2394 pfn = addr >> PAGE_SHIFT;
@@ -2034,6 +2413,13 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf,
2034 return result; 2413 return result;
2035} 2414}
2036 2415
2416/**
2417 * amdgpu_iomem_write - Virtual write access to GPU mapped memory
2418 *
2419 * This function is used to write memory that has been mapped to the
2420 * GPU and the known addresses are not physical addresses but instead
2421 * bus addresses (e.g., what you'd put in an IB or ring buffer).
2422 */
2037static ssize_t amdgpu_iomem_write(struct file *f, const char __user *buf, 2423static ssize_t amdgpu_iomem_write(struct file *f, const char __user *buf,
2038 size_t size, loff_t *pos) 2424 size_t size, loff_t *pos)
2039{ 2425{
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 6ea7de863041..e969c879d87e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -77,6 +77,7 @@ uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man);
77uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man); 77uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man);
78 78
79int amdgpu_ttm_init(struct amdgpu_device *adev); 79int amdgpu_ttm_init(struct amdgpu_device *adev);
80void amdgpu_ttm_late_init(struct amdgpu_device *adev);
80void amdgpu_ttm_fini(struct amdgpu_device *adev); 81void amdgpu_ttm_fini(struct amdgpu_device *adev);
81void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, 82void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
82 bool enable); 83 bool enable);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
index 5916cc25e28b..f55f72a37ca8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
@@ -161,8 +161,38 @@ void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
161 le32_to_cpu(rlc_hdr->reg_list_format_separate_array_offset_bytes)); 161 le32_to_cpu(rlc_hdr->reg_list_format_separate_array_offset_bytes));
162 DRM_DEBUG("reg_list_separate_size_bytes: %u\n", 162 DRM_DEBUG("reg_list_separate_size_bytes: %u\n",
163 le32_to_cpu(rlc_hdr->reg_list_separate_size_bytes)); 163 le32_to_cpu(rlc_hdr->reg_list_separate_size_bytes));
164 DRM_DEBUG("reg_list_separate_size_bytes: %u\n", 164 DRM_DEBUG("reg_list_separate_array_offset_bytes: %u\n",
165 le32_to_cpu(rlc_hdr->reg_list_separate_size_bytes)); 165 le32_to_cpu(rlc_hdr->reg_list_separate_array_offset_bytes));
166 if (version_minor == 1) {
167 const struct rlc_firmware_header_v2_1 *v2_1 =
168 container_of(rlc_hdr, struct rlc_firmware_header_v2_1, v2_0);
169 DRM_DEBUG("reg_list_format_direct_reg_list_length: %u\n",
170 le32_to_cpu(v2_1->reg_list_format_direct_reg_list_length));
171 DRM_DEBUG("save_restore_list_cntl_ucode_ver: %u\n",
172 le32_to_cpu(v2_1->save_restore_list_cntl_ucode_ver));
173 DRM_DEBUG("save_restore_list_cntl_feature_ver: %u\n",
174 le32_to_cpu(v2_1->save_restore_list_cntl_feature_ver));
175 DRM_DEBUG("save_restore_list_cntl_size_bytes %u\n",
176 le32_to_cpu(v2_1->save_restore_list_cntl_size_bytes));
177 DRM_DEBUG("save_restore_list_cntl_offset_bytes: %u\n",
178 le32_to_cpu(v2_1->save_restore_list_cntl_offset_bytes));
179 DRM_DEBUG("save_restore_list_gpm_ucode_ver: %u\n",
180 le32_to_cpu(v2_1->save_restore_list_gpm_ucode_ver));
181 DRM_DEBUG("save_restore_list_gpm_feature_ver: %u\n",
182 le32_to_cpu(v2_1->save_restore_list_gpm_feature_ver));
183 DRM_DEBUG("save_restore_list_gpm_size_bytes %u\n",
184 le32_to_cpu(v2_1->save_restore_list_gpm_size_bytes));
185 DRM_DEBUG("save_restore_list_gpm_offset_bytes: %u\n",
186 le32_to_cpu(v2_1->save_restore_list_gpm_offset_bytes));
187 DRM_DEBUG("save_restore_list_srm_ucode_ver: %u\n",
188 le32_to_cpu(v2_1->save_restore_list_srm_ucode_ver));
189 DRM_DEBUG("save_restore_list_srm_feature_ver: %u\n",
190 le32_to_cpu(v2_1->save_restore_list_srm_feature_ver));
191 DRM_DEBUG("save_restore_list_srm_size_bytes %u\n",
192 le32_to_cpu(v2_1->save_restore_list_srm_size_bytes));
193 DRM_DEBUG("save_restore_list_srm_offset_bytes: %u\n",
194 le32_to_cpu(v2_1->save_restore_list_srm_offset_bytes));
195 }
166 } else { 196 } else {
167 DRM_ERROR("Unknown RLC ucode version: %u.%u\n", version_major, version_minor); 197 DRM_ERROR("Unknown RLC ucode version: %u.%u\n", version_major, version_minor);
168 } 198 }
@@ -265,6 +295,7 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
265 case CHIP_POLARIS10: 295 case CHIP_POLARIS10:
266 case CHIP_POLARIS11: 296 case CHIP_POLARIS11:
267 case CHIP_POLARIS12: 297 case CHIP_POLARIS12:
298 case CHIP_VEGAM:
268 if (!load_type) 299 if (!load_type)
269 return AMDGPU_FW_LOAD_DIRECT; 300 return AMDGPU_FW_LOAD_DIRECT;
270 else 301 else
@@ -276,6 +307,8 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
276 return AMDGPU_FW_LOAD_DIRECT; 307 return AMDGPU_FW_LOAD_DIRECT;
277 else 308 else
278 return AMDGPU_FW_LOAD_PSP; 309 return AMDGPU_FW_LOAD_PSP;
310 case CHIP_VEGA20:
311 return AMDGPU_FW_LOAD_DIRECT;
279 default: 312 default:
280 DRM_ERROR("Unknown firmware load type\n"); 313 DRM_ERROR("Unknown firmware load type\n");
281 } 314 }
@@ -307,7 +340,10 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
307 (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 && 340 (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 &&
308 ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2 && 341 ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2 &&
309 ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1_JT && 342 ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1_JT &&
310 ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT)) { 343 ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT &&
344 ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL &&
345 ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM &&
346 ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM)) {
311 ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); 347 ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes);
312 348
313 memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + 349 memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
@@ -329,6 +365,18 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
329 le32_to_cpu(header->ucode_array_offset_bytes) + 365 le32_to_cpu(header->ucode_array_offset_bytes) +
330 le32_to_cpu(cp_hdr->jt_offset) * 4), 366 le32_to_cpu(cp_hdr->jt_offset) * 4),
331 ucode->ucode_size); 367 ucode->ucode_size);
368 } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) {
369 ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes;
370 memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl,
371 ucode->ucode_size);
372 } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM) {
373 ucode->ucode_size = adev->gfx.rlc.save_restore_list_gpm_size_bytes;
374 memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_gpm,
375 ucode->ucode_size);
376 } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM) {
377 ucode->ucode_size = adev->gfx.rlc.save_restore_list_srm_size_bytes;
378 memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_srm,
379 ucode->ucode_size);
332 } 380 }
333 381
334 return 0; 382 return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
index 30b5500dc152..08e38579af24 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
@@ -98,6 +98,24 @@ struct rlc_firmware_header_v2_0 {
98 uint32_t reg_list_separate_array_offset_bytes; /* payload offset from the start of the header */ 98 uint32_t reg_list_separate_array_offset_bytes; /* payload offset from the start of the header */
99}; 99};
100 100
101/* version_major=2, version_minor=1 */
102struct rlc_firmware_header_v2_1 {
103 struct rlc_firmware_header_v2_0 v2_0;
104 uint32_t reg_list_format_direct_reg_list_length; /* length of direct reg list format array */
105 uint32_t save_restore_list_cntl_ucode_ver;
106 uint32_t save_restore_list_cntl_feature_ver;
107 uint32_t save_restore_list_cntl_size_bytes;
108 uint32_t save_restore_list_cntl_offset_bytes;
109 uint32_t save_restore_list_gpm_ucode_ver;
110 uint32_t save_restore_list_gpm_feature_ver;
111 uint32_t save_restore_list_gpm_size_bytes;
112 uint32_t save_restore_list_gpm_offset_bytes;
113 uint32_t save_restore_list_srm_ucode_ver;
114 uint32_t save_restore_list_srm_feature_ver;
115 uint32_t save_restore_list_srm_size_bytes;
116 uint32_t save_restore_list_srm_offset_bytes;
117};
118
101/* version_major=1, version_minor=0 */ 119/* version_major=1, version_minor=0 */
102struct sdma_firmware_header_v1_0 { 120struct sdma_firmware_header_v1_0 {
103 struct common_firmware_header header; 121 struct common_firmware_header header;
@@ -148,6 +166,7 @@ union amdgpu_firmware_header {
148 struct gfx_firmware_header_v1_0 gfx; 166 struct gfx_firmware_header_v1_0 gfx;
149 struct rlc_firmware_header_v1_0 rlc; 167 struct rlc_firmware_header_v1_0 rlc;
150 struct rlc_firmware_header_v2_0 rlc_v2_0; 168 struct rlc_firmware_header_v2_0 rlc_v2_0;
169 struct rlc_firmware_header_v2_1 rlc_v2_1;
151 struct sdma_firmware_header_v1_0 sdma; 170 struct sdma_firmware_header_v1_0 sdma;
152 struct sdma_firmware_header_v1_1 sdma_v1_1; 171 struct sdma_firmware_header_v1_1 sdma_v1_1;
153 struct gpu_info_firmware_header_v1_0 gpu_info; 172 struct gpu_info_firmware_header_v1_0 gpu_info;
@@ -168,6 +187,9 @@ enum AMDGPU_UCODE_ID {
168 AMDGPU_UCODE_ID_CP_MEC2, 187 AMDGPU_UCODE_ID_CP_MEC2,
169 AMDGPU_UCODE_ID_CP_MEC2_JT, 188 AMDGPU_UCODE_ID_CP_MEC2_JT,
170 AMDGPU_UCODE_ID_RLC_G, 189 AMDGPU_UCODE_ID_RLC_G,
190 AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL,
191 AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM,
192 AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM,
171 AMDGPU_UCODE_ID_STORAGE, 193 AMDGPU_UCODE_ID_STORAGE,
172 AMDGPU_UCODE_ID_SMC, 194 AMDGPU_UCODE_ID_SMC,
173 AMDGPU_UCODE_ID_UVD, 195 AMDGPU_UCODE_ID_UVD,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 627542b22ae4..bcf68f80bbf0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -66,15 +66,18 @@
66#define FIRMWARE_POLARIS10 "amdgpu/polaris10_uvd.bin" 66#define FIRMWARE_POLARIS10 "amdgpu/polaris10_uvd.bin"
67#define FIRMWARE_POLARIS11 "amdgpu/polaris11_uvd.bin" 67#define FIRMWARE_POLARIS11 "amdgpu/polaris11_uvd.bin"
68#define FIRMWARE_POLARIS12 "amdgpu/polaris12_uvd.bin" 68#define FIRMWARE_POLARIS12 "amdgpu/polaris12_uvd.bin"
69#define FIRMWARE_VEGAM "amdgpu/vegam_uvd.bin"
69 70
70#define FIRMWARE_VEGA10 "amdgpu/vega10_uvd.bin" 71#define FIRMWARE_VEGA10 "amdgpu/vega10_uvd.bin"
71#define FIRMWARE_VEGA12 "amdgpu/vega12_uvd.bin" 72#define FIRMWARE_VEGA12 "amdgpu/vega12_uvd.bin"
73#define FIRMWARE_VEGA20 "amdgpu/vega20_uvd.bin"
72 74
73#define mmUVD_GPCOM_VCPU_DATA0_VEGA10 (0x03c4 + 0x7e00) 75/* These are common relative offsets for all asics, from uvd_7_0_offset.h, */
74#define mmUVD_GPCOM_VCPU_DATA1_VEGA10 (0x03c5 + 0x7e00) 76#define UVD_GPCOM_VCPU_CMD 0x03c3
75#define mmUVD_GPCOM_VCPU_CMD_VEGA10 (0x03c3 + 0x7e00) 77#define UVD_GPCOM_VCPU_DATA0 0x03c4
76#define mmUVD_NO_OP_VEGA10 (0x03ff + 0x7e00) 78#define UVD_GPCOM_VCPU_DATA1 0x03c5
77#define mmUVD_ENGINE_CNTL_VEGA10 (0x03c6 + 0x7e00) 79#define UVD_NO_OP 0x03ff
80#define UVD_BASE_SI 0x3800
78 81
79/** 82/**
80 * amdgpu_uvd_cs_ctx - Command submission parser context 83 * amdgpu_uvd_cs_ctx - Command submission parser context
@@ -109,9 +112,11 @@ MODULE_FIRMWARE(FIRMWARE_STONEY);
109MODULE_FIRMWARE(FIRMWARE_POLARIS10); 112MODULE_FIRMWARE(FIRMWARE_POLARIS10);
110MODULE_FIRMWARE(FIRMWARE_POLARIS11); 113MODULE_FIRMWARE(FIRMWARE_POLARIS11);
111MODULE_FIRMWARE(FIRMWARE_POLARIS12); 114MODULE_FIRMWARE(FIRMWARE_POLARIS12);
115MODULE_FIRMWARE(FIRMWARE_VEGAM);
112 116
113MODULE_FIRMWARE(FIRMWARE_VEGA10); 117MODULE_FIRMWARE(FIRMWARE_VEGA10);
114MODULE_FIRMWARE(FIRMWARE_VEGA12); 118MODULE_FIRMWARE(FIRMWARE_VEGA12);
119MODULE_FIRMWARE(FIRMWARE_VEGA20);
115 120
116static void amdgpu_uvd_idle_work_handler(struct work_struct *work); 121static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
117 122
@@ -123,9 +128,9 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
123 const char *fw_name; 128 const char *fw_name;
124 const struct common_firmware_header *hdr; 129 const struct common_firmware_header *hdr;
125 unsigned version_major, version_minor, family_id; 130 unsigned version_major, version_minor, family_id;
126 int i, r; 131 int i, j, r;
127 132
128 INIT_DELAYED_WORK(&adev->uvd.idle_work, amdgpu_uvd_idle_work_handler); 133 INIT_DELAYED_WORK(&adev->uvd.inst->idle_work, amdgpu_uvd_idle_work_handler);
129 134
130 switch (adev->asic_type) { 135 switch (adev->asic_type) {
131#ifdef CONFIG_DRM_AMDGPU_CIK 136#ifdef CONFIG_DRM_AMDGPU_CIK
@@ -172,6 +177,12 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
172 case CHIP_VEGA12: 177 case CHIP_VEGA12:
173 fw_name = FIRMWARE_VEGA12; 178 fw_name = FIRMWARE_VEGA12;
174 break; 179 break;
180 case CHIP_VEGAM:
181 fw_name = FIRMWARE_VEGAM;
182 break;
183 case CHIP_VEGA20:
184 fw_name = FIRMWARE_VEGA20;
185 break;
175 default: 186 default:
176 return -EINVAL; 187 return -EINVAL;
177 } 188 }
@@ -226,28 +237,30 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
226 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) 237 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
227 bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 238 bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
228 239
229 r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, 240 for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
230 AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.vcpu_bo,
231 &adev->uvd.gpu_addr, &adev->uvd.cpu_addr);
232 if (r) {
233 dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r);
234 return r;
235 }
236 241
237 ring = &adev->uvd.ring; 242 r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
238 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 243 AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst[j].vcpu_bo,
239 r = drm_sched_entity_init(&ring->sched, &adev->uvd.entity, 244 &adev->uvd.inst[j].gpu_addr, &adev->uvd.inst[j].cpu_addr);
240 rq, amdgpu_sched_jobs, NULL); 245 if (r) {
241 if (r != 0) { 246 dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r);
242 DRM_ERROR("Failed setting up UVD run queue.\n"); 247 return r;
243 return r; 248 }
244 }
245 249
246 for (i = 0; i < adev->uvd.max_handles; ++i) { 250 ring = &adev->uvd.inst[j].ring;
247 atomic_set(&adev->uvd.handles[i], 0); 251 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL];
248 adev->uvd.filp[i] = NULL; 252 r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst[j].entity,
249 } 253 rq, NULL);
254 if (r != 0) {
255 DRM_ERROR("Failed setting up UVD(%d) run queue.\n", j);
256 return r;
257 }
250 258
259 for (i = 0; i < adev->uvd.max_handles; ++i) {
260 atomic_set(&adev->uvd.inst[j].handles[i], 0);
261 adev->uvd.inst[j].filp[i] = NULL;
262 }
263 }
251 /* from uvd v5.0 HW addressing capacity increased to 64 bits */ 264 /* from uvd v5.0 HW addressing capacity increased to 64 bits */
252 if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0)) 265 if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0))
253 adev->uvd.address_64_bit = true; 266 adev->uvd.address_64_bit = true;
@@ -274,20 +287,22 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
274 287
275int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) 288int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
276{ 289{
277 int i; 290 int i, j;
278 kfree(adev->uvd.saved_bo);
279 291
280 drm_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); 292 for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
293 kfree(adev->uvd.inst[j].saved_bo);
281 294
282 amdgpu_bo_free_kernel(&adev->uvd.vcpu_bo, 295 drm_sched_entity_fini(&adev->uvd.inst[j].ring.sched, &adev->uvd.inst[j].entity);
283 &adev->uvd.gpu_addr,
284 (void **)&adev->uvd.cpu_addr);
285 296
286 amdgpu_ring_fini(&adev->uvd.ring); 297 amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo,
298 &adev->uvd.inst[j].gpu_addr,
299 (void **)&adev->uvd.inst[j].cpu_addr);
287 300
288 for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i) 301 amdgpu_ring_fini(&adev->uvd.inst[j].ring);
289 amdgpu_ring_fini(&adev->uvd.ring_enc[i]);
290 302
303 for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i)
304 amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]);
305 }
291 release_firmware(adev->uvd.fw); 306 release_firmware(adev->uvd.fw);
292 307
293 return 0; 308 return 0;
@@ -297,32 +312,33 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
297{ 312{
298 unsigned size; 313 unsigned size;
299 void *ptr; 314 void *ptr;
300 int i; 315 int i, j;
301
302 if (adev->uvd.vcpu_bo == NULL)
303 return 0;
304 316
305 cancel_delayed_work_sync(&adev->uvd.idle_work); 317 for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
318 if (adev->uvd.inst[j].vcpu_bo == NULL)
319 continue;
306 320
307 /* only valid for physical mode */ 321 cancel_delayed_work_sync(&adev->uvd.inst[j].idle_work);
308 if (adev->asic_type < CHIP_POLARIS10) {
309 for (i = 0; i < adev->uvd.max_handles; ++i)
310 if (atomic_read(&adev->uvd.handles[i]))
311 break;
312 322
313 if (i == adev->uvd.max_handles) 323 /* only valid for physical mode */
314 return 0; 324 if (adev->asic_type < CHIP_POLARIS10) {
315 } 325 for (i = 0; i < adev->uvd.max_handles; ++i)
326 if (atomic_read(&adev->uvd.inst[j].handles[i]))
327 break;
316 328
317 size = amdgpu_bo_size(adev->uvd.vcpu_bo); 329 if (i == adev->uvd.max_handles)
318 ptr = adev->uvd.cpu_addr; 330 continue;
331 }
319 332
320 adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); 333 size = amdgpu_bo_size(adev->uvd.inst[j].vcpu_bo);
321 if (!adev->uvd.saved_bo) 334 ptr = adev->uvd.inst[j].cpu_addr;
322 return -ENOMEM;
323 335
324 memcpy_fromio(adev->uvd.saved_bo, ptr, size); 336 adev->uvd.inst[j].saved_bo = kmalloc(size, GFP_KERNEL);
337 if (!adev->uvd.inst[j].saved_bo)
338 return -ENOMEM;
325 339
340 memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size);
341 }
326 return 0; 342 return 0;
327} 343}
328 344
@@ -330,59 +346,65 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
330{ 346{
331 unsigned size; 347 unsigned size;
332 void *ptr; 348 void *ptr;
349 int i;
333 350
334 if (adev->uvd.vcpu_bo == NULL) 351 for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
335 return -EINVAL; 352 if (adev->uvd.inst[i].vcpu_bo == NULL)
353 return -EINVAL;
336 354
337 size = amdgpu_bo_size(adev->uvd.vcpu_bo); 355 size = amdgpu_bo_size(adev->uvd.inst[i].vcpu_bo);
338 ptr = adev->uvd.cpu_addr; 356 ptr = adev->uvd.inst[i].cpu_addr;
339 357
340 if (adev->uvd.saved_bo != NULL) { 358 if (adev->uvd.inst[i].saved_bo != NULL) {
341 memcpy_toio(ptr, adev->uvd.saved_bo, size); 359 memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size);
342 kfree(adev->uvd.saved_bo); 360 kfree(adev->uvd.inst[i].saved_bo);
343 adev->uvd.saved_bo = NULL; 361 adev->uvd.inst[i].saved_bo = NULL;
344 } else { 362 } else {
345 const struct common_firmware_header *hdr; 363 const struct common_firmware_header *hdr;
346 unsigned offset; 364 unsigned offset;
347 365
348 hdr = (const struct common_firmware_header *)adev->uvd.fw->data; 366 hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
349 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { 367 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
350 offset = le32_to_cpu(hdr->ucode_array_offset_bytes); 368 offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
351 memcpy_toio(adev->uvd.cpu_addr, adev->uvd.fw->data + offset, 369 memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset,
352 le32_to_cpu(hdr->ucode_size_bytes)); 370 le32_to_cpu(hdr->ucode_size_bytes));
353 size -= le32_to_cpu(hdr->ucode_size_bytes); 371 size -= le32_to_cpu(hdr->ucode_size_bytes);
354 ptr += le32_to_cpu(hdr->ucode_size_bytes); 372 ptr += le32_to_cpu(hdr->ucode_size_bytes);
373 }
374 memset_io(ptr, 0, size);
375 /* to restore uvd fence seq */
376 amdgpu_fence_driver_force_completion(&adev->uvd.inst[i].ring);
355 } 377 }
356 memset_io(ptr, 0, size);
357 /* to restore uvd fence seq */
358 amdgpu_fence_driver_force_completion(&adev->uvd.ring);
359 } 378 }
360
361 return 0; 379 return 0;
362} 380}
363 381
364void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp) 382void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
365{ 383{
366 struct amdgpu_ring *ring = &adev->uvd.ring; 384 struct amdgpu_ring *ring;
367 int i, r; 385 int i, j, r;
368 386
369 for (i = 0; i < adev->uvd.max_handles; ++i) { 387 for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
370 uint32_t handle = atomic_read(&adev->uvd.handles[i]); 388 ring = &adev->uvd.inst[j].ring;
371 if (handle != 0 && adev->uvd.filp[i] == filp) { 389
372 struct dma_fence *fence; 390 for (i = 0; i < adev->uvd.max_handles; ++i) {
373 391 uint32_t handle = atomic_read(&adev->uvd.inst[j].handles[i]);
374 r = amdgpu_uvd_get_destroy_msg(ring, handle, 392 if (handle != 0 && adev->uvd.inst[j].filp[i] == filp) {
375 false, &fence); 393 struct dma_fence *fence;
376 if (r) { 394
377 DRM_ERROR("Error destroying UVD (%d)!\n", r); 395 r = amdgpu_uvd_get_destroy_msg(ring, handle,
378 continue; 396 false, &fence);
379 } 397 if (r) {
398 DRM_ERROR("Error destroying UVD(%d) %d!\n", j, r);
399 continue;
400 }
380 401
381 dma_fence_wait(fence, false); 402 dma_fence_wait(fence, false);
382 dma_fence_put(fence); 403 dma_fence_put(fence);
383 404
384 adev->uvd.filp[i] = NULL; 405 adev->uvd.inst[j].filp[i] = NULL;
385 atomic_set(&adev->uvd.handles[i], 0); 406 atomic_set(&adev->uvd.inst[j].handles[i], 0);
407 }
386 } 408 }
387 } 409 }
388} 410}
@@ -657,15 +679,16 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
657 void *ptr; 679 void *ptr;
658 long r; 680 long r;
659 int i; 681 int i;
682 uint32_t ip_instance = ctx->parser->job->ring->me;
660 683
661 if (offset & 0x3F) { 684 if (offset & 0x3F) {
662 DRM_ERROR("UVD messages must be 64 byte aligned!\n"); 685 DRM_ERROR("UVD(%d) messages must be 64 byte aligned!\n", ip_instance);
663 return -EINVAL; 686 return -EINVAL;
664 } 687 }
665 688
666 r = amdgpu_bo_kmap(bo, &ptr); 689 r = amdgpu_bo_kmap(bo, &ptr);
667 if (r) { 690 if (r) {
668 DRM_ERROR("Failed mapping the UVD message (%ld)!\n", r); 691 DRM_ERROR("Failed mapping the UVD(%d) message (%ld)!\n", ip_instance, r);
669 return r; 692 return r;
670 } 693 }
671 694
@@ -675,7 +698,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
675 handle = msg[2]; 698 handle = msg[2];
676 699
677 if (handle == 0) { 700 if (handle == 0) {
678 DRM_ERROR("Invalid UVD handle!\n"); 701 DRM_ERROR("Invalid UVD(%d) handle!\n", ip_instance);
679 return -EINVAL; 702 return -EINVAL;
680 } 703 }
681 704
@@ -686,18 +709,18 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
686 709
687 /* try to alloc a new handle */ 710 /* try to alloc a new handle */
688 for (i = 0; i < adev->uvd.max_handles; ++i) { 711 for (i = 0; i < adev->uvd.max_handles; ++i) {
689 if (atomic_read(&adev->uvd.handles[i]) == handle) { 712 if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) {
690 DRM_ERROR("Handle 0x%x already in use!\n", handle); 713 DRM_ERROR("(%d)Handle 0x%x already in use!\n", ip_instance, handle);
691 return -EINVAL; 714 return -EINVAL;
692 } 715 }
693 716
694 if (!atomic_cmpxchg(&adev->uvd.handles[i], 0, handle)) { 717 if (!atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], 0, handle)) {
695 adev->uvd.filp[i] = ctx->parser->filp; 718 adev->uvd.inst[ip_instance].filp[i] = ctx->parser->filp;
696 return 0; 719 return 0;
697 } 720 }
698 } 721 }
699 722
700 DRM_ERROR("No more free UVD handles!\n"); 723 DRM_ERROR("No more free UVD(%d) handles!\n", ip_instance);
701 return -ENOSPC; 724 return -ENOSPC;
702 725
703 case 1: 726 case 1:
@@ -709,27 +732,27 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
709 732
710 /* validate the handle */ 733 /* validate the handle */
711 for (i = 0; i < adev->uvd.max_handles; ++i) { 734 for (i = 0; i < adev->uvd.max_handles; ++i) {
712 if (atomic_read(&adev->uvd.handles[i]) == handle) { 735 if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) {
713 if (adev->uvd.filp[i] != ctx->parser->filp) { 736 if (adev->uvd.inst[ip_instance].filp[i] != ctx->parser->filp) {
714 DRM_ERROR("UVD handle collision detected!\n"); 737 DRM_ERROR("UVD(%d) handle collision detected!\n", ip_instance);
715 return -EINVAL; 738 return -EINVAL;
716 } 739 }
717 return 0; 740 return 0;
718 } 741 }
719 } 742 }
720 743
721 DRM_ERROR("Invalid UVD handle 0x%x!\n", handle); 744 DRM_ERROR("Invalid UVD(%d) handle 0x%x!\n", ip_instance, handle);
722 return -ENOENT; 745 return -ENOENT;
723 746
724 case 2: 747 case 2:
725 /* it's a destroy msg, free the handle */ 748 /* it's a destroy msg, free the handle */
726 for (i = 0; i < adev->uvd.max_handles; ++i) 749 for (i = 0; i < adev->uvd.max_handles; ++i)
727 atomic_cmpxchg(&adev->uvd.handles[i], handle, 0); 750 atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], handle, 0);
728 amdgpu_bo_kunmap(bo); 751 amdgpu_bo_kunmap(bo);
729 return 0; 752 return 0;
730 753
731 default: 754 default:
732 DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); 755 DRM_ERROR("Illegal UVD(%d) message type (%d)!\n", ip_instance, msg_type);
733 return -EINVAL; 756 return -EINVAL;
734 } 757 }
735 BUG(); 758 BUG();
@@ -800,7 +823,7 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx)
800 } 823 }
801 824
802 if ((cmd == 0 || cmd == 0x3) && 825 if ((cmd == 0 || cmd == 0x3) &&
803 (start >> 28) != (ctx->parser->adev->uvd.gpu_addr >> 28)) { 826 (start >> 28) != (ctx->parser->adev->uvd.inst->gpu_addr >> 28)) {
804 DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n", 827 DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n",
805 start, end); 828 start, end);
806 return -EINVAL; 829 return -EINVAL;
@@ -968,6 +991,8 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
968 uint64_t addr; 991 uint64_t addr;
969 long r; 992 long r;
970 int i; 993 int i;
994 unsigned offset_idx = 0;
995 unsigned offset[3] = { UVD_BASE_SI, 0, 0 };
971 996
972 amdgpu_bo_kunmap(bo); 997 amdgpu_bo_kunmap(bo);
973 amdgpu_bo_unpin(bo); 998 amdgpu_bo_unpin(bo);
@@ -987,17 +1012,16 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
987 goto err; 1012 goto err;
988 1013
989 if (adev->asic_type >= CHIP_VEGA10) { 1014 if (adev->asic_type >= CHIP_VEGA10) {
990 data[0] = PACKET0(mmUVD_GPCOM_VCPU_DATA0_VEGA10, 0); 1015 offset_idx = 1 + ring->me;
991 data[1] = PACKET0(mmUVD_GPCOM_VCPU_DATA1_VEGA10, 0); 1016 offset[1] = adev->reg_offset[UVD_HWIP][0][1];
992 data[2] = PACKET0(mmUVD_GPCOM_VCPU_CMD_VEGA10, 0); 1017 offset[2] = adev->reg_offset[UVD_HWIP][1][1];
993 data[3] = PACKET0(mmUVD_NO_OP_VEGA10, 0);
994 } else {
995 data[0] = PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0);
996 data[1] = PACKET0(mmUVD_GPCOM_VCPU_DATA1, 0);
997 data[2] = PACKET0(mmUVD_GPCOM_VCPU_CMD, 0);
998 data[3] = PACKET0(mmUVD_NO_OP, 0);
999 } 1018 }
1000 1019
1020 data[0] = PACKET0(offset[offset_idx] + UVD_GPCOM_VCPU_DATA0, 0);
1021 data[1] = PACKET0(offset[offset_idx] + UVD_GPCOM_VCPU_DATA1, 0);
1022 data[2] = PACKET0(offset[offset_idx] + UVD_GPCOM_VCPU_CMD, 0);
1023 data[3] = PACKET0(offset[offset_idx] + UVD_NO_OP, 0);
1024
1001 ib = &job->ibs[0]; 1025 ib = &job->ibs[0];
1002 addr = amdgpu_bo_gpu_offset(bo); 1026 addr = amdgpu_bo_gpu_offset(bo);
1003 ib->ptr[0] = data[0]; 1027 ib->ptr[0] = data[0];
@@ -1033,7 +1057,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
1033 if (r) 1057 if (r)
1034 goto err_free; 1058 goto err_free;
1035 1059
1036 r = amdgpu_job_submit(job, ring, &adev->uvd.entity, 1060 r = amdgpu_job_submit(job, ring, &adev->uvd.inst[ring->me].entity,
1037 AMDGPU_FENCE_OWNER_UNDEFINED, &f); 1061 AMDGPU_FENCE_OWNER_UNDEFINED, &f);
1038 if (r) 1062 if (r)
1039 goto err_free; 1063 goto err_free;
@@ -1121,8 +1145,15 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
1121static void amdgpu_uvd_idle_work_handler(struct work_struct *work) 1145static void amdgpu_uvd_idle_work_handler(struct work_struct *work)
1122{ 1146{
1123 struct amdgpu_device *adev = 1147 struct amdgpu_device *adev =
1124 container_of(work, struct amdgpu_device, uvd.idle_work.work); 1148 container_of(work, struct amdgpu_device, uvd.inst->idle_work.work);
1125 unsigned fences = amdgpu_fence_count_emitted(&adev->uvd.ring); 1149 unsigned fences = 0, i, j;
1150
1151 for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
1152 fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring);
1153 for (j = 0; j < adev->uvd.num_enc_rings; ++j) {
1154 fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring_enc[j]);
1155 }
1156 }
1126 1157
1127 if (fences == 0) { 1158 if (fences == 0) {
1128 if (adev->pm.dpm_enabled) { 1159 if (adev->pm.dpm_enabled) {
@@ -1136,7 +1167,7 @@ static void amdgpu_uvd_idle_work_handler(struct work_struct *work)
1136 AMD_CG_STATE_GATE); 1167 AMD_CG_STATE_GATE);
1137 } 1168 }
1138 } else { 1169 } else {
1139 schedule_delayed_work(&adev->uvd.idle_work, UVD_IDLE_TIMEOUT); 1170 schedule_delayed_work(&adev->uvd.inst->idle_work, UVD_IDLE_TIMEOUT);
1140 } 1171 }
1141} 1172}
1142 1173
@@ -1148,7 +1179,7 @@ void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring)
1148 if (amdgpu_sriov_vf(adev)) 1179 if (amdgpu_sriov_vf(adev))
1149 return; 1180 return;
1150 1181
1151 set_clocks = !cancel_delayed_work_sync(&adev->uvd.idle_work); 1182 set_clocks = !cancel_delayed_work_sync(&adev->uvd.inst->idle_work);
1152 if (set_clocks) { 1183 if (set_clocks) {
1153 if (adev->pm.dpm_enabled) { 1184 if (adev->pm.dpm_enabled) {
1154 amdgpu_dpm_enable_uvd(adev, true); 1185 amdgpu_dpm_enable_uvd(adev, true);
@@ -1165,7 +1196,7 @@ void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring)
1165void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring) 1196void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring)
1166{ 1197{
1167 if (!amdgpu_sriov_vf(ring->adev)) 1198 if (!amdgpu_sriov_vf(ring->adev))
1168 schedule_delayed_work(&ring->adev->uvd.idle_work, UVD_IDLE_TIMEOUT); 1199 schedule_delayed_work(&ring->adev->uvd.inst->idle_work, UVD_IDLE_TIMEOUT);
1169} 1200}
1170 1201
1171/** 1202/**
@@ -1179,27 +1210,28 @@ int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout)
1179{ 1210{
1180 struct dma_fence *fence; 1211 struct dma_fence *fence;
1181 long r; 1212 long r;
1213 uint32_t ip_instance = ring->me;
1182 1214
1183 r = amdgpu_uvd_get_create_msg(ring, 1, NULL); 1215 r = amdgpu_uvd_get_create_msg(ring, 1, NULL);
1184 if (r) { 1216 if (r) {
1185 DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); 1217 DRM_ERROR("amdgpu: (%d)failed to get create msg (%ld).\n", ip_instance, r);
1186 goto error; 1218 goto error;
1187 } 1219 }
1188 1220
1189 r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); 1221 r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence);
1190 if (r) { 1222 if (r) {
1191 DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); 1223 DRM_ERROR("amdgpu: (%d)failed to get destroy ib (%ld).\n", ip_instance, r);
1192 goto error; 1224 goto error;
1193 } 1225 }
1194 1226
1195 r = dma_fence_wait_timeout(fence, false, timeout); 1227 r = dma_fence_wait_timeout(fence, false, timeout);
1196 if (r == 0) { 1228 if (r == 0) {
1197 DRM_ERROR("amdgpu: IB test timed out.\n"); 1229 DRM_ERROR("amdgpu: (%d)IB test timed out.\n", ip_instance);
1198 r = -ETIMEDOUT; 1230 r = -ETIMEDOUT;
1199 } else if (r < 0) { 1231 } else if (r < 0) {
1200 DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); 1232 DRM_ERROR("amdgpu: (%d)fence wait failed (%ld).\n", ip_instance, r);
1201 } else { 1233 } else {
1202 DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); 1234 DRM_DEBUG("ib test on (%d)ring %d succeeded\n", ip_instance, ring->idx);
1203 r = 0; 1235 r = 0;
1204 } 1236 }
1205 1237
@@ -1227,7 +1259,7 @@ uint32_t amdgpu_uvd_used_handles(struct amdgpu_device *adev)
1227 * necessarily linear. So we need to count 1259 * necessarily linear. So we need to count
1228 * all non-zero handles. 1260 * all non-zero handles.
1229 */ 1261 */
1230 if (atomic_read(&adev->uvd.handles[i])) 1262 if (atomic_read(&adev->uvd.inst->handles[i]))
1231 used_handles++; 1263 used_handles++;
1232 } 1264 }
1233 1265
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
index 32ea20b99e53..b1579fba134c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
@@ -31,30 +31,37 @@
31#define AMDGPU_UVD_SESSION_SIZE (50*1024) 31#define AMDGPU_UVD_SESSION_SIZE (50*1024)
32#define AMDGPU_UVD_FIRMWARE_OFFSET 256 32#define AMDGPU_UVD_FIRMWARE_OFFSET 256
33 33
34#define AMDGPU_MAX_UVD_INSTANCES 2
35
34#define AMDGPU_UVD_FIRMWARE_SIZE(adev) \ 36#define AMDGPU_UVD_FIRMWARE_SIZE(adev) \
35 (AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(((const struct common_firmware_header *)(adev)->uvd.fw->data)->ucode_size_bytes) + \ 37 (AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(((const struct common_firmware_header *)(adev)->uvd.fw->data)->ucode_size_bytes) + \
36 8) - AMDGPU_UVD_FIRMWARE_OFFSET) 38 8) - AMDGPU_UVD_FIRMWARE_OFFSET)
37 39
38struct amdgpu_uvd { 40struct amdgpu_uvd_inst {
39 struct amdgpu_bo *vcpu_bo; 41 struct amdgpu_bo *vcpu_bo;
40 void *cpu_addr; 42 void *cpu_addr;
41 uint64_t gpu_addr; 43 uint64_t gpu_addr;
42 unsigned fw_version;
43 void *saved_bo; 44 void *saved_bo;
44 unsigned max_handles;
45 atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; 45 atomic_t handles[AMDGPU_MAX_UVD_HANDLES];
46 struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; 46 struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES];
47 struct delayed_work idle_work; 47 struct delayed_work idle_work;
48 const struct firmware *fw; /* UVD firmware */
49 struct amdgpu_ring ring; 48 struct amdgpu_ring ring;
50 struct amdgpu_ring ring_enc[AMDGPU_MAX_UVD_ENC_RINGS]; 49 struct amdgpu_ring ring_enc[AMDGPU_MAX_UVD_ENC_RINGS];
51 struct amdgpu_irq_src irq; 50 struct amdgpu_irq_src irq;
52 bool address_64_bit;
53 bool use_ctx_buf;
54 struct drm_sched_entity entity; 51 struct drm_sched_entity entity;
55 struct drm_sched_entity entity_enc; 52 struct drm_sched_entity entity_enc;
56 uint32_t srbm_soft_reset; 53 uint32_t srbm_soft_reset;
54};
55
56struct amdgpu_uvd {
57 const struct firmware *fw; /* UVD firmware */
58 unsigned fw_version;
59 unsigned max_handles;
57 unsigned num_enc_rings; 60 unsigned num_enc_rings;
61 uint8_t num_uvd_inst;
62 bool address_64_bit;
63 bool use_ctx_buf;
64 struct amdgpu_uvd_inst inst[AMDGPU_MAX_UVD_INSTANCES];
58}; 65};
59 66
60int amdgpu_uvd_sw_init(struct amdgpu_device *adev); 67int amdgpu_uvd_sw_init(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index a33804bd3314..23d960ec1cf2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -51,11 +51,13 @@
51#define FIRMWARE_FIJI "amdgpu/fiji_vce.bin" 51#define FIRMWARE_FIJI "amdgpu/fiji_vce.bin"
52#define FIRMWARE_STONEY "amdgpu/stoney_vce.bin" 52#define FIRMWARE_STONEY "amdgpu/stoney_vce.bin"
53#define FIRMWARE_POLARIS10 "amdgpu/polaris10_vce.bin" 53#define FIRMWARE_POLARIS10 "amdgpu/polaris10_vce.bin"
54#define FIRMWARE_POLARIS11 "amdgpu/polaris11_vce.bin" 54#define FIRMWARE_POLARIS11 "amdgpu/polaris11_vce.bin"
55#define FIRMWARE_POLARIS12 "amdgpu/polaris12_vce.bin" 55#define FIRMWARE_POLARIS12 "amdgpu/polaris12_vce.bin"
56#define FIRMWARE_VEGAM "amdgpu/vegam_vce.bin"
56 57
57#define FIRMWARE_VEGA10 "amdgpu/vega10_vce.bin" 58#define FIRMWARE_VEGA10 "amdgpu/vega10_vce.bin"
58#define FIRMWARE_VEGA12 "amdgpu/vega12_vce.bin" 59#define FIRMWARE_VEGA12 "amdgpu/vega12_vce.bin"
60#define FIRMWARE_VEGA20 "amdgpu/vega20_vce.bin"
59 61
60#ifdef CONFIG_DRM_AMDGPU_CIK 62#ifdef CONFIG_DRM_AMDGPU_CIK
61MODULE_FIRMWARE(FIRMWARE_BONAIRE); 63MODULE_FIRMWARE(FIRMWARE_BONAIRE);
@@ -71,9 +73,11 @@ MODULE_FIRMWARE(FIRMWARE_STONEY);
71MODULE_FIRMWARE(FIRMWARE_POLARIS10); 73MODULE_FIRMWARE(FIRMWARE_POLARIS10);
72MODULE_FIRMWARE(FIRMWARE_POLARIS11); 74MODULE_FIRMWARE(FIRMWARE_POLARIS11);
73MODULE_FIRMWARE(FIRMWARE_POLARIS12); 75MODULE_FIRMWARE(FIRMWARE_POLARIS12);
76MODULE_FIRMWARE(FIRMWARE_VEGAM);
74 77
75MODULE_FIRMWARE(FIRMWARE_VEGA10); 78MODULE_FIRMWARE(FIRMWARE_VEGA10);
76MODULE_FIRMWARE(FIRMWARE_VEGA12); 79MODULE_FIRMWARE(FIRMWARE_VEGA12);
80MODULE_FIRMWARE(FIRMWARE_VEGA20);
77 81
78static void amdgpu_vce_idle_work_handler(struct work_struct *work); 82static void amdgpu_vce_idle_work_handler(struct work_struct *work);
79 83
@@ -132,12 +136,18 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
132 case CHIP_POLARIS12: 136 case CHIP_POLARIS12:
133 fw_name = FIRMWARE_POLARIS12; 137 fw_name = FIRMWARE_POLARIS12;
134 break; 138 break;
139 case CHIP_VEGAM:
140 fw_name = FIRMWARE_VEGAM;
141 break;
135 case CHIP_VEGA10: 142 case CHIP_VEGA10:
136 fw_name = FIRMWARE_VEGA10; 143 fw_name = FIRMWARE_VEGA10;
137 break; 144 break;
138 case CHIP_VEGA12: 145 case CHIP_VEGA12:
139 fw_name = FIRMWARE_VEGA12; 146 fw_name = FIRMWARE_VEGA12;
140 break; 147 break;
148 case CHIP_VEGA20:
149 fw_name = FIRMWARE_VEGA20;
150 break;
141 151
142 default: 152 default:
143 return -EINVAL; 153 return -EINVAL;
@@ -181,7 +191,7 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
181 ring = &adev->vce.ring[0]; 191 ring = &adev->vce.ring[0];
182 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 192 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL];
183 r = drm_sched_entity_init(&ring->sched, &adev->vce.entity, 193 r = drm_sched_entity_init(&ring->sched, &adev->vce.entity,
184 rq, amdgpu_sched_jobs, NULL); 194 rq, NULL);
185 if (r != 0) { 195 if (r != 0) {
186 DRM_ERROR("Failed setting up VCE run queue.\n"); 196 DRM_ERROR("Failed setting up VCE run queue.\n");
187 return r; 197 return r;
@@ -755,6 +765,18 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
755 if (r) 765 if (r)
756 goto out; 766 goto out;
757 break; 767 break;
768
769 case 0x0500000d: /* MV buffer */
770 r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3,
771 idx + 2, 0, 0);
772 if (r)
773 goto out;
774
775 r = amdgpu_vce_validate_bo(p, ib_idx, idx + 8,
776 idx + 7, 0, 0);
777 if (r)
778 goto out;
779 break;
758 } 780 }
759 781
760 idx += len / 4; 782 idx += len / 4;
@@ -860,6 +882,18 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
860 goto out; 882 goto out;
861 break; 883 break;
862 884
885 case 0x0500000d: /* MV buffer */
886 r = amdgpu_vce_cs_reloc(p, ib_idx, idx + 3,
887 idx + 2, *size, 0);
888 if (r)
889 goto out;
890
891 r = amdgpu_vce_cs_reloc(p, ib_idx, idx + 8,
892 idx + 7, *size / 12, 0);
893 if (r)
894 goto out;
895 break;
896
863 default: 897 default:
864 DRM_ERROR("invalid VCE command (0x%x)!\n", cmd); 898 DRM_ERROR("invalid VCE command (0x%x)!\n", cmd);
865 r = -EINVAL; 899 r = -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index 58e495330b38..8851bcdfc260 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -105,7 +105,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
105 ring = &adev->vcn.ring_dec; 105 ring = &adev->vcn.ring_dec;
106 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 106 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL];
107 r = drm_sched_entity_init(&ring->sched, &adev->vcn.entity_dec, 107 r = drm_sched_entity_init(&ring->sched, &adev->vcn.entity_dec,
108 rq, amdgpu_sched_jobs, NULL); 108 rq, NULL);
109 if (r != 0) { 109 if (r != 0) {
110 DRM_ERROR("Failed setting up VCN dec run queue.\n"); 110 DRM_ERROR("Failed setting up VCN dec run queue.\n");
111 return r; 111 return r;
@@ -114,7 +114,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
114 ring = &adev->vcn.ring_enc[0]; 114 ring = &adev->vcn.ring_enc[0];
115 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 115 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL];
116 r = drm_sched_entity_init(&ring->sched, &adev->vcn.entity_enc, 116 r = drm_sched_entity_init(&ring->sched, &adev->vcn.entity_enc,
117 rq, amdgpu_sched_jobs, NULL); 117 rq, NULL);
118 if (r != 0) { 118 if (r != 0) {
119 DRM_ERROR("Failed setting up VCN enc run queue.\n"); 119 DRM_ERROR("Failed setting up VCN enc run queue.\n");
120 return r; 120 return r;
@@ -205,13 +205,18 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
205 struct amdgpu_device *adev = 205 struct amdgpu_device *adev =
206 container_of(work, struct amdgpu_device, vcn.idle_work.work); 206 container_of(work, struct amdgpu_device, vcn.idle_work.work);
207 unsigned fences = amdgpu_fence_count_emitted(&adev->vcn.ring_dec); 207 unsigned fences = amdgpu_fence_count_emitted(&adev->vcn.ring_dec);
208 unsigned i;
209
210 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
211 fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]);
212 }
208 213
209 if (fences == 0) { 214 if (fences == 0) {
210 if (adev->pm.dpm_enabled) { 215 if (adev->pm.dpm_enabled)
211 /* might be used when with pg/cg
212 amdgpu_dpm_enable_uvd(adev, false); 216 amdgpu_dpm_enable_uvd(adev, false);
213 */ 217 else
214 } 218 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
219 AMD_PG_STATE_GATE);
215 } else { 220 } else {
216 schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT); 221 schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
217 } 222 }
@@ -223,9 +228,11 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
223 bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work); 228 bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
224 229
225 if (set_clocks && adev->pm.dpm_enabled) { 230 if (set_clocks && adev->pm.dpm_enabled) {
226 /* might be used when with pg/cg 231 if (adev->pm.dpm_enabled)
227 amdgpu_dpm_enable_uvd(adev, true); 232 amdgpu_dpm_enable_uvd(adev, true);
228 */ 233 else
234 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
235 AMD_PG_STATE_UNGATE);
229 } 236 }
230} 237}
231 238
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
index 2fd7db891689..181e6afa9847 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
@@ -45,6 +45,17 @@
45#define VCN_ENC_CMD_REG_WRITE 0x0000000b 45#define VCN_ENC_CMD_REG_WRITE 0x0000000b
46#define VCN_ENC_CMD_REG_WAIT 0x0000000c 46#define VCN_ENC_CMD_REG_WAIT 0x0000000c
47 47
48enum engine_status_constants {
49 UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON = 0x2AAAA0,
50 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON = 0x00000002,
51 UVD_STATUS__UVD_BUSY = 0x00000004,
52 GB_ADDR_CONFIG_DEFAULT = 0x26010011,
53 UVD_STATUS__IDLE = 0x2,
54 UVD_STATUS__BUSY = 0x5,
55 UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF = 0x1,
56 UVD_STATUS__RBC_BUSY = 0x1,
57};
58
48struct amdgpu_vcn { 59struct amdgpu_vcn {
49 struct amdgpu_bo *vcpu_bo; 60 struct amdgpu_bo *vcpu_bo;
50 void *cpu_addr; 61 void *cpu_addr;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index da55a78d7380..ccba88cc8c54 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -94,6 +94,34 @@ struct amdgpu_prt_cb {
94 struct dma_fence_cb cb; 94 struct dma_fence_cb cb;
95}; 95};
96 96
97static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
98 struct amdgpu_vm *vm,
99 struct amdgpu_bo *bo)
100{
101 base->vm = vm;
102 base->bo = bo;
103 INIT_LIST_HEAD(&base->bo_list);
104 INIT_LIST_HEAD(&base->vm_status);
105
106 if (!bo)
107 return;
108 list_add_tail(&base->bo_list, &bo->va);
109
110 if (bo->tbo.resv != vm->root.base.bo->tbo.resv)
111 return;
112
113 if (bo->preferred_domains &
114 amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type))
115 return;
116
117 /*
118 * we checked all the prerequisites, but it looks like this per vm bo
119 * is currently evicted. add the bo to the evicted list to make sure it
120 * is validated on next vm use to avoid fault.
121 * */
122 list_move_tail(&base->vm_status, &vm->evicted);
123}
124
97/** 125/**
98 * amdgpu_vm_level_shift - return the addr shift for each level 126 * amdgpu_vm_level_shift - return the addr shift for each level
99 * 127 *
@@ -196,24 +224,16 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
196 void *param) 224 void *param)
197{ 225{
198 struct ttm_bo_global *glob = adev->mman.bdev.glob; 226 struct ttm_bo_global *glob = adev->mman.bdev.glob;
199 int r; 227 struct amdgpu_vm_bo_base *bo_base, *tmp;
228 int r = 0;
200 229
201 spin_lock(&vm->status_lock); 230 list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) {
202 while (!list_empty(&vm->evicted)) { 231 struct amdgpu_bo *bo = bo_base->bo;
203 struct amdgpu_vm_bo_base *bo_base;
204 struct amdgpu_bo *bo;
205 232
206 bo_base = list_first_entry(&vm->evicted,
207 struct amdgpu_vm_bo_base,
208 vm_status);
209 spin_unlock(&vm->status_lock);
210
211 bo = bo_base->bo;
212 BUG_ON(!bo);
213 if (bo->parent) { 233 if (bo->parent) {
214 r = validate(param, bo); 234 r = validate(param, bo);
215 if (r) 235 if (r)
216 return r; 236 break;
217 237
218 spin_lock(&glob->lru_lock); 238 spin_lock(&glob->lru_lock);
219 ttm_bo_move_to_lru_tail(&bo->tbo); 239 ttm_bo_move_to_lru_tail(&bo->tbo);
@@ -222,22 +242,29 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
222 spin_unlock(&glob->lru_lock); 242 spin_unlock(&glob->lru_lock);
223 } 243 }
224 244
225 if (bo->tbo.type == ttm_bo_type_kernel && 245 if (bo->tbo.type != ttm_bo_type_kernel) {
226 vm->use_cpu_for_update) { 246 spin_lock(&vm->moved_lock);
227 r = amdgpu_bo_kmap(bo, NULL);
228 if (r)
229 return r;
230 }
231
232 spin_lock(&vm->status_lock);
233 if (bo->tbo.type != ttm_bo_type_kernel)
234 list_move(&bo_base->vm_status, &vm->moved); 247 list_move(&bo_base->vm_status, &vm->moved);
235 else 248 spin_unlock(&vm->moved_lock);
249 } else {
236 list_move(&bo_base->vm_status, &vm->relocated); 250 list_move(&bo_base->vm_status, &vm->relocated);
251 }
237 } 252 }
238 spin_unlock(&vm->status_lock);
239 253
240 return 0; 254 spin_lock(&glob->lru_lock);
255 list_for_each_entry(bo_base, &vm->idle, vm_status) {
256 struct amdgpu_bo *bo = bo_base->bo;
257
258 if (!bo->parent)
259 continue;
260
261 ttm_bo_move_to_lru_tail(&bo->tbo);
262 if (bo->shadow)
263 ttm_bo_move_to_lru_tail(&bo->shadow->tbo);
264 }
265 spin_unlock(&glob->lru_lock);
266
267 return r;
241} 268}
242 269
243/** 270/**
@@ -249,13 +276,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
249 */ 276 */
250bool amdgpu_vm_ready(struct amdgpu_vm *vm) 277bool amdgpu_vm_ready(struct amdgpu_vm *vm)
251{ 278{
252 bool ready; 279 return list_empty(&vm->evicted);
253
254 spin_lock(&vm->status_lock);
255 ready = list_empty(&vm->evicted);
256 spin_unlock(&vm->status_lock);
257
258 return ready;
259} 280}
260 281
261/** 282/**
@@ -412,11 +433,16 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
412 struct amdgpu_bo *pt; 433 struct amdgpu_bo *pt;
413 434
414 if (!entry->base.bo) { 435 if (!entry->base.bo) {
415 r = amdgpu_bo_create(adev, 436 struct amdgpu_bo_param bp;
416 amdgpu_vm_bo_size(adev, level), 437
417 AMDGPU_GPU_PAGE_SIZE, 438 memset(&bp, 0, sizeof(bp));
418 AMDGPU_GEM_DOMAIN_VRAM, flags, 439 bp.size = amdgpu_vm_bo_size(adev, level);
419 ttm_bo_type_kernel, resv, &pt); 440 bp.byte_align = AMDGPU_GPU_PAGE_SIZE;
441 bp.domain = AMDGPU_GEM_DOMAIN_VRAM;
442 bp.flags = flags;
443 bp.type = ttm_bo_type_kernel;
444 bp.resv = resv;
445 r = amdgpu_bo_create(adev, &bp, &pt);
420 if (r) 446 if (r)
421 return r; 447 return r;
422 448
@@ -441,12 +467,8 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
441 */ 467 */
442 pt->parent = amdgpu_bo_ref(parent->base.bo); 468 pt->parent = amdgpu_bo_ref(parent->base.bo);
443 469
444 entry->base.vm = vm; 470 amdgpu_vm_bo_base_init(&entry->base, vm, pt);
445 entry->base.bo = pt; 471 list_move(&entry->base.vm_status, &vm->relocated);
446 list_add_tail(&entry->base.bo_list, &pt->va);
447 spin_lock(&vm->status_lock);
448 list_add(&entry->base.vm_status, &vm->relocated);
449 spin_unlock(&vm->status_lock);
450 } 472 }
451 473
452 if (level < AMDGPU_VM_PTB) { 474 if (level < AMDGPU_VM_PTB) {
@@ -628,7 +650,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
628 amdgpu_gmc_emit_pasid_mapping(ring, job->vmid, job->pasid); 650 amdgpu_gmc_emit_pasid_mapping(ring, job->vmid, job->pasid);
629 651
630 if (vm_flush_needed || pasid_mapping_needed) { 652 if (vm_flush_needed || pasid_mapping_needed) {
631 r = amdgpu_fence_emit(ring, &fence); 653 r = amdgpu_fence_emit(ring, &fence, 0);
632 if (r) 654 if (r)
633 return r; 655 return r;
634 } 656 }
@@ -893,10 +915,8 @@ static void amdgpu_vm_invalidate_level(struct amdgpu_device *adev,
893 if (!entry->base.bo) 915 if (!entry->base.bo)
894 continue; 916 continue;
895 917
896 spin_lock(&vm->status_lock); 918 if (!entry->base.moved)
897 if (list_empty(&entry->base.vm_status)) 919 list_move(&entry->base.vm_status, &vm->relocated);
898 list_add(&entry->base.vm_status, &vm->relocated);
899 spin_unlock(&vm->status_lock);
900 amdgpu_vm_invalidate_level(adev, vm, entry, level + 1); 920 amdgpu_vm_invalidate_level(adev, vm, entry, level + 1);
901 } 921 }
902} 922}
@@ -926,6 +946,14 @@ restart:
926 params.adev = adev; 946 params.adev = adev;
927 947
928 if (vm->use_cpu_for_update) { 948 if (vm->use_cpu_for_update) {
949 struct amdgpu_vm_bo_base *bo_base;
950
951 list_for_each_entry(bo_base, &vm->relocated, vm_status) {
952 r = amdgpu_bo_kmap(bo_base->bo, NULL);
953 if (unlikely(r))
954 return r;
955 }
956
929 r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM); 957 r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM);
930 if (unlikely(r)) 958 if (unlikely(r))
931 return r; 959 return r;
@@ -941,7 +969,6 @@ restart:
941 params.func = amdgpu_vm_do_set_ptes; 969 params.func = amdgpu_vm_do_set_ptes;
942 } 970 }
943 971
944 spin_lock(&vm->status_lock);
945 while (!list_empty(&vm->relocated)) { 972 while (!list_empty(&vm->relocated)) {
946 struct amdgpu_vm_bo_base *bo_base, *parent; 973 struct amdgpu_vm_bo_base *bo_base, *parent;
947 struct amdgpu_vm_pt *pt, *entry; 974 struct amdgpu_vm_pt *pt, *entry;
@@ -950,14 +977,12 @@ restart:
950 bo_base = list_first_entry(&vm->relocated, 977 bo_base = list_first_entry(&vm->relocated,
951 struct amdgpu_vm_bo_base, 978 struct amdgpu_vm_bo_base,
952 vm_status); 979 vm_status);
953 list_del_init(&bo_base->vm_status); 980 bo_base->moved = false;
954 spin_unlock(&vm->status_lock); 981 list_move(&bo_base->vm_status, &vm->idle);
955 982
956 bo = bo_base->bo->parent; 983 bo = bo_base->bo->parent;
957 if (!bo) { 984 if (!bo)
958 spin_lock(&vm->status_lock);
959 continue; 985 continue;
960 }
961 986
962 parent = list_first_entry(&bo->va, struct amdgpu_vm_bo_base, 987 parent = list_first_entry(&bo->va, struct amdgpu_vm_bo_base,
963 bo_list); 988 bo_list);
@@ -966,12 +991,10 @@ restart:
966 991
967 amdgpu_vm_update_pde(&params, vm, pt, entry); 992 amdgpu_vm_update_pde(&params, vm, pt, entry);
968 993
969 spin_lock(&vm->status_lock);
970 if (!vm->use_cpu_for_update && 994 if (!vm->use_cpu_for_update &&
971 (ndw - params.ib->length_dw) < 32) 995 (ndw - params.ib->length_dw) < 32)
972 break; 996 break;
973 } 997 }
974 spin_unlock(&vm->status_lock);
975 998
976 if (vm->use_cpu_for_update) { 999 if (vm->use_cpu_for_update) {
977 /* Flush HDP */ 1000 /* Flush HDP */
@@ -1074,9 +1097,7 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p,
1074 if (entry->huge) { 1097 if (entry->huge) {
1075 /* Add the entry to the relocated list to update it. */ 1098 /* Add the entry to the relocated list to update it. */
1076 entry->huge = false; 1099 entry->huge = false;
1077 spin_lock(&p->vm->status_lock);
1078 list_move(&entry->base.vm_status, &p->vm->relocated); 1100 list_move(&entry->base.vm_status, &p->vm->relocated);
1079 spin_unlock(&p->vm->status_lock);
1080 } 1101 }
1081 return; 1102 return;
1082 } 1103 }
@@ -1555,9 +1576,22 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
1555 amdgpu_asic_flush_hdp(adev, NULL); 1576 amdgpu_asic_flush_hdp(adev, NULL);
1556 } 1577 }
1557 1578
1558 spin_lock(&vm->status_lock); 1579 spin_lock(&vm->moved_lock);
1559 list_del_init(&bo_va->base.vm_status); 1580 list_del_init(&bo_va->base.vm_status);
1560 spin_unlock(&vm->status_lock); 1581 spin_unlock(&vm->moved_lock);
1582
1583 /* If the BO is not in its preferred location add it back to
1584 * the evicted list so that it gets validated again on the
1585 * next command submission.
1586 */
1587 if (bo && bo->tbo.resv == vm->root.base.bo->tbo.resv) {
1588 uint32_t mem_type = bo->tbo.mem.mem_type;
1589
1590 if (!(bo->preferred_domains & amdgpu_mem_type_to_domain(mem_type)))
1591 list_add_tail(&bo_va->base.vm_status, &vm->evicted);
1592 else
1593 list_add(&bo_va->base.vm_status, &vm->idle);
1594 }
1561 1595
1562 list_splice_init(&bo_va->invalids, &bo_va->valids); 1596 list_splice_init(&bo_va->invalids, &bo_va->valids);
1563 bo_va->cleared = clear; 1597 bo_va->cleared = clear;
@@ -1766,19 +1800,18 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
1766int amdgpu_vm_handle_moved(struct amdgpu_device *adev, 1800int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
1767 struct amdgpu_vm *vm) 1801 struct amdgpu_vm *vm)
1768{ 1802{
1803 struct amdgpu_bo_va *bo_va, *tmp;
1804 struct list_head moved;
1769 bool clear; 1805 bool clear;
1770 int r = 0; 1806 int r;
1771
1772 spin_lock(&vm->status_lock);
1773 while (!list_empty(&vm->moved)) {
1774 struct amdgpu_bo_va *bo_va;
1775 struct reservation_object *resv;
1776 1807
1777 bo_va = list_first_entry(&vm->moved, 1808 INIT_LIST_HEAD(&moved);
1778 struct amdgpu_bo_va, base.vm_status); 1809 spin_lock(&vm->moved_lock);
1779 spin_unlock(&vm->status_lock); 1810 list_splice_init(&vm->moved, &moved);
1811 spin_unlock(&vm->moved_lock);
1780 1812
1781 resv = bo_va->base.bo->tbo.resv; 1813 list_for_each_entry_safe(bo_va, tmp, &moved, base.vm_status) {
1814 struct reservation_object *resv = bo_va->base.bo->tbo.resv;
1782 1815
1783 /* Per VM BOs never need to bo cleared in the page tables */ 1816 /* Per VM BOs never need to bo cleared in the page tables */
1784 if (resv == vm->root.base.bo->tbo.resv) 1817 if (resv == vm->root.base.bo->tbo.resv)
@@ -1791,17 +1824,19 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
1791 clear = true; 1824 clear = true;
1792 1825
1793 r = amdgpu_vm_bo_update(adev, bo_va, clear); 1826 r = amdgpu_vm_bo_update(adev, bo_va, clear);
1794 if (r) 1827 if (r) {
1828 spin_lock(&vm->moved_lock);
1829 list_splice(&moved, &vm->moved);
1830 spin_unlock(&vm->moved_lock);
1795 return r; 1831 return r;
1832 }
1796 1833
1797 if (!clear && resv != vm->root.base.bo->tbo.resv) 1834 if (!clear && resv != vm->root.base.bo->tbo.resv)
1798 reservation_object_unlock(resv); 1835 reservation_object_unlock(resv);
1799 1836
1800 spin_lock(&vm->status_lock);
1801 } 1837 }
1802 spin_unlock(&vm->status_lock);
1803 1838
1804 return r; 1839 return 0;
1805} 1840}
1806 1841
1807/** 1842/**
@@ -1827,36 +1862,12 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
1827 if (bo_va == NULL) { 1862 if (bo_va == NULL) {
1828 return NULL; 1863 return NULL;
1829 } 1864 }
1830 bo_va->base.vm = vm; 1865 amdgpu_vm_bo_base_init(&bo_va->base, vm, bo);
1831 bo_va->base.bo = bo;
1832 INIT_LIST_HEAD(&bo_va->base.bo_list);
1833 INIT_LIST_HEAD(&bo_va->base.vm_status);
1834 1866
1835 bo_va->ref_count = 1; 1867 bo_va->ref_count = 1;
1836 INIT_LIST_HEAD(&bo_va->valids); 1868 INIT_LIST_HEAD(&bo_va->valids);
1837 INIT_LIST_HEAD(&bo_va->invalids); 1869 INIT_LIST_HEAD(&bo_va->invalids);
1838 1870
1839 if (!bo)
1840 return bo_va;
1841
1842 list_add_tail(&bo_va->base.bo_list, &bo->va);
1843
1844 if (bo->tbo.resv != vm->root.base.bo->tbo.resv)
1845 return bo_va;
1846
1847 if (bo->preferred_domains &
1848 amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type))
1849 return bo_va;
1850
1851 /*
1852 * We checked all the prerequisites, but it looks like this per VM BO
1853 * is currently evicted. add the BO to the evicted list to make sure it
1854 * is validated on next VM use to avoid fault.
1855 * */
1856 spin_lock(&vm->status_lock);
1857 list_move_tail(&bo_va->base.vm_status, &vm->evicted);
1858 spin_unlock(&vm->status_lock);
1859
1860 return bo_va; 1871 return bo_va;
1861} 1872}
1862 1873
@@ -1884,11 +1895,11 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
1884 if (mapping->flags & AMDGPU_PTE_PRT) 1895 if (mapping->flags & AMDGPU_PTE_PRT)
1885 amdgpu_vm_prt_get(adev); 1896 amdgpu_vm_prt_get(adev);
1886 1897
1887 if (bo && bo->tbo.resv == vm->root.base.bo->tbo.resv) { 1898 if (bo && bo->tbo.resv == vm->root.base.bo->tbo.resv &&
1888 spin_lock(&vm->status_lock); 1899 !bo_va->base.moved) {
1889 if (list_empty(&bo_va->base.vm_status)) 1900 spin_lock(&vm->moved_lock);
1890 list_add(&bo_va->base.vm_status, &vm->moved); 1901 list_move(&bo_va->base.vm_status, &vm->moved);
1891 spin_unlock(&vm->status_lock); 1902 spin_unlock(&vm->moved_lock);
1892 } 1903 }
1893 trace_amdgpu_vm_bo_map(bo_va, mapping); 1904 trace_amdgpu_vm_bo_map(bo_va, mapping);
1894} 1905}
@@ -2198,9 +2209,9 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
2198 2209
2199 list_del(&bo_va->base.bo_list); 2210 list_del(&bo_va->base.bo_list);
2200 2211
2201 spin_lock(&vm->status_lock); 2212 spin_lock(&vm->moved_lock);
2202 list_del(&bo_va->base.vm_status); 2213 list_del(&bo_va->base.vm_status);
2203 spin_unlock(&vm->status_lock); 2214 spin_unlock(&vm->moved_lock);
2204 2215
2205 list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { 2216 list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
2206 list_del(&mapping->list); 2217 list_del(&mapping->list);
@@ -2234,33 +2245,34 @@ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
2234{ 2245{
2235 struct amdgpu_vm_bo_base *bo_base; 2246 struct amdgpu_vm_bo_base *bo_base;
2236 2247
2248 /* shadow bo doesn't have bo base, its validation needs its parent */
2249 if (bo->parent && bo->parent->shadow == bo)
2250 bo = bo->parent;
2251
2237 list_for_each_entry(bo_base, &bo->va, bo_list) { 2252 list_for_each_entry(bo_base, &bo->va, bo_list) {
2238 struct amdgpu_vm *vm = bo_base->vm; 2253 struct amdgpu_vm *vm = bo_base->vm;
2254 bool was_moved = bo_base->moved;
2239 2255
2240 bo_base->moved = true; 2256 bo_base->moved = true;
2241 if (evicted && bo->tbo.resv == vm->root.base.bo->tbo.resv) { 2257 if (evicted && bo->tbo.resv == vm->root.base.bo->tbo.resv) {
2242 spin_lock(&bo_base->vm->status_lock);
2243 if (bo->tbo.type == ttm_bo_type_kernel) 2258 if (bo->tbo.type == ttm_bo_type_kernel)
2244 list_move(&bo_base->vm_status, &vm->evicted); 2259 list_move(&bo_base->vm_status, &vm->evicted);
2245 else 2260 else
2246 list_move_tail(&bo_base->vm_status, 2261 list_move_tail(&bo_base->vm_status,
2247 &vm->evicted); 2262 &vm->evicted);
2248 spin_unlock(&bo_base->vm->status_lock);
2249 continue; 2263 continue;
2250 } 2264 }
2251 2265
2252 if (bo->tbo.type == ttm_bo_type_kernel) { 2266 if (was_moved)
2253 spin_lock(&bo_base->vm->status_lock);
2254 if (list_empty(&bo_base->vm_status))
2255 list_add(&bo_base->vm_status, &vm->relocated);
2256 spin_unlock(&bo_base->vm->status_lock);
2257 continue; 2267 continue;
2258 }
2259 2268
2260 spin_lock(&bo_base->vm->status_lock); 2269 if (bo->tbo.type == ttm_bo_type_kernel) {
2261 if (list_empty(&bo_base->vm_status)) 2270 list_move(&bo_base->vm_status, &vm->relocated);
2262 list_add(&bo_base->vm_status, &vm->moved); 2271 } else {
2263 spin_unlock(&bo_base->vm->status_lock); 2272 spin_lock(&bo_base->vm->moved_lock);
2273 list_move(&bo_base->vm_status, &vm->moved);
2274 spin_unlock(&bo_base->vm->moved_lock);
2275 }
2264 } 2276 }
2265} 2277}
2266 2278
@@ -2355,6 +2367,8 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
2355int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, 2367int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
2356 int vm_context, unsigned int pasid) 2368 int vm_context, unsigned int pasid)
2357{ 2369{
2370 struct amdgpu_bo_param bp;
2371 struct amdgpu_bo *root;
2358 const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE, 2372 const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE,
2359 AMDGPU_VM_PTE_COUNT(adev) * 8); 2373 AMDGPU_VM_PTE_COUNT(adev) * 8);
2360 unsigned ring_instance; 2374 unsigned ring_instance;
@@ -2367,10 +2381,11 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
2367 vm->va = RB_ROOT_CACHED; 2381 vm->va = RB_ROOT_CACHED;
2368 for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) 2382 for (i = 0; i < AMDGPU_MAX_VMHUBS; i++)
2369 vm->reserved_vmid[i] = NULL; 2383 vm->reserved_vmid[i] = NULL;
2370 spin_lock_init(&vm->status_lock);
2371 INIT_LIST_HEAD(&vm->evicted); 2384 INIT_LIST_HEAD(&vm->evicted);
2372 INIT_LIST_HEAD(&vm->relocated); 2385 INIT_LIST_HEAD(&vm->relocated);
2386 spin_lock_init(&vm->moved_lock);
2373 INIT_LIST_HEAD(&vm->moved); 2387 INIT_LIST_HEAD(&vm->moved);
2388 INIT_LIST_HEAD(&vm->idle);
2374 INIT_LIST_HEAD(&vm->freed); 2389 INIT_LIST_HEAD(&vm->freed);
2375 2390
2376 /* create scheduler entity for page table updates */ 2391 /* create scheduler entity for page table updates */
@@ -2380,7 +2395,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
2380 ring = adev->vm_manager.vm_pte_rings[ring_instance]; 2395 ring = adev->vm_manager.vm_pte_rings[ring_instance];
2381 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_KERNEL]; 2396 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_KERNEL];
2382 r = drm_sched_entity_init(&ring->sched, &vm->entity, 2397 r = drm_sched_entity_init(&ring->sched, &vm->entity,
2383 rq, amdgpu_sched_jobs, NULL); 2398 rq, NULL);
2384 if (r) 2399 if (r)
2385 return r; 2400 return r;
2386 2401
@@ -2409,24 +2424,28 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
2409 flags |= AMDGPU_GEM_CREATE_SHADOW; 2424 flags |= AMDGPU_GEM_CREATE_SHADOW;
2410 2425
2411 size = amdgpu_vm_bo_size(adev, adev->vm_manager.root_level); 2426 size = amdgpu_vm_bo_size(adev, adev->vm_manager.root_level);
2412 r = amdgpu_bo_create(adev, size, align, AMDGPU_GEM_DOMAIN_VRAM, flags, 2427 memset(&bp, 0, sizeof(bp));
2413 ttm_bo_type_kernel, NULL, &vm->root.base.bo); 2428 bp.size = size;
2429 bp.byte_align = align;
2430 bp.domain = AMDGPU_GEM_DOMAIN_VRAM;
2431 bp.flags = flags;
2432 bp.type = ttm_bo_type_kernel;
2433 bp.resv = NULL;
2434 r = amdgpu_bo_create(adev, &bp, &root);
2414 if (r) 2435 if (r)
2415 goto error_free_sched_entity; 2436 goto error_free_sched_entity;
2416 2437
2417 r = amdgpu_bo_reserve(vm->root.base.bo, true); 2438 r = amdgpu_bo_reserve(root, true);
2418 if (r) 2439 if (r)
2419 goto error_free_root; 2440 goto error_free_root;
2420 2441
2421 r = amdgpu_vm_clear_bo(adev, vm, vm->root.base.bo, 2442 r = amdgpu_vm_clear_bo(adev, vm, root,
2422 adev->vm_manager.root_level, 2443 adev->vm_manager.root_level,
2423 vm->pte_support_ats); 2444 vm->pte_support_ats);
2424 if (r) 2445 if (r)
2425 goto error_unreserve; 2446 goto error_unreserve;
2426 2447
2427 vm->root.base.vm = vm; 2448 amdgpu_vm_bo_base_init(&vm->root.base, vm, root);
2428 list_add_tail(&vm->root.base.bo_list, &vm->root.base.bo->va);
2429 list_add_tail(&vm->root.base.vm_status, &vm->evicted);
2430 amdgpu_bo_unreserve(vm->root.base.bo); 2449 amdgpu_bo_unreserve(vm->root.base.bo);
2431 2450
2432 if (pasid) { 2451 if (pasid) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 30f080364c97..061b99a18cb8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -75,11 +75,12 @@ struct amdgpu_bo_list_entry;
75/* PDE Block Fragment Size for VEGA10 */ 75/* PDE Block Fragment Size for VEGA10 */
76#define AMDGPU_PDE_BFS(a) ((uint64_t)a << 59) 76#define AMDGPU_PDE_BFS(a) ((uint64_t)a << 59)
77 77
78/* VEGA10 only */ 78
79/* For GFX9 */
79#define AMDGPU_PTE_MTYPE(a) ((uint64_t)a << 57) 80#define AMDGPU_PTE_MTYPE(a) ((uint64_t)a << 57)
80#define AMDGPU_PTE_MTYPE_MASK AMDGPU_PTE_MTYPE(3ULL) 81#define AMDGPU_PTE_MTYPE_MASK AMDGPU_PTE_MTYPE(3ULL)
81 82
82/* For Raven */ 83#define AMDGPU_MTYPE_NC 0
83#define AMDGPU_MTYPE_CC 2 84#define AMDGPU_MTYPE_CC 2
84 85
85#define AMDGPU_PTE_DEFAULT_ATC (AMDGPU_PTE_SYSTEM \ 86#define AMDGPU_PTE_DEFAULT_ATC (AMDGPU_PTE_SYSTEM \
@@ -167,9 +168,6 @@ struct amdgpu_vm {
167 /* tree of virtual addresses mapped */ 168 /* tree of virtual addresses mapped */
168 struct rb_root_cached va; 169 struct rb_root_cached va;
169 170
170 /* protecting invalidated */
171 spinlock_t status_lock;
172
173 /* BOs who needs a validation */ 171 /* BOs who needs a validation */
174 struct list_head evicted; 172 struct list_head evicted;
175 173
@@ -178,6 +176,10 @@ struct amdgpu_vm {
178 176
179 /* BOs moved, but not yet updated in the PT */ 177 /* BOs moved, but not yet updated in the PT */
180 struct list_head moved; 178 struct list_head moved;
179 spinlock_t moved_lock;
180
181 /* All BOs of this VM not currently in the state machine */
182 struct list_head idle;
181 183
182 /* BO mappings freed, but not yet updated in the PT */ 184 /* BO mappings freed, but not yet updated in the PT */
183 struct list_head freed; 185 struct list_head freed;
@@ -186,9 +188,6 @@ struct amdgpu_vm {
186 struct amdgpu_vm_pt root; 188 struct amdgpu_vm_pt root;
187 struct dma_fence *last_update; 189 struct dma_fence *last_update;
188 190
189 /* protecting freed */
190 spinlock_t freed_lock;
191
192 /* Scheduler entity for page table updates */ 191 /* Scheduler entity for page table updates */
193 struct drm_sched_entity entity; 192 struct drm_sched_entity entity;
194 193
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
index 47ef3e6e7178..a266dcf5daed 100644
--- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
@@ -5903,7 +5903,7 @@ static int ci_dpm_init(struct amdgpu_device *adev)
5903 pi->pcie_dpm_key_disabled = 0; 5903 pi->pcie_dpm_key_disabled = 0;
5904 pi->thermal_sclk_dpm_enabled = 0; 5904 pi->thermal_sclk_dpm_enabled = 0;
5905 5905
5906 if (amdgpu_pp_feature_mask & SCLK_DEEP_SLEEP_MASK) 5906 if (adev->powerplay.pp_feature & PP_SCLK_DEEP_SLEEP_MASK)
5907 pi->caps_sclk_ds = true; 5907 pi->caps_sclk_ds = true;
5908 else 5908 else
5909 pi->caps_sclk_ds = false; 5909 pi->caps_sclk_ds = false;
@@ -6255,7 +6255,7 @@ static int ci_dpm_late_init(void *handle)
6255 int ret; 6255 int ret;
6256 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 6256 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
6257 6257
6258 if (!amdgpu_dpm) 6258 if (!adev->pm.dpm_enabled)
6259 return 0; 6259 return 0;
6260 6260
6261 /* init the sysfs and debugfs files late */ 6261 /* init the sysfs and debugfs files late */
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index 0df22030e713..8ff4c60d1b59 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -1735,6 +1735,12 @@ static void cik_invalidate_hdp(struct amdgpu_device *adev,
1735 } 1735 }
1736} 1736}
1737 1737
1738static bool cik_need_full_reset(struct amdgpu_device *adev)
1739{
1740 /* change this when we support soft reset */
1741 return true;
1742}
1743
1738static const struct amdgpu_asic_funcs cik_asic_funcs = 1744static const struct amdgpu_asic_funcs cik_asic_funcs =
1739{ 1745{
1740 .read_disabled_bios = &cik_read_disabled_bios, 1746 .read_disabled_bios = &cik_read_disabled_bios,
@@ -1748,6 +1754,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =
1748 .get_config_memsize = &cik_get_config_memsize, 1754 .get_config_memsize = &cik_get_config_memsize,
1749 .flush_hdp = &cik_flush_hdp, 1755 .flush_hdp = &cik_flush_hdp,
1750 .invalidate_hdp = &cik_invalidate_hdp, 1756 .invalidate_hdp = &cik_invalidate_hdp,
1757 .need_full_reset = &cik_need_full_reset,
1751}; 1758};
1752 1759
1753static int cik_common_early_init(void *handle) 1760static int cik_common_early_init(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 452f88ea46a2..ada241bfeee9 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -1823,7 +1823,6 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc,
1823 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 1823 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
1824 struct drm_device *dev = crtc->dev; 1824 struct drm_device *dev = crtc->dev;
1825 struct amdgpu_device *adev = dev->dev_private; 1825 struct amdgpu_device *adev = dev->dev_private;
1826 struct amdgpu_framebuffer *amdgpu_fb;
1827 struct drm_framebuffer *target_fb; 1826 struct drm_framebuffer *target_fb;
1828 struct drm_gem_object *obj; 1827 struct drm_gem_object *obj;
1829 struct amdgpu_bo *abo; 1828 struct amdgpu_bo *abo;
@@ -1842,18 +1841,15 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc,
1842 return 0; 1841 return 0;
1843 } 1842 }
1844 1843
1845 if (atomic) { 1844 if (atomic)
1846 amdgpu_fb = to_amdgpu_framebuffer(fb);
1847 target_fb = fb; 1845 target_fb = fb;
1848 } else { 1846 else
1849 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb);
1850 target_fb = crtc->primary->fb; 1847 target_fb = crtc->primary->fb;
1851 }
1852 1848
1853 /* If atomic, assume fb object is pinned & idle & fenced and 1849 /* If atomic, assume fb object is pinned & idle & fenced and
1854 * just update base pointers 1850 * just update base pointers
1855 */ 1851 */
1856 obj = amdgpu_fb->obj; 1852 obj = target_fb->obj[0];
1857 abo = gem_to_amdgpu_bo(obj); 1853 abo = gem_to_amdgpu_bo(obj);
1858 r = amdgpu_bo_reserve(abo, false); 1854 r = amdgpu_bo_reserve(abo, false);
1859 if (unlikely(r != 0)) 1855 if (unlikely(r != 0))
@@ -2043,8 +2039,7 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc,
2043 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0); 2039 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
2044 2040
2045 if (!atomic && fb && fb != crtc->primary->fb) { 2041 if (!atomic && fb && fb != crtc->primary->fb) {
2046 amdgpu_fb = to_amdgpu_framebuffer(fb); 2042 abo = gem_to_amdgpu_bo(fb->obj[0]);
2047 abo = gem_to_amdgpu_bo(amdgpu_fb->obj);
2048 r = amdgpu_bo_reserve(abo, true); 2043 r = amdgpu_bo_reserve(abo, true);
2049 if (unlikely(r != 0)) 2044 if (unlikely(r != 0))
2050 return r; 2045 return r;
@@ -2526,11 +2521,9 @@ static void dce_v10_0_crtc_disable(struct drm_crtc *crtc)
2526 dce_v10_0_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 2521 dce_v10_0_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
2527 if (crtc->primary->fb) { 2522 if (crtc->primary->fb) {
2528 int r; 2523 int r;
2529 struct amdgpu_framebuffer *amdgpu_fb;
2530 struct amdgpu_bo *abo; 2524 struct amdgpu_bo *abo;
2531 2525
2532 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); 2526 abo = gem_to_amdgpu_bo(crtc->primary->fb->obj[0]);
2533 abo = gem_to_amdgpu_bo(amdgpu_fb->obj);
2534 r = amdgpu_bo_reserve(abo, true); 2527 r = amdgpu_bo_reserve(abo, true);
2535 if (unlikely(r)) 2528 if (unlikely(r))
2536 DRM_ERROR("failed to reserve abo before unpin\n"); 2529 DRM_ERROR("failed to reserve abo before unpin\n");
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index a7c1c584a191..a5b96eac3033 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -173,6 +173,7 @@ static void dce_v11_0_init_golden_registers(struct amdgpu_device *adev)
173 ARRAY_SIZE(polaris11_golden_settings_a11)); 173 ARRAY_SIZE(polaris11_golden_settings_a11));
174 break; 174 break;
175 case CHIP_POLARIS10: 175 case CHIP_POLARIS10:
176 case CHIP_VEGAM:
176 amdgpu_device_program_register_sequence(adev, 177 amdgpu_device_program_register_sequence(adev,
177 polaris10_golden_settings_a11, 178 polaris10_golden_settings_a11,
178 ARRAY_SIZE(polaris10_golden_settings_a11)); 179 ARRAY_SIZE(polaris10_golden_settings_a11));
@@ -473,6 +474,7 @@ static int dce_v11_0_get_num_crtc (struct amdgpu_device *adev)
473 num_crtc = 2; 474 num_crtc = 2;
474 break; 475 break;
475 case CHIP_POLARIS10: 476 case CHIP_POLARIS10:
477 case CHIP_VEGAM:
476 num_crtc = 6; 478 num_crtc = 6;
477 break; 479 break;
478 case CHIP_POLARIS11: 480 case CHIP_POLARIS11:
@@ -1445,6 +1447,7 @@ static int dce_v11_0_audio_init(struct amdgpu_device *adev)
1445 adev->mode_info.audio.num_pins = 7; 1447 adev->mode_info.audio.num_pins = 7;
1446 break; 1448 break;
1447 case CHIP_POLARIS10: 1449 case CHIP_POLARIS10:
1450 case CHIP_VEGAM:
1448 adev->mode_info.audio.num_pins = 8; 1451 adev->mode_info.audio.num_pins = 8;
1449 break; 1452 break;
1450 case CHIP_POLARIS11: 1453 case CHIP_POLARIS11:
@@ -1862,7 +1865,6 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc,
1862 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 1865 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
1863 struct drm_device *dev = crtc->dev; 1866 struct drm_device *dev = crtc->dev;
1864 struct amdgpu_device *adev = dev->dev_private; 1867 struct amdgpu_device *adev = dev->dev_private;
1865 struct amdgpu_framebuffer *amdgpu_fb;
1866 struct drm_framebuffer *target_fb; 1868 struct drm_framebuffer *target_fb;
1867 struct drm_gem_object *obj; 1869 struct drm_gem_object *obj;
1868 struct amdgpu_bo *abo; 1870 struct amdgpu_bo *abo;
@@ -1881,18 +1883,15 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc,
1881 return 0; 1883 return 0;
1882 } 1884 }
1883 1885
1884 if (atomic) { 1886 if (atomic)
1885 amdgpu_fb = to_amdgpu_framebuffer(fb);
1886 target_fb = fb; 1887 target_fb = fb;
1887 } else { 1888 else
1888 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb);
1889 target_fb = crtc->primary->fb; 1889 target_fb = crtc->primary->fb;
1890 }
1891 1890
1892 /* If atomic, assume fb object is pinned & idle & fenced and 1891 /* If atomic, assume fb object is pinned & idle & fenced and
1893 * just update base pointers 1892 * just update base pointers
1894 */ 1893 */
1895 obj = amdgpu_fb->obj; 1894 obj = target_fb->obj[0];
1896 abo = gem_to_amdgpu_bo(obj); 1895 abo = gem_to_amdgpu_bo(obj);
1897 r = amdgpu_bo_reserve(abo, false); 1896 r = amdgpu_bo_reserve(abo, false);
1898 if (unlikely(r != 0)) 1897 if (unlikely(r != 0))
@@ -2082,8 +2081,7 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc,
2082 WREG32(mmCRTC_MASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0); 2081 WREG32(mmCRTC_MASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
2083 2082
2084 if (!atomic && fb && fb != crtc->primary->fb) { 2083 if (!atomic && fb && fb != crtc->primary->fb) {
2085 amdgpu_fb = to_amdgpu_framebuffer(fb); 2084 abo = gem_to_amdgpu_bo(fb->obj[0]);
2086 abo = gem_to_amdgpu_bo(amdgpu_fb->obj);
2087 r = amdgpu_bo_reserve(abo, true); 2085 r = amdgpu_bo_reserve(abo, true);
2088 if (unlikely(r != 0)) 2086 if (unlikely(r != 0))
2089 return r; 2087 return r;
@@ -2253,7 +2251,8 @@ static u32 dce_v11_0_pick_pll(struct drm_crtc *crtc)
2253 2251
2254 if ((adev->asic_type == CHIP_POLARIS10) || 2252 if ((adev->asic_type == CHIP_POLARIS10) ||
2255 (adev->asic_type == CHIP_POLARIS11) || 2253 (adev->asic_type == CHIP_POLARIS11) ||
2256 (adev->asic_type == CHIP_POLARIS12)) { 2254 (adev->asic_type == CHIP_POLARIS12) ||
2255 (adev->asic_type == CHIP_VEGAM)) {
2257 struct amdgpu_encoder *amdgpu_encoder = 2256 struct amdgpu_encoder *amdgpu_encoder =
2258 to_amdgpu_encoder(amdgpu_crtc->encoder); 2257 to_amdgpu_encoder(amdgpu_crtc->encoder);
2259 struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv; 2258 struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
@@ -2601,11 +2600,9 @@ static void dce_v11_0_crtc_disable(struct drm_crtc *crtc)
2601 dce_v11_0_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 2600 dce_v11_0_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
2602 if (crtc->primary->fb) { 2601 if (crtc->primary->fb) {
2603 int r; 2602 int r;
2604 struct amdgpu_framebuffer *amdgpu_fb;
2605 struct amdgpu_bo *abo; 2603 struct amdgpu_bo *abo;
2606 2604
2607 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); 2605 abo = gem_to_amdgpu_bo(crtc->primary->fb->obj[0]);
2608 abo = gem_to_amdgpu_bo(amdgpu_fb->obj);
2609 r = amdgpu_bo_reserve(abo, true); 2606 r = amdgpu_bo_reserve(abo, true);
2610 if (unlikely(r)) 2607 if (unlikely(r))
2611 DRM_ERROR("failed to reserve abo before unpin\n"); 2608 DRM_ERROR("failed to reserve abo before unpin\n");
@@ -2673,7 +2670,8 @@ static int dce_v11_0_crtc_mode_set(struct drm_crtc *crtc,
2673 2670
2674 if ((adev->asic_type == CHIP_POLARIS10) || 2671 if ((adev->asic_type == CHIP_POLARIS10) ||
2675 (adev->asic_type == CHIP_POLARIS11) || 2672 (adev->asic_type == CHIP_POLARIS11) ||
2676 (adev->asic_type == CHIP_POLARIS12)) { 2673 (adev->asic_type == CHIP_POLARIS12) ||
2674 (adev->asic_type == CHIP_VEGAM)) {
2677 struct amdgpu_encoder *amdgpu_encoder = 2675 struct amdgpu_encoder *amdgpu_encoder =
2678 to_amdgpu_encoder(amdgpu_crtc->encoder); 2676 to_amdgpu_encoder(amdgpu_crtc->encoder);
2679 int encoder_mode = 2677 int encoder_mode =
@@ -2830,6 +2828,7 @@ static int dce_v11_0_early_init(void *handle)
2830 adev->mode_info.num_dig = 9; 2828 adev->mode_info.num_dig = 9;
2831 break; 2829 break;
2832 case CHIP_POLARIS10: 2830 case CHIP_POLARIS10:
2831 case CHIP_VEGAM:
2833 adev->mode_info.num_hpd = 6; 2832 adev->mode_info.num_hpd = 6;
2834 adev->mode_info.num_dig = 6; 2833 adev->mode_info.num_dig = 6;
2835 break; 2834 break;
@@ -2949,7 +2948,8 @@ static int dce_v11_0_hw_init(void *handle)
2949 amdgpu_atombios_encoder_init_dig(adev); 2948 amdgpu_atombios_encoder_init_dig(adev);
2950 if ((adev->asic_type == CHIP_POLARIS10) || 2949 if ((adev->asic_type == CHIP_POLARIS10) ||
2951 (adev->asic_type == CHIP_POLARIS11) || 2950 (adev->asic_type == CHIP_POLARIS11) ||
2952 (adev->asic_type == CHIP_POLARIS12)) { 2951 (adev->asic_type == CHIP_POLARIS12) ||
2952 (adev->asic_type == CHIP_VEGAM)) {
2953 amdgpu_atombios_crtc_set_dce_clock(adev, adev->clock.default_dispclk, 2953 amdgpu_atombios_crtc_set_dce_clock(adev, adev->clock.default_dispclk,
2954 DCE_CLOCK_TYPE_DISPCLK, ATOM_GCK_DFS); 2954 DCE_CLOCK_TYPE_DISPCLK, ATOM_GCK_DFS);
2955 amdgpu_atombios_crtc_set_dce_clock(adev, 0, 2955 amdgpu_atombios_crtc_set_dce_clock(adev, 0,
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 9f67b7fd3487..394cc1e8fe20 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1780,7 +1780,6 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc,
1780 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 1780 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
1781 struct drm_device *dev = crtc->dev; 1781 struct drm_device *dev = crtc->dev;
1782 struct amdgpu_device *adev = dev->dev_private; 1782 struct amdgpu_device *adev = dev->dev_private;
1783 struct amdgpu_framebuffer *amdgpu_fb;
1784 struct drm_framebuffer *target_fb; 1783 struct drm_framebuffer *target_fb;
1785 struct drm_gem_object *obj; 1784 struct drm_gem_object *obj;
1786 struct amdgpu_bo *abo; 1785 struct amdgpu_bo *abo;
@@ -1798,18 +1797,15 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc,
1798 return 0; 1797 return 0;
1799 } 1798 }
1800 1799
1801 if (atomic) { 1800 if (atomic)
1802 amdgpu_fb = to_amdgpu_framebuffer(fb);
1803 target_fb = fb; 1801 target_fb = fb;
1804 } else { 1802 else
1805 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb);
1806 target_fb = crtc->primary->fb; 1803 target_fb = crtc->primary->fb;
1807 }
1808 1804
1809 /* If atomic, assume fb object is pinned & idle & fenced and 1805 /* If atomic, assume fb object is pinned & idle & fenced and
1810 * just update base pointers 1806 * just update base pointers
1811 */ 1807 */
1812 obj = amdgpu_fb->obj; 1808 obj = target_fb->obj[0];
1813 abo = gem_to_amdgpu_bo(obj); 1809 abo = gem_to_amdgpu_bo(obj);
1814 r = amdgpu_bo_reserve(abo, false); 1810 r = amdgpu_bo_reserve(abo, false);
1815 if (unlikely(r != 0)) 1811 if (unlikely(r != 0))
@@ -1978,8 +1974,7 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc,
1978 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0); 1974 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
1979 1975
1980 if (!atomic && fb && fb != crtc->primary->fb) { 1976 if (!atomic && fb && fb != crtc->primary->fb) {
1981 amdgpu_fb = to_amdgpu_framebuffer(fb); 1977 abo = gem_to_amdgpu_bo(fb->obj[0]);
1982 abo = gem_to_amdgpu_bo(amdgpu_fb->obj);
1983 r = amdgpu_bo_reserve(abo, true); 1978 r = amdgpu_bo_reserve(abo, true);
1984 if (unlikely(r != 0)) 1979 if (unlikely(r != 0))
1985 return r; 1980 return r;
@@ -2414,11 +2409,9 @@ static void dce_v6_0_crtc_disable(struct drm_crtc *crtc)
2414 dce_v6_0_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 2409 dce_v6_0_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
2415 if (crtc->primary->fb) { 2410 if (crtc->primary->fb) {
2416 int r; 2411 int r;
2417 struct amdgpu_framebuffer *amdgpu_fb;
2418 struct amdgpu_bo *abo; 2412 struct amdgpu_bo *abo;
2419 2413
2420 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); 2414 abo = gem_to_amdgpu_bo(crtc->primary->fb->obj[0]);
2421 abo = gem_to_amdgpu_bo(amdgpu_fb->obj);
2422 r = amdgpu_bo_reserve(abo, true); 2415 r = amdgpu_bo_reserve(abo, true);
2423 if (unlikely(r)) 2416 if (unlikely(r))
2424 DRM_ERROR("failed to reserve abo before unpin\n"); 2417 DRM_ERROR("failed to reserve abo before unpin\n");
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index f55422cbd77a..c9b9ab8f1b05 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -1754,7 +1754,6 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
1754 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 1754 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
1755 struct drm_device *dev = crtc->dev; 1755 struct drm_device *dev = crtc->dev;
1756 struct amdgpu_device *adev = dev->dev_private; 1756 struct amdgpu_device *adev = dev->dev_private;
1757 struct amdgpu_framebuffer *amdgpu_fb;
1758 struct drm_framebuffer *target_fb; 1757 struct drm_framebuffer *target_fb;
1759 struct drm_gem_object *obj; 1758 struct drm_gem_object *obj;
1760 struct amdgpu_bo *abo; 1759 struct amdgpu_bo *abo;
@@ -1773,18 +1772,15 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
1773 return 0; 1772 return 0;
1774 } 1773 }
1775 1774
1776 if (atomic) { 1775 if (atomic)
1777 amdgpu_fb = to_amdgpu_framebuffer(fb);
1778 target_fb = fb; 1776 target_fb = fb;
1779 } else { 1777 else
1780 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb);
1781 target_fb = crtc->primary->fb; 1778 target_fb = crtc->primary->fb;
1782 }
1783 1779
1784 /* If atomic, assume fb object is pinned & idle & fenced and 1780 /* If atomic, assume fb object is pinned & idle & fenced and
1785 * just update base pointers 1781 * just update base pointers
1786 */ 1782 */
1787 obj = amdgpu_fb->obj; 1783 obj = target_fb->obj[0];
1788 abo = gem_to_amdgpu_bo(obj); 1784 abo = gem_to_amdgpu_bo(obj);
1789 r = amdgpu_bo_reserve(abo, false); 1785 r = amdgpu_bo_reserve(abo, false);
1790 if (unlikely(r != 0)) 1786 if (unlikely(r != 0))
@@ -1955,8 +1951,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
1955 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0); 1951 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
1956 1952
1957 if (!atomic && fb && fb != crtc->primary->fb) { 1953 if (!atomic && fb && fb != crtc->primary->fb) {
1958 amdgpu_fb = to_amdgpu_framebuffer(fb); 1954 abo = gem_to_amdgpu_bo(fb->obj[0]);
1959 abo = gem_to_amdgpu_bo(amdgpu_fb->obj);
1960 r = amdgpu_bo_reserve(abo, true); 1955 r = amdgpu_bo_reserve(abo, true);
1961 if (unlikely(r != 0)) 1956 if (unlikely(r != 0))
1962 return r; 1957 return r;
@@ -2430,11 +2425,9 @@ static void dce_v8_0_crtc_disable(struct drm_crtc *crtc)
2430 dce_v8_0_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 2425 dce_v8_0_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
2431 if (crtc->primary->fb) { 2426 if (crtc->primary->fb) {
2432 int r; 2427 int r;
2433 struct amdgpu_framebuffer *amdgpu_fb;
2434 struct amdgpu_bo *abo; 2428 struct amdgpu_bo *abo;
2435 2429
2436 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); 2430 abo = gem_to_amdgpu_bo(crtc->primary->fb->obj[0]);
2437 abo = gem_to_amdgpu_bo(amdgpu_fb->obj);
2438 r = amdgpu_bo_reserve(abo, true); 2431 r = amdgpu_bo_reserve(abo, true);
2439 if (unlikely(r)) 2432 if (unlikely(r))
2440 DRM_ERROR("failed to reserve abo before unpin\n"); 2433 DRM_ERROR("failed to reserve abo before unpin\n");
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index b51f05dc9582..dbf2ccd0c744 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -168,11 +168,9 @@ static void dce_virtual_crtc_disable(struct drm_crtc *crtc)
168 dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 168 dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
169 if (crtc->primary->fb) { 169 if (crtc->primary->fb) {
170 int r; 170 int r;
171 struct amdgpu_framebuffer *amdgpu_fb;
172 struct amdgpu_bo *abo; 171 struct amdgpu_bo *abo;
173 172
174 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); 173 abo = gem_to_amdgpu_bo(crtc->primary->fb->obj[0]);
175 abo = gem_to_amdgpu_bo(amdgpu_fb->obj);
176 r = amdgpu_bo_reserve(abo, true); 174 r = amdgpu_bo_reserve(abo, true);
177 if (unlikely(r)) 175 if (unlikely(r))
178 DRM_ERROR("failed to reserve abo before unpin\n"); 176 DRM_ERROR("failed to reserve abo before unpin\n");
@@ -329,7 +327,7 @@ static int dce_virtual_get_modes(struct drm_connector *connector)
329 return 0; 327 return 0;
330} 328}
331 329
332static int dce_virtual_mode_valid(struct drm_connector *connector, 330static enum drm_mode_status dce_virtual_mode_valid(struct drm_connector *connector,
333 struct drm_display_mode *mode) 331 struct drm_display_mode *mode)
334{ 332{
335 return MODE_OK; 333 return MODE_OK;
@@ -462,8 +460,9 @@ static int dce_virtual_hw_init(void *handle)
462 break; 460 break;
463 case CHIP_CARRIZO: 461 case CHIP_CARRIZO:
464 case CHIP_STONEY: 462 case CHIP_STONEY:
465 case CHIP_POLARIS11:
466 case CHIP_POLARIS10: 463 case CHIP_POLARIS10:
464 case CHIP_POLARIS11:
465 case CHIP_VEGAM:
467 dce_v11_0_disable_dce(adev); 466 dce_v11_0_disable_dce(adev);
468 break; 467 break;
469 case CHIP_TOPAZ: 468 case CHIP_TOPAZ:
@@ -474,6 +473,7 @@ static int dce_virtual_hw_init(void *handle)
474 break; 473 break;
475 case CHIP_VEGA10: 474 case CHIP_VEGA10:
476 case CHIP_VEGA12: 475 case CHIP_VEGA12:
476 case CHIP_VEGA20:
477 break; 477 break;
478 default: 478 default:
479 DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type); 479 DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type);
diff --git a/drivers/gpu/drm/amd/amdgpu/df_v1_7.c b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c
new file mode 100644
index 000000000000..9935371db7ce
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#include "amdgpu.h"
24#include "df_v1_7.h"
25
26#include "df/df_1_7_default.h"
27#include "df/df_1_7_offset.h"
28#include "df/df_1_7_sh_mask.h"
29
30static u32 df_v1_7_channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2};
31
32static void df_v1_7_init (struct amdgpu_device *adev)
33{
34}
35
36static void df_v1_7_enable_broadcast_mode(struct amdgpu_device *adev,
37 bool enable)
38{
39 u32 tmp;
40
41 if (enable) {
42 tmp = RREG32_SOC15(DF, 0, mmFabricConfigAccessControl);
43 tmp &= ~FabricConfigAccessControl__CfgRegInstAccEn_MASK;
44 WREG32_SOC15(DF, 0, mmFabricConfigAccessControl, tmp);
45 } else
46 WREG32_SOC15(DF, 0, mmFabricConfigAccessControl,
47 mmFabricConfigAccessControl_DEFAULT);
48}
49
50static u32 df_v1_7_get_fb_channel_number(struct amdgpu_device *adev)
51{
52 u32 tmp;
53
54 tmp = RREG32_SOC15(DF, 0, mmDF_CS_AON0_DramBaseAddress0);
55 tmp &= DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK;
56 tmp >>= DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
57
58 return tmp;
59}
60
61static u32 df_v1_7_get_hbm_channel_number(struct amdgpu_device *adev)
62{
63 int fb_channel_number;
64
65 fb_channel_number = adev->df_funcs->get_fb_channel_number(adev);
66
67 return df_v1_7_channel_number[fb_channel_number];
68}
69
70static void df_v1_7_update_medium_grain_clock_gating(struct amdgpu_device *adev,
71 bool enable)
72{
73 u32 tmp;
74
75 /* Put DF on broadcast mode */
76 adev->df_funcs->enable_broadcast_mode(adev, true);
77
78 if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG)) {
79 tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
80 tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
81 tmp |= DF_V1_7_MGCG_ENABLE_15_CYCLE_DELAY;
82 WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp);
83 } else {
84 tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
85 tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
86 tmp |= DF_V1_7_MGCG_DISABLE;
87 WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp);
88 }
89
90 /* Exit boradcast mode */
91 adev->df_funcs->enable_broadcast_mode(adev, false);
92}
93
94static void df_v1_7_get_clockgating_state(struct amdgpu_device *adev,
95 u32 *flags)
96{
97 u32 tmp;
98
99 /* AMD_CG_SUPPORT_DF_MGCG */
100 tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
101 if (tmp & DF_V1_7_MGCG_ENABLE_15_CYCLE_DELAY)
102 *flags |= AMD_CG_SUPPORT_DF_MGCG;
103}
104
105static void df_v1_7_enable_ecc_force_par_wr_rmw(struct amdgpu_device *adev,
106 bool enable)
107{
108 WREG32_FIELD15(DF, 0, DF_CS_AON0_CoherentSlaveModeCtrlA0,
109 ForceParWrRMW, enable);
110}
111
112const struct amdgpu_df_funcs df_v1_7_funcs = {
113 .init = df_v1_7_init,
114 .enable_broadcast_mode = df_v1_7_enable_broadcast_mode,
115 .get_fb_channel_number = df_v1_7_get_fb_channel_number,
116 .get_hbm_channel_number = df_v1_7_get_hbm_channel_number,
117 .update_medium_grain_clock_gating = df_v1_7_update_medium_grain_clock_gating,
118 .get_clockgating_state = df_v1_7_get_clockgating_state,
119 .enable_ecc_force_par_wr_rmw = df_v1_7_enable_ecc_force_par_wr_rmw,
120};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk104.c b/drivers/gpu/drm/amd/amdgpu/df_v1_7.h
index 780a1d973634..74621104c487 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk104.c
+++ b/drivers/gpu/drm/amd/amdgpu/df_v1_7.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2015 Red Hat Inc. 2 * Copyright 2018 Advanced Micro Devices, Inc.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -19,20 +19,22 @@
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE. 20 * OTHER DEALINGS IN THE SOFTWARE.
21 * 21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */ 22 */
24#include "dmacnv50.h"
25#include "rootnv50.h"
26 23
27#include <nvif/class.h> 24#ifndef __DF_V1_7_H__
25#define __DF_V1_7_H__
28 26
29const struct nv50_disp_dmac_oclass 27#include "soc15_common.h"
30gk104_disp_base_oclass = { 28enum DF_V1_7_MGCG
31 .base.oclass = GK104_DISP_BASE_CHANNEL_DMA, 29{
32 .base.minver = 0, 30 DF_V1_7_MGCG_DISABLE = 0,
33 .base.maxver = 0, 31 DF_V1_7_MGCG_ENABLE_00_CYCLE_DELAY =1,
34 .ctor = nv50_disp_base_new, 32 DF_V1_7_MGCG_ENABLE_01_CYCLE_DELAY =2,
35 .func = &gf119_disp_dmac_func, 33 DF_V1_7_MGCG_ENABLE_15_CYCLE_DELAY =13,
36 .mthd = &gf119_disp_base_chan_mthd, 34 DF_V1_7_MGCG_ENABLE_31_CYCLE_DELAY =14,
37 .chid = 1, 35 DF_V1_7_MGCG_ENABLE_63_CYCLE_DELAY =15
38}; 36};
37
38extern const struct amdgpu_df_funcs df_v1_7_funcs;
39
40#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
new file mode 100644
index 000000000000..60608b3df881
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#include "amdgpu.h"
24#include "df_v3_6.h"
25
26#include "df/df_3_6_default.h"
27#include "df/df_3_6_offset.h"
28#include "df/df_3_6_sh_mask.h"
29
30static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0,
31 16, 32, 0, 0, 0, 2, 4, 8};
32
33static void df_v3_6_init(struct amdgpu_device *adev)
34{
35}
36
37static void df_v3_6_enable_broadcast_mode(struct amdgpu_device *adev,
38 bool enable)
39{
40 u32 tmp;
41
42 if (enable) {
43 tmp = RREG32_SOC15(DF, 0, mmFabricConfigAccessControl);
44 tmp &= ~FabricConfigAccessControl__CfgRegInstAccEn_MASK;
45 WREG32_SOC15(DF, 0, mmFabricConfigAccessControl, tmp);
46 } else
47 WREG32_SOC15(DF, 0, mmFabricConfigAccessControl,
48 mmFabricConfigAccessControl_DEFAULT);
49}
50
51static u32 df_v3_6_get_fb_channel_number(struct amdgpu_device *adev)
52{
53 u32 tmp;
54
55 tmp = RREG32_SOC15(DF, 0, mmDF_CS_UMC_AON0_DramBaseAddress0);
56 tmp &= DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan_MASK;
57 tmp >>= DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
58
59 return tmp;
60}
61
62static u32 df_v3_6_get_hbm_channel_number(struct amdgpu_device *adev)
63{
64 int fb_channel_number;
65
66 fb_channel_number = adev->df_funcs->get_fb_channel_number(adev);
67 if (fb_channel_number > ARRAY_SIZE(df_v3_6_channel_number))
68 fb_channel_number = 0;
69
70 return df_v3_6_channel_number[fb_channel_number];
71}
72
73static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev,
74 bool enable)
75{
76 u32 tmp;
77
78 /* Put DF on broadcast mode */
79 adev->df_funcs->enable_broadcast_mode(adev, true);
80
81 if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG)) {
82 tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
83 tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
84 tmp |= DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY;
85 WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp);
86 } else {
87 tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
88 tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
89 tmp |= DF_V3_6_MGCG_DISABLE;
90 WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp);
91 }
92
93 /* Exit broadcast mode */
94 adev->df_funcs->enable_broadcast_mode(adev, false);
95}
96
97static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev,
98 u32 *flags)
99{
100 u32 tmp;
101
102 /* AMD_CG_SUPPORT_DF_MGCG */
103 tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
104 if (tmp & DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY)
105 *flags |= AMD_CG_SUPPORT_DF_MGCG;
106}
107
108const struct amdgpu_df_funcs df_v3_6_funcs = {
109 .init = df_v3_6_init,
110 .enable_broadcast_mode = df_v3_6_enable_broadcast_mode,
111 .get_fb_channel_number = df_v3_6_get_fb_channel_number,
112 .get_hbm_channel_number = df_v3_6_get_hbm_channel_number,
113 .update_medium_grain_clock_gating =
114 df_v3_6_update_medium_grain_clock_gating,
115 .get_clockgating_state = df_v3_6_get_clockgating_state,
116};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk110.c b/drivers/gpu/drm/amd/amdgpu/df_v3_6.h
index d8bdd246c8ed..e79c58e5efcb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk110.c
+++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2015 Red Hat Inc. 2 * Copyright 2018 Advanced Micro Devices, Inc.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -19,20 +19,22 @@
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE. 20 * OTHER DEALINGS IN THE SOFTWARE.
21 * 21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */ 22 */
24#include "dmacnv50.h"
25#include "rootnv50.h"
26 23
27#include <nvif/class.h> 24#ifndef __DF_V3_6_H__
25#define __DF_V3_6_H__
28 26
29const struct nv50_disp_dmac_oclass 27#include "soc15_common.h"
30gk110_disp_base_oclass = { 28
31 .base.oclass = GK110_DISP_BASE_CHANNEL_DMA, 29enum DF_V3_6_MGCG {
32 .base.minver = 0, 30 DF_V3_6_MGCG_DISABLE = 0,
33 .base.maxver = 0, 31 DF_V3_6_MGCG_ENABLE_00_CYCLE_DELAY = 1,
34 .ctor = nv50_disp_base_new, 32 DF_V3_6_MGCG_ENABLE_01_CYCLE_DELAY = 2,
35 .func = &gf119_disp_dmac_func, 33 DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY = 13,
36 .mthd = &gf119_disp_base_chan_mthd, 34 DF_V3_6_MGCG_ENABLE_31_CYCLE_DELAY = 14,
37 .chid = 1, 35 DF_V3_6_MGCG_ENABLE_63_CYCLE_DELAY = 15
38}; 36};
37
38extern const struct amdgpu_df_funcs df_v3_6_funcs;
39
40#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index e14263fca1c9..818874b13c99 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -125,18 +125,6 @@ MODULE_FIRMWARE("amdgpu/fiji_mec.bin");
125MODULE_FIRMWARE("amdgpu/fiji_mec2.bin"); 125MODULE_FIRMWARE("amdgpu/fiji_mec2.bin");
126MODULE_FIRMWARE("amdgpu/fiji_rlc.bin"); 126MODULE_FIRMWARE("amdgpu/fiji_rlc.bin");
127 127
128MODULE_FIRMWARE("amdgpu/polaris11_ce.bin");
129MODULE_FIRMWARE("amdgpu/polaris11_ce_2.bin");
130MODULE_FIRMWARE("amdgpu/polaris11_pfp.bin");
131MODULE_FIRMWARE("amdgpu/polaris11_pfp_2.bin");
132MODULE_FIRMWARE("amdgpu/polaris11_me.bin");
133MODULE_FIRMWARE("amdgpu/polaris11_me_2.bin");
134MODULE_FIRMWARE("amdgpu/polaris11_mec.bin");
135MODULE_FIRMWARE("amdgpu/polaris11_mec_2.bin");
136MODULE_FIRMWARE("amdgpu/polaris11_mec2.bin");
137MODULE_FIRMWARE("amdgpu/polaris11_mec2_2.bin");
138MODULE_FIRMWARE("amdgpu/polaris11_rlc.bin");
139
140MODULE_FIRMWARE("amdgpu/polaris10_ce.bin"); 128MODULE_FIRMWARE("amdgpu/polaris10_ce.bin");
141MODULE_FIRMWARE("amdgpu/polaris10_ce_2.bin"); 129MODULE_FIRMWARE("amdgpu/polaris10_ce_2.bin");
142MODULE_FIRMWARE("amdgpu/polaris10_pfp.bin"); 130MODULE_FIRMWARE("amdgpu/polaris10_pfp.bin");
@@ -149,6 +137,18 @@ MODULE_FIRMWARE("amdgpu/polaris10_mec2.bin");
149MODULE_FIRMWARE("amdgpu/polaris10_mec2_2.bin"); 137MODULE_FIRMWARE("amdgpu/polaris10_mec2_2.bin");
150MODULE_FIRMWARE("amdgpu/polaris10_rlc.bin"); 138MODULE_FIRMWARE("amdgpu/polaris10_rlc.bin");
151 139
140MODULE_FIRMWARE("amdgpu/polaris11_ce.bin");
141MODULE_FIRMWARE("amdgpu/polaris11_ce_2.bin");
142MODULE_FIRMWARE("amdgpu/polaris11_pfp.bin");
143MODULE_FIRMWARE("amdgpu/polaris11_pfp_2.bin");
144MODULE_FIRMWARE("amdgpu/polaris11_me.bin");
145MODULE_FIRMWARE("amdgpu/polaris11_me_2.bin");
146MODULE_FIRMWARE("amdgpu/polaris11_mec.bin");
147MODULE_FIRMWARE("amdgpu/polaris11_mec_2.bin");
148MODULE_FIRMWARE("amdgpu/polaris11_mec2.bin");
149MODULE_FIRMWARE("amdgpu/polaris11_mec2_2.bin");
150MODULE_FIRMWARE("amdgpu/polaris11_rlc.bin");
151
152MODULE_FIRMWARE("amdgpu/polaris12_ce.bin"); 152MODULE_FIRMWARE("amdgpu/polaris12_ce.bin");
153MODULE_FIRMWARE("amdgpu/polaris12_ce_2.bin"); 153MODULE_FIRMWARE("amdgpu/polaris12_ce_2.bin");
154MODULE_FIRMWARE("amdgpu/polaris12_pfp.bin"); 154MODULE_FIRMWARE("amdgpu/polaris12_pfp.bin");
@@ -161,6 +161,13 @@ MODULE_FIRMWARE("amdgpu/polaris12_mec2.bin");
161MODULE_FIRMWARE("amdgpu/polaris12_mec2_2.bin"); 161MODULE_FIRMWARE("amdgpu/polaris12_mec2_2.bin");
162MODULE_FIRMWARE("amdgpu/polaris12_rlc.bin"); 162MODULE_FIRMWARE("amdgpu/polaris12_rlc.bin");
163 163
164MODULE_FIRMWARE("amdgpu/vegam_ce.bin");
165MODULE_FIRMWARE("amdgpu/vegam_pfp.bin");
166MODULE_FIRMWARE("amdgpu/vegam_me.bin");
167MODULE_FIRMWARE("amdgpu/vegam_mec.bin");
168MODULE_FIRMWARE("amdgpu/vegam_mec2.bin");
169MODULE_FIRMWARE("amdgpu/vegam_rlc.bin");
170
164static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] = 171static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] =
165{ 172{
166 {mmGDS_VMID0_BASE, mmGDS_VMID0_SIZE, mmGDS_GWS_VMID0, mmGDS_OA_VMID0}, 173 {mmGDS_VMID0_BASE, mmGDS_VMID0_SIZE, mmGDS_GWS_VMID0, mmGDS_OA_VMID0},
@@ -292,6 +299,37 @@ static const u32 tonga_mgcg_cgcg_init[] =
292 mmCP_MEM_SLP_CNTL, 0x00000001, 0x00000001, 299 mmCP_MEM_SLP_CNTL, 0x00000001, 0x00000001,
293}; 300};
294 301
302static const u32 golden_settings_vegam_a11[] =
303{
304 mmCB_HW_CONTROL, 0x0001f3cf, 0x00007208,
305 mmCB_HW_CONTROL_2, 0x0f000000, 0x0d000000,
306 mmCB_HW_CONTROL_3, 0x000001ff, 0x00000040,
307 mmDB_DEBUG2, 0xf00fffff, 0x00000400,
308 mmPA_SC_ENHANCE, 0xffffffff, 0x20000001,
309 mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000,
310 mmPA_SC_RASTER_CONFIG, 0x3f3fffff, 0x3a00161a,
311 mmPA_SC_RASTER_CONFIG_1, 0x0000003f, 0x0000002e,
312 mmRLC_CGCG_CGLS_CTRL, 0x00000003, 0x0001003c,
313 mmRLC_CGCG_CGLS_CTRL_3D, 0xffffffff, 0x0001003c,
314 mmSQ_CONFIG, 0x07f80000, 0x01180000,
315 mmTA_CNTL_AUX, 0x000f000f, 0x000b0000,
316 mmTCC_CTRL, 0x00100000, 0xf31fff7f,
317 mmTCP_ADDR_CONFIG, 0x000003ff, 0x000000f7,
318 mmTCP_CHAN_STEER_HI, 0xffffffff, 0x00000000,
319 mmTCP_CHAN_STEER_LO, 0xffffffff, 0x32761054,
320 mmVGT_RESET_DEBUG, 0x00000004, 0x00000004,
321};
322
323static const u32 vegam_golden_common_all[] =
324{
325 mmGRBM_GFX_INDEX, 0xffffffff, 0xe0000000,
326 mmGB_ADDR_CONFIG, 0xffffffff, 0x22011003,
327 mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
328 mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
329 mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
330 mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF,
331};
332
295static const u32 golden_settings_polaris11_a11[] = 333static const u32 golden_settings_polaris11_a11[] =
296{ 334{
297 mmCB_HW_CONTROL, 0x0000f3cf, 0x00007208, 335 mmCB_HW_CONTROL, 0x0000f3cf, 0x00007208,
@@ -712,6 +750,14 @@ static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev)
712 tonga_golden_common_all, 750 tonga_golden_common_all,
713 ARRAY_SIZE(tonga_golden_common_all)); 751 ARRAY_SIZE(tonga_golden_common_all));
714 break; 752 break;
753 case CHIP_VEGAM:
754 amdgpu_device_program_register_sequence(adev,
755 golden_settings_vegam_a11,
756 ARRAY_SIZE(golden_settings_vegam_a11));
757 amdgpu_device_program_register_sequence(adev,
758 vegam_golden_common_all,
759 ARRAY_SIZE(vegam_golden_common_all));
760 break;
715 case CHIP_POLARIS11: 761 case CHIP_POLARIS11:
716 case CHIP_POLARIS12: 762 case CHIP_POLARIS12:
717 amdgpu_device_program_register_sequence(adev, 763 amdgpu_device_program_register_sequence(adev,
@@ -918,17 +964,20 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev)
918 case CHIP_FIJI: 964 case CHIP_FIJI:
919 chip_name = "fiji"; 965 chip_name = "fiji";
920 break; 966 break;
921 case CHIP_POLARIS11: 967 case CHIP_STONEY:
922 chip_name = "polaris11"; 968 chip_name = "stoney";
923 break; 969 break;
924 case CHIP_POLARIS10: 970 case CHIP_POLARIS10:
925 chip_name = "polaris10"; 971 chip_name = "polaris10";
926 break; 972 break;
973 case CHIP_POLARIS11:
974 chip_name = "polaris11";
975 break;
927 case CHIP_POLARIS12: 976 case CHIP_POLARIS12:
928 chip_name = "polaris12"; 977 chip_name = "polaris12";
929 break; 978 break;
930 case CHIP_STONEY: 979 case CHIP_VEGAM:
931 chip_name = "stoney"; 980 chip_name = "vegam";
932 break; 981 break;
933 default: 982 default:
934 BUG(); 983 BUG();
@@ -1770,6 +1819,7 @@ static int gfx_v8_0_gpu_early_init(struct amdgpu_device *adev)
1770 gb_addr_config = POLARIS11_GB_ADDR_CONFIG_GOLDEN; 1819 gb_addr_config = POLARIS11_GB_ADDR_CONFIG_GOLDEN;
1771 break; 1820 break;
1772 case CHIP_POLARIS10: 1821 case CHIP_POLARIS10:
1822 case CHIP_VEGAM:
1773 ret = amdgpu_atombios_get_gfx_info(adev); 1823 ret = amdgpu_atombios_get_gfx_info(adev);
1774 if (ret) 1824 if (ret)
1775 return ret; 1825 return ret;
@@ -1957,12 +2007,13 @@ static int gfx_v8_0_sw_init(void *handle)
1957 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 2007 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1958 2008
1959 switch (adev->asic_type) { 2009 switch (adev->asic_type) {
1960 case CHIP_FIJI:
1961 case CHIP_TONGA: 2010 case CHIP_TONGA:
2011 case CHIP_CARRIZO:
2012 case CHIP_FIJI:
2013 case CHIP_POLARIS10:
1962 case CHIP_POLARIS11: 2014 case CHIP_POLARIS11:
1963 case CHIP_POLARIS12: 2015 case CHIP_POLARIS12:
1964 case CHIP_POLARIS10: 2016 case CHIP_VEGAM:
1965 case CHIP_CARRIZO:
1966 adev->gfx.mec.num_mec = 2; 2017 adev->gfx.mec.num_mec = 2;
1967 break; 2018 break;
1968 case CHIP_TOPAZ: 2019 case CHIP_TOPAZ:
@@ -2323,6 +2374,7 @@ static void gfx_v8_0_tiling_mode_table_init(struct amdgpu_device *adev)
2323 2374
2324 break; 2375 break;
2325 case CHIP_FIJI: 2376 case CHIP_FIJI:
2377 case CHIP_VEGAM:
2326 modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 2378 modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2327 PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 2379 PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2328 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 2380 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
@@ -3504,6 +3556,7 @@ gfx_v8_0_raster_config(struct amdgpu_device *adev, u32 *rconf, u32 *rconf1)
3504{ 3556{
3505 switch (adev->asic_type) { 3557 switch (adev->asic_type) {
3506 case CHIP_FIJI: 3558 case CHIP_FIJI:
3559 case CHIP_VEGAM:
3507 *rconf |= RB_MAP_PKR0(2) | RB_MAP_PKR1(2) | 3560 *rconf |= RB_MAP_PKR0(2) | RB_MAP_PKR1(2) |
3508 RB_XSEL2(1) | PKR_MAP(2) | 3561 RB_XSEL2(1) | PKR_MAP(2) |
3509 PKR_XSEL(1) | PKR_YSEL(1) | 3562 PKR_XSEL(1) | PKR_YSEL(1) |
@@ -4071,7 +4124,8 @@ static void gfx_v8_0_init_pg(struct amdgpu_device *adev)
4071 gfx_v8_0_init_power_gating(adev); 4124 gfx_v8_0_init_power_gating(adev);
4072 WREG32(mmRLC_PG_ALWAYS_ON_CU_MASK, adev->gfx.cu_info.ao_cu_mask); 4125 WREG32(mmRLC_PG_ALWAYS_ON_CU_MASK, adev->gfx.cu_info.ao_cu_mask);
4073 } else if ((adev->asic_type == CHIP_POLARIS11) || 4126 } else if ((adev->asic_type == CHIP_POLARIS11) ||
4074 (adev->asic_type == CHIP_POLARIS12)) { 4127 (adev->asic_type == CHIP_POLARIS12) ||
4128 (adev->asic_type == CHIP_VEGAM)) {
4075 gfx_v8_0_init_csb(adev); 4129 gfx_v8_0_init_csb(adev);
4076 gfx_v8_0_init_save_restore_list(adev); 4130 gfx_v8_0_init_save_restore_list(adev);
4077 gfx_v8_0_enable_save_restore_machine(adev); 4131 gfx_v8_0_enable_save_restore_machine(adev);
@@ -4146,7 +4200,8 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
4146 WREG32(mmRLC_CGCG_CGLS_CTRL, tmp); 4200 WREG32(mmRLC_CGCG_CGLS_CTRL, tmp);
4147 if (adev->asic_type == CHIP_POLARIS11 || 4201 if (adev->asic_type == CHIP_POLARIS11 ||
4148 adev->asic_type == CHIP_POLARIS10 || 4202 adev->asic_type == CHIP_POLARIS10 ||
4149 adev->asic_type == CHIP_POLARIS12) { 4203 adev->asic_type == CHIP_POLARIS12 ||
4204 adev->asic_type == CHIP_VEGAM) {
4150 tmp = RREG32(mmRLC_CGCG_CGLS_CTRL_3D); 4205 tmp = RREG32(mmRLC_CGCG_CGLS_CTRL_3D);
4151 tmp &= ~0x3; 4206 tmp &= ~0x3;
4152 WREG32(mmRLC_CGCG_CGLS_CTRL_3D, tmp); 4207 WREG32(mmRLC_CGCG_CGLS_CTRL_3D, tmp);
@@ -5498,7 +5553,8 @@ static void gfx_v8_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *ade
5498 bool enable) 5553 bool enable)
5499{ 5554{
5500 if ((adev->asic_type == CHIP_POLARIS11) || 5555 if ((adev->asic_type == CHIP_POLARIS11) ||
5501 (adev->asic_type == CHIP_POLARIS12)) 5556 (adev->asic_type == CHIP_POLARIS12) ||
5557 (adev->asic_type == CHIP_VEGAM))
5502 /* Send msg to SMU via Powerplay */ 5558 /* Send msg to SMU via Powerplay */
5503 amdgpu_device_ip_set_powergating_state(adev, 5559 amdgpu_device_ip_set_powergating_state(adev,
5504 AMD_IP_BLOCK_TYPE_SMC, 5560 AMD_IP_BLOCK_TYPE_SMC,
@@ -5588,6 +5644,7 @@ static int gfx_v8_0_set_powergating_state(void *handle,
5588 break; 5644 break;
5589 case CHIP_POLARIS11: 5645 case CHIP_POLARIS11:
5590 case CHIP_POLARIS12: 5646 case CHIP_POLARIS12:
5647 case CHIP_VEGAM:
5591 if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) && enable) 5648 if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) && enable)
5592 gfx_v8_0_enable_gfx_static_mg_power_gating(adev, true); 5649 gfx_v8_0_enable_gfx_static_mg_power_gating(adev, true);
5593 else 5650 else
@@ -6154,6 +6211,7 @@ static int gfx_v8_0_set_clockgating_state(void *handle,
6154 case CHIP_POLARIS10: 6211 case CHIP_POLARIS10:
6155 case CHIP_POLARIS11: 6212 case CHIP_POLARIS11:
6156 case CHIP_POLARIS12: 6213 case CHIP_POLARIS12:
6214 case CHIP_VEGAM:
6157 gfx_v8_0_polaris_update_gfx_clock_gating(adev, state); 6215 gfx_v8_0_polaris_update_gfx_clock_gating(adev, state);
6158 break; 6216 break;
6159 default: 6217 default:
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 9d39fd5b1822..d7530fdfaad5 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -27,6 +27,7 @@
27#include "amdgpu_gfx.h" 27#include "amdgpu_gfx.h"
28#include "soc15.h" 28#include "soc15.h"
29#include "soc15d.h" 29#include "soc15d.h"
30#include "amdgpu_atomfirmware.h"
30 31
31#include "gc/gc_9_0_offset.h" 32#include "gc/gc_9_0_offset.h"
32#include "gc/gc_9_0_sh_mask.h" 33#include "gc/gc_9_0_sh_mask.h"
@@ -41,7 +42,6 @@
41#define GFX9_MEC_HPD_SIZE 2048 42#define GFX9_MEC_HPD_SIZE 2048
42#define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L 43#define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
43#define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L 44#define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L
44#define GFX9_RLC_FORMAT_DIRECT_REG_LIST_LENGTH 34
45 45
46#define mmPWR_MISC_CNTL_STATUS 0x0183 46#define mmPWR_MISC_CNTL_STATUS 0x0183
47#define mmPWR_MISC_CNTL_STATUS_BASE_IDX 0 47#define mmPWR_MISC_CNTL_STATUS_BASE_IDX 0
@@ -64,6 +64,13 @@ MODULE_FIRMWARE("amdgpu/vega12_mec.bin");
64MODULE_FIRMWARE("amdgpu/vega12_mec2.bin"); 64MODULE_FIRMWARE("amdgpu/vega12_mec2.bin");
65MODULE_FIRMWARE("amdgpu/vega12_rlc.bin"); 65MODULE_FIRMWARE("amdgpu/vega12_rlc.bin");
66 66
67MODULE_FIRMWARE("amdgpu/vega20_ce.bin");
68MODULE_FIRMWARE("amdgpu/vega20_pfp.bin");
69MODULE_FIRMWARE("amdgpu/vega20_me.bin");
70MODULE_FIRMWARE("amdgpu/vega20_mec.bin");
71MODULE_FIRMWARE("amdgpu/vega20_mec2.bin");
72MODULE_FIRMWARE("amdgpu/vega20_rlc.bin");
73
67MODULE_FIRMWARE("amdgpu/raven_ce.bin"); 74MODULE_FIRMWARE("amdgpu/raven_ce.bin");
68MODULE_FIRMWARE("amdgpu/raven_pfp.bin"); 75MODULE_FIRMWARE("amdgpu/raven_pfp.bin");
69MODULE_FIRMWARE("amdgpu/raven_me.bin"); 76MODULE_FIRMWARE("amdgpu/raven_me.bin");
@@ -73,29 +80,22 @@ MODULE_FIRMWARE("amdgpu/raven_rlc.bin");
73 80
74static const struct soc15_reg_golden golden_settings_gc_9_0[] = 81static const struct soc15_reg_golden golden_settings_gc_9_0[] =
75{ 82{
76 SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPC_UTCL1_CNTL, 0x08000000, 0x08000080),
77 SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPF_UTCL1_CNTL, 0x08000000, 0x08000080),
78 SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPG_UTCL1_CNTL, 0x08000000, 0x08000080),
79 SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0xf00fffff, 0x00000420), 83 SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0xf00fffff, 0x00000420),
80 SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_GPU_ID, 0x0000000f, 0x00000000), 84 SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_GPU_ID, 0x0000000f, 0x00000000),
81 SOC15_REG_GOLDEN_VALUE(GC, 0, mmIA_UTCL1_CNTL, 0x08000000, 0x08000080),
82 SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3, 0x00000003, 0x82400024), 85 SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3, 0x00000003, 0x82400024),
83 SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE, 0x3fffffff, 0x00000001), 86 SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE, 0x3fffffff, 0x00000001),
84 SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000), 87 SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000),
85 SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_GPM_UTCL1_CNTL_0, 0x08000000, 0x08000080),
86 SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_GPM_UTCL1_CNTL_1, 0x08000000, 0x08000080),
87 SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_GPM_UTCL1_CNTL_2, 0x08000000, 0x08000080),
88 SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_PREWALKER_UTCL1_CNTL, 0x08000000, 0x08000080),
89 SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_UTCL1_CNTL, 0x08000000, 0x08000080),
90 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSH_MEM_CONFIG, 0x00001000, 0x00001000), 88 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSH_MEM_CONFIG, 0x00001000, 0x00001000),
91 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x0000000f, 0x01000107), 89 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_CU_0, 0x0007ffff, 0x00000800),
90 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_CU_1, 0x0007ffff, 0x00000800),
91 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_EN_CU_0, 0x01ffffff, 0x0000ff87),
92 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_EN_CU_1, 0x01ffffff, 0x0000ff8f),
92 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQC_CONFIG, 0x03000000, 0x020a2000), 93 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQC_CONFIG, 0x03000000, 0x020a2000),
93 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfffffeef, 0x010b0000), 94 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfffffeef, 0x010b0000),
94 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x4a2c0e68), 95 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x4a2c0e68),
95 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0xffffffff, 0xb5d3f197), 96 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0xffffffff, 0xb5d3f197),
96 SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_CACHE_INVALIDATION, 0x3fff3af3, 0x19200000), 97 SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_CACHE_INVALIDATION, 0x3fff3af3, 0x19200000),
97 SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000003ff), 98 SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000003ff)
98 SOC15_REG_GOLDEN_VALUE(GC, 0, mmWD_UTCL1_CNTL, 0x08000000, 0x08000080)
99}; 99};
100 100
101static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] = 101static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] =
@@ -109,6 +109,20 @@ static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] =
109 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x00001800, 0x00000800) 109 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x00001800, 0x00000800)
110}; 110};
111 111
112static const struct soc15_reg_golden golden_settings_gc_9_0_vg20[] =
113{
114 SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_2, 0x0f000000, 0x0a000000),
115 SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_3, 0x30000000, 0x10000000),
116 SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0xf3e777ff, 0x22014042),
117 SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG_READ, 0xf3e777ff, 0x22014042),
118 SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0x00003e00, 0x00000400),
119 SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_1, 0xff840000, 0x04040000),
120 SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_UTCL1_CNTL2, 0x00030000, 0x00030000),
121 SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0xffff010f, 0x01000107),
122 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0x000b0000, 0x000b0000),
123 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x01000000, 0x01000000)
124};
125
112static const struct soc15_reg_golden golden_settings_gc_9_1[] = 126static const struct soc15_reg_golden golden_settings_gc_9_1[] =
113{ 127{
114 SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL, 0xfffdf3cf, 0x00014104), 128 SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL, 0xfffdf3cf, 0x00014104),
@@ -185,6 +199,30 @@ static const struct soc15_reg_golden golden_settings_gc_9_2_1_vg12[] =
185 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x01bd9f33, 0x01000000) 199 SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x01bd9f33, 0x01000000)
186}; 200};
187 201
202static const u32 GFX_RLC_SRM_INDEX_CNTL_ADDR_OFFSETS[] =
203{
204 mmRLC_SRM_INDEX_CNTL_ADDR_0 - mmRLC_SRM_INDEX_CNTL_ADDR_0,
205 mmRLC_SRM_INDEX_CNTL_ADDR_1 - mmRLC_SRM_INDEX_CNTL_ADDR_0,
206 mmRLC_SRM_INDEX_CNTL_ADDR_2 - mmRLC_SRM_INDEX_CNTL_ADDR_0,
207 mmRLC_SRM_INDEX_CNTL_ADDR_3 - mmRLC_SRM_INDEX_CNTL_ADDR_0,
208 mmRLC_SRM_INDEX_CNTL_ADDR_4 - mmRLC_SRM_INDEX_CNTL_ADDR_0,
209 mmRLC_SRM_INDEX_CNTL_ADDR_5 - mmRLC_SRM_INDEX_CNTL_ADDR_0,
210 mmRLC_SRM_INDEX_CNTL_ADDR_6 - mmRLC_SRM_INDEX_CNTL_ADDR_0,
211 mmRLC_SRM_INDEX_CNTL_ADDR_7 - mmRLC_SRM_INDEX_CNTL_ADDR_0,
212};
213
214static const u32 GFX_RLC_SRM_INDEX_CNTL_DATA_OFFSETS[] =
215{
216 mmRLC_SRM_INDEX_CNTL_DATA_0 - mmRLC_SRM_INDEX_CNTL_DATA_0,
217 mmRLC_SRM_INDEX_CNTL_DATA_1 - mmRLC_SRM_INDEX_CNTL_DATA_0,
218 mmRLC_SRM_INDEX_CNTL_DATA_2 - mmRLC_SRM_INDEX_CNTL_DATA_0,
219 mmRLC_SRM_INDEX_CNTL_DATA_3 - mmRLC_SRM_INDEX_CNTL_DATA_0,
220 mmRLC_SRM_INDEX_CNTL_DATA_4 - mmRLC_SRM_INDEX_CNTL_DATA_0,
221 mmRLC_SRM_INDEX_CNTL_DATA_5 - mmRLC_SRM_INDEX_CNTL_DATA_0,
222 mmRLC_SRM_INDEX_CNTL_DATA_6 - mmRLC_SRM_INDEX_CNTL_DATA_0,
223 mmRLC_SRM_INDEX_CNTL_DATA_7 - mmRLC_SRM_INDEX_CNTL_DATA_0,
224};
225
188#define VEGA10_GB_ADDR_CONFIG_GOLDEN 0x2a114042 226#define VEGA10_GB_ADDR_CONFIG_GOLDEN 0x2a114042
189#define VEGA12_GB_ADDR_CONFIG_GOLDEN 0x24104041 227#define VEGA12_GB_ADDR_CONFIG_GOLDEN 0x24104041
190#define RAVEN_GB_ADDR_CONFIG_GOLDEN 0x24000042 228#define RAVEN_GB_ADDR_CONFIG_GOLDEN 0x24000042
@@ -218,6 +256,14 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev)
218 golden_settings_gc_9_2_1_vg12, 256 golden_settings_gc_9_2_1_vg12,
219 ARRAY_SIZE(golden_settings_gc_9_2_1_vg12)); 257 ARRAY_SIZE(golden_settings_gc_9_2_1_vg12));
220 break; 258 break;
259 case CHIP_VEGA20:
260 soc15_program_register_sequence(adev,
261 golden_settings_gc_9_0,
262 ARRAY_SIZE(golden_settings_gc_9_0));
263 soc15_program_register_sequence(adev,
264 golden_settings_gc_9_0_vg20,
265 ARRAY_SIZE(golden_settings_gc_9_0_vg20));
266 break;
221 case CHIP_RAVEN: 267 case CHIP_RAVEN:
222 soc15_program_register_sequence(adev, 268 soc15_program_register_sequence(adev,
223 golden_settings_gc_9_1, 269 golden_settings_gc_9_1,
@@ -401,6 +447,27 @@ static void gfx_v9_0_free_microcode(struct amdgpu_device *adev)
401 kfree(adev->gfx.rlc.register_list_format); 447 kfree(adev->gfx.rlc.register_list_format);
402} 448}
403 449
450static void gfx_v9_0_init_rlc_ext_microcode(struct amdgpu_device *adev)
451{
452 const struct rlc_firmware_header_v2_1 *rlc_hdr;
453
454 rlc_hdr = (const struct rlc_firmware_header_v2_1 *)adev->gfx.rlc_fw->data;
455 adev->gfx.rlc_srlc_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_ucode_ver);
456 adev->gfx.rlc_srlc_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_feature_ver);
457 adev->gfx.rlc.save_restore_list_cntl_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_cntl_size_bytes);
458 adev->gfx.rlc.save_restore_list_cntl = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_cntl_offset_bytes);
459 adev->gfx.rlc_srlg_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_ucode_ver);
460 adev->gfx.rlc_srlg_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_feature_ver);
461 adev->gfx.rlc.save_restore_list_gpm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_gpm_size_bytes);
462 adev->gfx.rlc.save_restore_list_gpm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_gpm_offset_bytes);
463 adev->gfx.rlc_srls_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_ucode_ver);
464 adev->gfx.rlc_srls_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_feature_ver);
465 adev->gfx.rlc.save_restore_list_srm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_srm_size_bytes);
466 adev->gfx.rlc.save_restore_list_srm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_srm_offset_bytes);
467 adev->gfx.rlc.reg_list_format_direct_reg_list_length =
468 le32_to_cpu(rlc_hdr->reg_list_format_direct_reg_list_length);
469}
470
404static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) 471static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
405{ 472{
406 const char *chip_name; 473 const char *chip_name;
@@ -412,6 +479,8 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
412 const struct rlc_firmware_header_v2_0 *rlc_hdr; 479 const struct rlc_firmware_header_v2_0 *rlc_hdr;
413 unsigned int *tmp = NULL; 480 unsigned int *tmp = NULL;
414 unsigned int i = 0; 481 unsigned int i = 0;
482 uint16_t version_major;
483 uint16_t version_minor;
415 484
416 DRM_DEBUG("\n"); 485 DRM_DEBUG("\n");
417 486
@@ -422,6 +491,9 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
422 case CHIP_VEGA12: 491 case CHIP_VEGA12:
423 chip_name = "vega12"; 492 chip_name = "vega12";
424 break; 493 break;
494 case CHIP_VEGA20:
495 chip_name = "vega20";
496 break;
425 case CHIP_RAVEN: 497 case CHIP_RAVEN:
426 chip_name = "raven"; 498 chip_name = "raven";
427 break; 499 break;
@@ -468,6 +540,12 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
468 goto out; 540 goto out;
469 err = amdgpu_ucode_validate(adev->gfx.rlc_fw); 541 err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
470 rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data; 542 rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
543
544 version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
545 version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
546 if (version_major == 2 && version_minor == 1)
547 adev->gfx.rlc.is_rlc_v2_1 = true;
548
471 adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version); 549 adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
472 adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version); 550 adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
473 adev->gfx.rlc.save_and_restore_offset = 551 adev->gfx.rlc.save_and_restore_offset =
@@ -508,6 +586,9 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
508 for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++) 586 for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++)
509 adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]); 587 adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
510 588
589 if (adev->gfx.rlc.is_rlc_v2_1)
590 gfx_v9_0_init_rlc_ext_microcode(adev);
591
511 snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name); 592 snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
512 err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev); 593 err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
513 if (err) 594 if (err)
@@ -566,6 +647,26 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
566 adev->firmware.fw_size += 647 adev->firmware.fw_size +=
567 ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); 648 ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
568 649
650 if (adev->gfx.rlc.is_rlc_v2_1) {
651 info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL];
652 info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL;
653 info->fw = adev->gfx.rlc_fw;
654 adev->firmware.fw_size +=
655 ALIGN(adev->gfx.rlc.save_restore_list_cntl_size_bytes, PAGE_SIZE);
656
657 info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM];
658 info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM;
659 info->fw = adev->gfx.rlc_fw;
660 adev->firmware.fw_size +=
661 ALIGN(adev->gfx.rlc.save_restore_list_gpm_size_bytes, PAGE_SIZE);
662
663 info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM];
664 info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM;
665 info->fw = adev->gfx.rlc_fw;
666 adev->firmware.fw_size +=
667 ALIGN(adev->gfx.rlc.save_restore_list_srm_size_bytes, PAGE_SIZE);
668 }
669
569 info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1]; 670 info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
570 info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1; 671 info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
571 info->fw = adev->gfx.mec_fw; 672 info->fw = adev->gfx.mec_fw;
@@ -1013,9 +1114,10 @@ static const struct amdgpu_gfx_funcs gfx_v9_0_gfx_funcs = {
1013 .select_me_pipe_q = &gfx_v9_0_select_me_pipe_q 1114 .select_me_pipe_q = &gfx_v9_0_select_me_pipe_q
1014}; 1115};
1015 1116
1016static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) 1117static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
1017{ 1118{
1018 u32 gb_addr_config; 1119 u32 gb_addr_config;
1120 int err;
1019 1121
1020 adev->gfx.funcs = &gfx_v9_0_gfx_funcs; 1122 adev->gfx.funcs = &gfx_v9_0_gfx_funcs;
1021 1123
@@ -1037,6 +1139,20 @@ static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
1037 gb_addr_config = VEGA12_GB_ADDR_CONFIG_GOLDEN; 1139 gb_addr_config = VEGA12_GB_ADDR_CONFIG_GOLDEN;
1038 DRM_INFO("fix gfx.config for vega12\n"); 1140 DRM_INFO("fix gfx.config for vega12\n");
1039 break; 1141 break;
1142 case CHIP_VEGA20:
1143 adev->gfx.config.max_hw_contexts = 8;
1144 adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
1145 adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
1146 adev->gfx.config.sc_hiz_tile_fifo_size = 0x30;
1147 adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0;
1148 gb_addr_config = RREG32_SOC15(GC, 0, mmGB_ADDR_CONFIG);
1149 gb_addr_config &= ~0xf3e777ff;
1150 gb_addr_config |= 0x22014042;
1151 /* check vbios table if gpu info is not available */
1152 err = amdgpu_atomfirmware_get_gfx_info(adev);
1153 if (err)
1154 return err;
1155 break;
1040 case CHIP_RAVEN: 1156 case CHIP_RAVEN:
1041 adev->gfx.config.max_hw_contexts = 8; 1157 adev->gfx.config.max_hw_contexts = 8;
1042 adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; 1158 adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
@@ -1086,6 +1202,8 @@ static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
1086 adev->gfx.config.gb_addr_config, 1202 adev->gfx.config.gb_addr_config,
1087 GB_ADDR_CONFIG, 1203 GB_ADDR_CONFIG,
1088 PIPE_INTERLEAVE_SIZE)); 1204 PIPE_INTERLEAVE_SIZE));
1205
1206 return 0;
1089} 1207}
1090 1208
1091static int gfx_v9_0_ngg_create_buf(struct amdgpu_device *adev, 1209static int gfx_v9_0_ngg_create_buf(struct amdgpu_device *adev,
@@ -1319,6 +1437,7 @@ static int gfx_v9_0_sw_init(void *handle)
1319 switch (adev->asic_type) { 1437 switch (adev->asic_type) {
1320 case CHIP_VEGA10: 1438 case CHIP_VEGA10:
1321 case CHIP_VEGA12: 1439 case CHIP_VEGA12:
1440 case CHIP_VEGA20:
1322 case CHIP_RAVEN: 1441 case CHIP_RAVEN:
1323 adev->gfx.mec.num_mec = 2; 1442 adev->gfx.mec.num_mec = 2;
1324 break; 1443 break;
@@ -1446,7 +1565,9 @@ static int gfx_v9_0_sw_init(void *handle)
1446 1565
1447 adev->gfx.ce_ram_size = 0x8000; 1566 adev->gfx.ce_ram_size = 0x8000;
1448 1567
1449 gfx_v9_0_gpu_early_init(adev); 1568 r = gfx_v9_0_gpu_early_init(adev);
1569 if (r)
1570 return r;
1450 1571
1451 r = gfx_v9_0_ngg_init(adev); 1572 r = gfx_v9_0_ngg_init(adev);
1452 if (r) 1573 if (r)
@@ -1600,6 +1721,7 @@ static void gfx_v9_0_gpu_init(struct amdgpu_device *adev)
1600 1721
1601 gfx_v9_0_setup_rb(adev); 1722 gfx_v9_0_setup_rb(adev);
1602 gfx_v9_0_get_cu_info(adev, &adev->gfx.cu_info); 1723 gfx_v9_0_get_cu_info(adev, &adev->gfx.cu_info);
1724 adev->gfx.config.db_debug2 = RREG32_SOC15(GC, 0, mmDB_DEBUG2);
1603 1725
1604 /* XXX SH_MEM regs */ 1726 /* XXX SH_MEM regs */
1605 /* where to put LDS, scratch, GPUVM in FSA64 space */ 1727 /* where to put LDS, scratch, GPUVM in FSA64 space */
@@ -1616,7 +1738,10 @@ static void gfx_v9_0_gpu_init(struct amdgpu_device *adev)
1616 tmp = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE, 1738 tmp = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE,
1617 SH_MEM_ALIGNMENT_MODE_UNALIGNED); 1739 SH_MEM_ALIGNMENT_MODE_UNALIGNED);
1618 WREG32_SOC15(GC, 0, mmSH_MEM_CONFIG, tmp); 1740 WREG32_SOC15(GC, 0, mmSH_MEM_CONFIG, tmp);
1619 tmp = adev->gmc.shared_aperture_start >> 48; 1741 tmp = REG_SET_FIELD(0, SH_MEM_BASES, PRIVATE_BASE,
1742 (adev->gmc.private_aperture_start >> 48));
1743 tmp = REG_SET_FIELD(tmp, SH_MEM_BASES, SHARED_BASE,
1744 (adev->gmc.shared_aperture_start >> 48));
1620 WREG32_SOC15(GC, 0, mmSH_MEM_BASES, tmp); 1745 WREG32_SOC15(GC, 0, mmSH_MEM_BASES, tmp);
1621 } 1746 }
1622 } 1747 }
@@ -1708,55 +1833,42 @@ static void gfx_v9_0_init_csb(struct amdgpu_device *adev)
1708 adev->gfx.rlc.clear_state_size); 1833 adev->gfx.rlc.clear_state_size);
1709} 1834}
1710 1835
1711static void gfx_v9_0_parse_ind_reg_list(int *register_list_format, 1836static void gfx_v9_1_parse_ind_reg_list(int *register_list_format,
1712 int indirect_offset, 1837 int indirect_offset,
1713 int list_size, 1838 int list_size,
1714 int *unique_indirect_regs, 1839 int *unique_indirect_regs,
1715 int *unique_indirect_reg_count, 1840 int *unique_indirect_reg_count,
1716 int max_indirect_reg_count,
1717 int *indirect_start_offsets, 1841 int *indirect_start_offsets,
1718 int *indirect_start_offsets_count, 1842 int *indirect_start_offsets_count)
1719 int max_indirect_start_offsets_count)
1720{ 1843{
1721 int idx; 1844 int idx;
1722 bool new_entry = true;
1723 1845
1724 for (; indirect_offset < list_size; indirect_offset++) { 1846 for (; indirect_offset < list_size; indirect_offset++) {
1847 indirect_start_offsets[*indirect_start_offsets_count] = indirect_offset;
1848 *indirect_start_offsets_count = *indirect_start_offsets_count + 1;
1725 1849
1726 if (new_entry) { 1850 while (register_list_format[indirect_offset] != 0xFFFFFFFF) {
1727 new_entry = false; 1851 indirect_offset += 2;
1728 indirect_start_offsets[*indirect_start_offsets_count] = indirect_offset;
1729 *indirect_start_offsets_count = *indirect_start_offsets_count + 1;
1730 BUG_ON(*indirect_start_offsets_count >= max_indirect_start_offsets_count);
1731 }
1732 1852
1733 if (register_list_format[indirect_offset] == 0xFFFFFFFF) { 1853 /* look for the matching indice */
1734 new_entry = true; 1854 for (idx = 0; idx < *unique_indirect_reg_count; idx++) {
1735 continue; 1855 if (unique_indirect_regs[idx] ==
1736 } 1856 register_list_format[indirect_offset] ||
1857 !unique_indirect_regs[idx])
1858 break;
1859 }
1737 1860
1738 indirect_offset += 2; 1861 BUG_ON(idx >= *unique_indirect_reg_count);
1739 1862
1740 /* look for the matching indice */ 1863 if (!unique_indirect_regs[idx])
1741 for (idx = 0; idx < *unique_indirect_reg_count; idx++) { 1864 unique_indirect_regs[idx] = register_list_format[indirect_offset];
1742 if (unique_indirect_regs[idx] ==
1743 register_list_format[indirect_offset])
1744 break;
1745 }
1746 1865
1747 if (idx >= *unique_indirect_reg_count) { 1866 indirect_offset++;
1748 unique_indirect_regs[*unique_indirect_reg_count] =
1749 register_list_format[indirect_offset];
1750 idx = *unique_indirect_reg_count;
1751 *unique_indirect_reg_count = *unique_indirect_reg_count + 1;
1752 BUG_ON(*unique_indirect_reg_count >= max_indirect_reg_count);
1753 } 1867 }
1754
1755 register_list_format[indirect_offset] = idx;
1756 } 1868 }
1757} 1869}
1758 1870
1759static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev) 1871static int gfx_v9_1_init_rlc_save_restore_list(struct amdgpu_device *adev)
1760{ 1872{
1761 int unique_indirect_regs[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; 1873 int unique_indirect_regs[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1762 int unique_indirect_reg_count = 0; 1874 int unique_indirect_reg_count = 0;
@@ -1765,7 +1877,7 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev)
1765 int indirect_start_offsets_count = 0; 1877 int indirect_start_offsets_count = 0;
1766 1878
1767 int list_size = 0; 1879 int list_size = 0;
1768 int i = 0; 1880 int i = 0, j = 0;
1769 u32 tmp = 0; 1881 u32 tmp = 0;
1770 1882
1771 u32 *register_list_format = 1883 u32 *register_list_format =
@@ -1776,15 +1888,14 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev)
1776 adev->gfx.rlc.reg_list_format_size_bytes); 1888 adev->gfx.rlc.reg_list_format_size_bytes);
1777 1889
1778 /* setup unique_indirect_regs array and indirect_start_offsets array */ 1890 /* setup unique_indirect_regs array and indirect_start_offsets array */
1779 gfx_v9_0_parse_ind_reg_list(register_list_format, 1891 unique_indirect_reg_count = ARRAY_SIZE(unique_indirect_regs);
1780 GFX9_RLC_FORMAT_DIRECT_REG_LIST_LENGTH, 1892 gfx_v9_1_parse_ind_reg_list(register_list_format,
1781 adev->gfx.rlc.reg_list_format_size_bytes >> 2, 1893 adev->gfx.rlc.reg_list_format_direct_reg_list_length,
1782 unique_indirect_regs, 1894 adev->gfx.rlc.reg_list_format_size_bytes >> 2,
1783 &unique_indirect_reg_count, 1895 unique_indirect_regs,
1784 ARRAY_SIZE(unique_indirect_regs), 1896 &unique_indirect_reg_count,
1785 indirect_start_offsets, 1897 indirect_start_offsets,
1786 &indirect_start_offsets_count, 1898 &indirect_start_offsets_count);
1787 ARRAY_SIZE(indirect_start_offsets));
1788 1899
1789 /* enable auto inc in case it is disabled */ 1900 /* enable auto inc in case it is disabled */
1790 tmp = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_CNTL)); 1901 tmp = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_CNTL));
@@ -1798,19 +1909,37 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev)
1798 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_ARAM_DATA), 1909 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_ARAM_DATA),
1799 adev->gfx.rlc.register_restore[i]); 1910 adev->gfx.rlc.register_restore[i]);
1800 1911
1801 /* load direct register */
1802 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_ARAM_ADDR), 0);
1803 for (i = 0; i < adev->gfx.rlc.reg_list_size_bytes >> 2; i++)
1804 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_ARAM_DATA),
1805 adev->gfx.rlc.register_restore[i]);
1806
1807 /* load indirect register */ 1912 /* load indirect register */
1808 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_ADDR), 1913 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_ADDR),
1809 adev->gfx.rlc.reg_list_format_start); 1914 adev->gfx.rlc.reg_list_format_start);
1810 for (i = 0; i < adev->gfx.rlc.reg_list_format_size_bytes >> 2; i++) 1915
1916 /* direct register portion */
1917 for (i = 0; i < adev->gfx.rlc.reg_list_format_direct_reg_list_length; i++)
1811 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_DATA), 1918 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_DATA),
1812 register_list_format[i]); 1919 register_list_format[i]);
1813 1920
1921 /* indirect register portion */
1922 while (i < (adev->gfx.rlc.reg_list_format_size_bytes >> 2)) {
1923 if (register_list_format[i] == 0xFFFFFFFF) {
1924 WREG32_SOC15(GC, 0, mmRLC_GPM_SCRATCH_DATA, register_list_format[i++]);
1925 continue;
1926 }
1927
1928 WREG32_SOC15(GC, 0, mmRLC_GPM_SCRATCH_DATA, register_list_format[i++]);
1929 WREG32_SOC15(GC, 0, mmRLC_GPM_SCRATCH_DATA, register_list_format[i++]);
1930
1931 for (j = 0; j < unique_indirect_reg_count; j++) {
1932 if (register_list_format[i] == unique_indirect_regs[j]) {
1933 WREG32_SOC15(GC, 0, mmRLC_GPM_SCRATCH_DATA, j);
1934 break;
1935 }
1936 }
1937
1938 BUG_ON(j >= unique_indirect_reg_count);
1939
1940 i++;
1941 }
1942
1814 /* set save/restore list size */ 1943 /* set save/restore list size */
1815 list_size = adev->gfx.rlc.reg_list_size_bytes >> 2; 1944 list_size = adev->gfx.rlc.reg_list_size_bytes >> 2;
1816 list_size = list_size >> 1; 1945 list_size = list_size >> 1;
@@ -1823,14 +1952,19 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev)
1823 adev->gfx.rlc.starting_offsets_start); 1952 adev->gfx.rlc.starting_offsets_start);
1824 for (i = 0; i < ARRAY_SIZE(indirect_start_offsets); i++) 1953 for (i = 0; i < ARRAY_SIZE(indirect_start_offsets); i++)
1825 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_DATA), 1954 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_DATA),
1826 indirect_start_offsets[i]); 1955 indirect_start_offsets[i]);
1827 1956
1828 /* load unique indirect regs*/ 1957 /* load unique indirect regs*/
1829 for (i = 0; i < ARRAY_SIZE(unique_indirect_regs); i++) { 1958 for (i = 0; i < ARRAY_SIZE(unique_indirect_regs); i++) {
1830 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_ADDR_0) + i, 1959 if (unique_indirect_regs[i] != 0) {
1831 unique_indirect_regs[i] & 0x3FFFF); 1960 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_ADDR_0)
1832 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_DATA_0) + i, 1961 + GFX_RLC_SRM_INDEX_CNTL_ADDR_OFFSETS[i],
1833 unique_indirect_regs[i] >> 20); 1962 unique_indirect_regs[i] & 0x3FFFF);
1963
1964 WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_DATA_0)
1965 + GFX_RLC_SRM_INDEX_CNTL_DATA_OFFSETS[i],
1966 unique_indirect_regs[i] >> 20);
1967 }
1834 } 1968 }
1835 1969
1836 kfree(register_list_format); 1970 kfree(register_list_format);
@@ -2010,6 +2144,9 @@ static void gfx_v9_0_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *ad
2010 2144
2011static void gfx_v9_0_init_pg(struct amdgpu_device *adev) 2145static void gfx_v9_0_init_pg(struct amdgpu_device *adev)
2012{ 2146{
2147 if (!adev->gfx.rlc.is_rlc_v2_1)
2148 return;
2149
2013 if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG | 2150 if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG |
2014 AMD_PG_SUPPORT_GFX_SMG | 2151 AMD_PG_SUPPORT_GFX_SMG |
2015 AMD_PG_SUPPORT_GFX_DMG | 2152 AMD_PG_SUPPORT_GFX_DMG |
@@ -2017,27 +2154,12 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev)
2017 AMD_PG_SUPPORT_GDS | 2154 AMD_PG_SUPPORT_GDS |
2018 AMD_PG_SUPPORT_RLC_SMU_HS)) { 2155 AMD_PG_SUPPORT_RLC_SMU_HS)) {
2019 gfx_v9_0_init_csb(adev); 2156 gfx_v9_0_init_csb(adev);
2020 gfx_v9_0_init_rlc_save_restore_list(adev); 2157 gfx_v9_1_init_rlc_save_restore_list(adev);
2021 gfx_v9_0_enable_save_restore_machine(adev); 2158 gfx_v9_0_enable_save_restore_machine(adev);
2022 2159
2023 if (adev->asic_type == CHIP_RAVEN) { 2160 WREG32(mmRLC_JUMP_TABLE_RESTORE,
2024 WREG32(mmRLC_JUMP_TABLE_RESTORE, 2161 adev->gfx.rlc.cp_table_gpu_addr >> 8);
2025 adev->gfx.rlc.cp_table_gpu_addr >> 8); 2162 gfx_v9_0_init_gfx_power_gating(adev);
2026 gfx_v9_0_init_gfx_power_gating(adev);
2027
2028 if (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS) {
2029 gfx_v9_0_enable_sck_slow_down_on_power_up(adev, true);
2030 gfx_v9_0_enable_sck_slow_down_on_power_down(adev, true);
2031 } else {
2032 gfx_v9_0_enable_sck_slow_down_on_power_up(adev, false);
2033 gfx_v9_0_enable_sck_slow_down_on_power_down(adev, false);
2034 }
2035
2036 if (adev->pg_flags & AMD_PG_SUPPORT_CP)
2037 gfx_v9_0_enable_cp_power_gating(adev, true);
2038 else
2039 gfx_v9_0_enable_cp_power_gating(adev, false);
2040 }
2041 } 2163 }
2042} 2164}
2043 2165
@@ -3061,6 +3183,9 @@ static int gfx_v9_0_hw_fini(void *handle)
3061 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 3183 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
3062 int i; 3184 int i;
3063 3185
3186 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_GFX,
3187 AMD_PG_STATE_UNGATE);
3188
3064 amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); 3189 amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
3065 amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); 3190 amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
3066 3191
@@ -3279,6 +3404,11 @@ static int gfx_v9_0_late_init(void *handle)
3279 if (r) 3404 if (r)
3280 return r; 3405 return r;
3281 3406
3407 r = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_GFX,
3408 AMD_PG_STATE_GATE);
3409 if (r)
3410 return r;
3411
3282 return 0; 3412 return 0;
3283} 3413}
3284 3414
@@ -3339,8 +3469,7 @@ static void gfx_v9_0_exit_rlc_safe_mode(struct amdgpu_device *adev)
3339static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev, 3469static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev,
3340 bool enable) 3470 bool enable)
3341{ 3471{
3342 /* TODO: double check if we need to perform under safe mdoe */ 3472 gfx_v9_0_enter_rlc_safe_mode(adev);
3343 /* gfx_v9_0_enter_rlc_safe_mode(adev); */
3344 3473
3345 if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) { 3474 if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) {
3346 gfx_v9_0_enable_gfx_cg_power_gating(adev, true); 3475 gfx_v9_0_enable_gfx_cg_power_gating(adev, true);
@@ -3351,7 +3480,7 @@ static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev,
3351 gfx_v9_0_enable_gfx_pipeline_powergating(adev, false); 3480 gfx_v9_0_enable_gfx_pipeline_powergating(adev, false);
3352 } 3481 }
3353 3482
3354 /* gfx_v9_0_exit_rlc_safe_mode(adev); */ 3483 gfx_v9_0_exit_rlc_safe_mode(adev);
3355} 3484}
3356 3485
3357static void gfx_v9_0_update_gfx_mg_power_gating(struct amdgpu_device *adev, 3486static void gfx_v9_0_update_gfx_mg_power_gating(struct amdgpu_device *adev,
@@ -3605,6 +3734,7 @@ static int gfx_v9_0_set_clockgating_state(void *handle,
3605 switch (adev->asic_type) { 3734 switch (adev->asic_type) {
3606 case CHIP_VEGA10: 3735 case CHIP_VEGA10:
3607 case CHIP_VEGA12: 3736 case CHIP_VEGA12:
3737 case CHIP_VEGA20:
3608 case CHIP_RAVEN: 3738 case CHIP_RAVEN:
3609 gfx_v9_0_update_gfx_clock_gating(adev, 3739 gfx_v9_0_update_gfx_clock_gating(adev,
3610 state == AMD_CG_STATE_GATE ? true : false); 3740 state == AMD_CG_STATE_GATE ? true : false);
@@ -3742,7 +3872,7 @@ static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
3742 } 3872 }
3743 3873
3744 amdgpu_ring_write(ring, header); 3874 amdgpu_ring_write(ring, header);
3745BUG_ON(ib->gpu_addr & 0x3); /* Dword align */ 3875 BUG_ON(ib->gpu_addr & 0x3); /* Dword align */
3746 amdgpu_ring_write(ring, 3876 amdgpu_ring_write(ring,
3747#ifdef __BIG_ENDIAN 3877#ifdef __BIG_ENDIAN
3748 (2 << 0) | 3878 (2 << 0) |
@@ -3774,13 +3904,16 @@ static void gfx_v9_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,
3774{ 3904{
3775 bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT; 3905 bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT;
3776 bool int_sel = flags & AMDGPU_FENCE_FLAG_INT; 3906 bool int_sel = flags & AMDGPU_FENCE_FLAG_INT;
3907 bool writeback = flags & AMDGPU_FENCE_FLAG_TC_WB_ONLY;
3777 3908
3778 /* RELEASE_MEM - flush caches, send int */ 3909 /* RELEASE_MEM - flush caches, send int */
3779 amdgpu_ring_write(ring, PACKET3(PACKET3_RELEASE_MEM, 6)); 3910 amdgpu_ring_write(ring, PACKET3(PACKET3_RELEASE_MEM, 6));
3780 amdgpu_ring_write(ring, (EOP_TCL1_ACTION_EN | 3911 amdgpu_ring_write(ring, ((writeback ? (EOP_TC_WB_ACTION_EN |
3781 EOP_TC_ACTION_EN | 3912 EOP_TC_NC_ACTION_EN) :
3782 EOP_TC_WB_ACTION_EN | 3913 (EOP_TCL1_ACTION_EN |
3783 EOP_TC_MD_ACTION_EN | 3914 EOP_TC_ACTION_EN |
3915 EOP_TC_WB_ACTION_EN |
3916 EOP_TC_MD_ACTION_EN)) |
3784 EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | 3917 EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
3785 EVENT_INDEX(5))); 3918 EVENT_INDEX(5)));
3786 amdgpu_ring_write(ring, DATA_SEL(write64bit ? 2 : 1) | INT_SEL(int_sel ? 2 : 0)); 3919 amdgpu_ring_write(ring, DATA_SEL(write64bit ? 2 : 1) | INT_SEL(int_sel ? 2 : 0));
@@ -4137,6 +4270,20 @@ static void gfx_v9_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
4137 gfx_v9_0_wait_reg_mem(ring, 0, 0, 0, reg, 0, val, mask, 0x20); 4270 gfx_v9_0_wait_reg_mem(ring, 0, 0, 0, reg, 0, val, mask, 0x20);
4138} 4271}
4139 4272
4273static void gfx_v9_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,
4274 uint32_t reg0, uint32_t reg1,
4275 uint32_t ref, uint32_t mask)
4276{
4277 int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
4278
4279 if (amdgpu_sriov_vf(ring->adev))
4280 gfx_v9_0_wait_reg_mem(ring, usepfp, 0, 1, reg0, reg1,
4281 ref, mask, 0x20);
4282 else
4283 amdgpu_ring_emit_reg_write_reg_wait_helper(ring, reg0, reg1,
4284 ref, mask);
4285}
4286
4140static void gfx_v9_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev, 4287static void gfx_v9_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
4141 enum amdgpu_interrupt_state state) 4288 enum amdgpu_interrupt_state state)
4142{ 4289{
@@ -4458,6 +4605,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {
4458 .emit_tmz = gfx_v9_0_ring_emit_tmz, 4605 .emit_tmz = gfx_v9_0_ring_emit_tmz,
4459 .emit_wreg = gfx_v9_0_ring_emit_wreg, 4606 .emit_wreg = gfx_v9_0_ring_emit_wreg,
4460 .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait, 4607 .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,
4608 .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,
4461}; 4609};
4462 4610
4463static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = { 4611static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = {
@@ -4492,6 +4640,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = {
4492 .set_priority = gfx_v9_0_ring_set_priority_compute, 4640 .set_priority = gfx_v9_0_ring_set_priority_compute,
4493 .emit_wreg = gfx_v9_0_ring_emit_wreg, 4641 .emit_wreg = gfx_v9_0_ring_emit_wreg,
4494 .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait, 4642 .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,
4643 .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,
4495}; 4644};
4496 4645
4497static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_kiq = { 4646static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_kiq = {
@@ -4522,6 +4671,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_kiq = {
4522 .emit_rreg = gfx_v9_0_ring_emit_rreg, 4671 .emit_rreg = gfx_v9_0_ring_emit_rreg,
4523 .emit_wreg = gfx_v9_0_ring_emit_wreg, 4672 .emit_wreg = gfx_v9_0_ring_emit_wreg,
4524 .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait, 4673 .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,
4674 .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,
4525}; 4675};
4526 4676
4527static void gfx_v9_0_set_ring_funcs(struct amdgpu_device *adev) 4677static void gfx_v9_0_set_ring_funcs(struct amdgpu_device *adev)
@@ -4577,6 +4727,7 @@ static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev)
4577 switch (adev->asic_type) { 4727 switch (adev->asic_type) {
4578 case CHIP_VEGA10: 4728 case CHIP_VEGA10:
4579 case CHIP_VEGA12: 4729 case CHIP_VEGA12:
4730 case CHIP_VEGA20:
4580 case CHIP_RAVEN: 4731 case CHIP_RAVEN:
4581 adev->gfx.rlc.funcs = &gfx_v9_0_rlc_funcs; 4732 adev->gfx.rlc.funcs = &gfx_v9_0_rlc_funcs;
4582 break; 4733 break;
@@ -4686,6 +4837,7 @@ static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
4686 4837
4687 cu_info->number = active_cu_number; 4838 cu_info->number = active_cu_number;
4688 cu_info->ao_cu_mask = ao_cu_mask; 4839 cu_info->ao_cu_mask = ao_cu_mask;
4840 cu_info->simd_per_cu = NUM_SIMD_PER_CU;
4689 4841
4690 return 0; 4842 return 0;
4691} 4843}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
index 5617cf62c566..79f9ac29019b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
@@ -819,12 +819,33 @@ static int gmc_v6_0_late_init(void *handle)
819{ 819{
820 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 820 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
821 821
822 amdgpu_bo_late_init(adev);
823
822 if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) 824 if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
823 return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0); 825 return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0);
824 else 826 else
825 return 0; 827 return 0;
826} 828}
827 829
830static unsigned gmc_v6_0_get_vbios_fb_size(struct amdgpu_device *adev)
831{
832 u32 d1vga_control = RREG32(mmD1VGA_CONTROL);
833 unsigned size;
834
835 if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL, D1VGA_MODE_ENABLE)) {
836 size = 9 * 1024 * 1024; /* reserve 8MB for vga emulator and 1 MB for FB */
837 } else {
838 u32 viewport = RREG32(mmVIEWPORT_SIZE);
839 size = (REG_GET_FIELD(viewport, VIEWPORT_SIZE, VIEWPORT_HEIGHT) *
840 REG_GET_FIELD(viewport, VIEWPORT_SIZE, VIEWPORT_WIDTH) *
841 4);
842 }
843 /* return 0 if the pre-OS buffer uses up most of vram */
844 if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024))
845 return 0;
846 return size;
847}
848
828static int gmc_v6_0_sw_init(void *handle) 849static int gmc_v6_0_sw_init(void *handle)
829{ 850{
830 int r; 851 int r;
@@ -851,8 +872,6 @@ static int gmc_v6_0_sw_init(void *handle)
851 872
852 adev->gmc.mc_mask = 0xffffffffffULL; 873 adev->gmc.mc_mask = 0xffffffffffULL;
853 874
854 adev->gmc.stolen_size = 256 * 1024;
855
856 adev->need_dma32 = false; 875 adev->need_dma32 = false;
857 dma_bits = adev->need_dma32 ? 32 : 40; 876 dma_bits = adev->need_dma32 ? 32 : 40;
858 r = pci_set_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits)); 877 r = pci_set_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
@@ -878,6 +897,8 @@ static int gmc_v6_0_sw_init(void *handle)
878 if (r) 897 if (r)
879 return r; 898 return r;
880 899
900 adev->gmc.stolen_size = gmc_v6_0_get_vbios_fb_size(adev);
901
881 r = amdgpu_bo_init(adev); 902 r = amdgpu_bo_init(adev);
882 if (r) 903 if (r)
883 return r; 904 return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 80054f36e487..7147bfe25a23 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -958,12 +958,33 @@ static int gmc_v7_0_late_init(void *handle)
958{ 958{
959 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 959 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
960 960
961 amdgpu_bo_late_init(adev);
962
961 if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) 963 if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
962 return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0); 964 return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0);
963 else 965 else
964 return 0; 966 return 0;
965} 967}
966 968
969static unsigned gmc_v7_0_get_vbios_fb_size(struct amdgpu_device *adev)
970{
971 u32 d1vga_control = RREG32(mmD1VGA_CONTROL);
972 unsigned size;
973
974 if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL, D1VGA_MODE_ENABLE)) {
975 size = 9 * 1024 * 1024; /* reserve 8MB for vga emulator and 1 MB for FB */
976 } else {
977 u32 viewport = RREG32(mmVIEWPORT_SIZE);
978 size = (REG_GET_FIELD(viewport, VIEWPORT_SIZE, VIEWPORT_HEIGHT) *
979 REG_GET_FIELD(viewport, VIEWPORT_SIZE, VIEWPORT_WIDTH) *
980 4);
981 }
982 /* return 0 if the pre-OS buffer uses up most of vram */
983 if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024))
984 return 0;
985 return size;
986}
987
967static int gmc_v7_0_sw_init(void *handle) 988static int gmc_v7_0_sw_init(void *handle)
968{ 989{
969 int r; 990 int r;
@@ -998,8 +1019,6 @@ static int gmc_v7_0_sw_init(void *handle)
998 */ 1019 */
999 adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */ 1020 adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
1000 1021
1001 adev->gmc.stolen_size = 256 * 1024;
1002
1003 /* set DMA mask + need_dma32 flags. 1022 /* set DMA mask + need_dma32 flags.
1004 * PCIE - can handle 40-bits. 1023 * PCIE - can handle 40-bits.
1005 * IGP - can handle 40-bits 1024 * IGP - can handle 40-bits
@@ -1030,6 +1049,8 @@ static int gmc_v7_0_sw_init(void *handle)
1030 if (r) 1049 if (r)
1031 return r; 1050 return r;
1032 1051
1052 adev->gmc.stolen_size = gmc_v7_0_get_vbios_fb_size(adev);
1053
1033 /* Memory manager */ 1054 /* Memory manager */
1034 r = amdgpu_bo_init(adev); 1055 r = amdgpu_bo_init(adev);
1035 if (r) 1056 if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index d71d4cb68f9c..1edbe6b477b5 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -138,6 +138,7 @@ static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev)
138 break; 138 break;
139 case CHIP_POLARIS11: 139 case CHIP_POLARIS11:
140 case CHIP_POLARIS12: 140 case CHIP_POLARIS12:
141 case CHIP_VEGAM:
141 amdgpu_device_program_register_sequence(adev, 142 amdgpu_device_program_register_sequence(adev,
142 golden_settings_polaris11_a11, 143 golden_settings_polaris11_a11,
143 ARRAY_SIZE(golden_settings_polaris11_a11)); 144 ARRAY_SIZE(golden_settings_polaris11_a11));
@@ -231,6 +232,7 @@ static int gmc_v8_0_init_microcode(struct amdgpu_device *adev)
231 case CHIP_FIJI: 232 case CHIP_FIJI:
232 case CHIP_CARRIZO: 233 case CHIP_CARRIZO:
233 case CHIP_STONEY: 234 case CHIP_STONEY:
235 case CHIP_VEGAM:
234 return 0; 236 return 0;
235 default: BUG(); 237 default: BUG();
236 } 238 }
@@ -567,9 +569,10 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
567 /* set the gart size */ 569 /* set the gart size */
568 if (amdgpu_gart_size == -1) { 570 if (amdgpu_gart_size == -1) {
569 switch (adev->asic_type) { 571 switch (adev->asic_type) {
570 case CHIP_POLARIS11: /* all engines support GPUVM */
571 case CHIP_POLARIS10: /* all engines support GPUVM */ 572 case CHIP_POLARIS10: /* all engines support GPUVM */
573 case CHIP_POLARIS11: /* all engines support GPUVM */
572 case CHIP_POLARIS12: /* all engines support GPUVM */ 574 case CHIP_POLARIS12: /* all engines support GPUVM */
575 case CHIP_VEGAM: /* all engines support GPUVM */
573 default: 576 default:
574 adev->gmc.gart_size = 256ULL << 20; 577 adev->gmc.gart_size = 256ULL << 20;
575 break; 578 break;
@@ -1049,12 +1052,33 @@ static int gmc_v8_0_late_init(void *handle)
1049{ 1052{
1050 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1053 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1051 1054
1055 amdgpu_bo_late_init(adev);
1056
1052 if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) 1057 if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
1053 return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0); 1058 return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0);
1054 else 1059 else
1055 return 0; 1060 return 0;
1056} 1061}
1057 1062
1063static unsigned gmc_v8_0_get_vbios_fb_size(struct amdgpu_device *adev)
1064{
1065 u32 d1vga_control = RREG32(mmD1VGA_CONTROL);
1066 unsigned size;
1067
1068 if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL, D1VGA_MODE_ENABLE)) {
1069 size = 9 * 1024 * 1024; /* reserve 8MB for vga emulator and 1 MB for FB */
1070 } else {
1071 u32 viewport = RREG32(mmVIEWPORT_SIZE);
1072 size = (REG_GET_FIELD(viewport, VIEWPORT_SIZE, VIEWPORT_HEIGHT) *
1073 REG_GET_FIELD(viewport, VIEWPORT_SIZE, VIEWPORT_WIDTH) *
1074 4);
1075 }
1076 /* return 0 if the pre-OS buffer uses up most of vram */
1077 if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024))
1078 return 0;
1079 return size;
1080}
1081
1058#define mmMC_SEQ_MISC0_FIJI 0xA71 1082#define mmMC_SEQ_MISC0_FIJI 0xA71
1059 1083
1060static int gmc_v8_0_sw_init(void *handle) 1084static int gmc_v8_0_sw_init(void *handle)
@@ -1068,7 +1092,8 @@ static int gmc_v8_0_sw_init(void *handle)
1068 } else { 1092 } else {
1069 u32 tmp; 1093 u32 tmp;
1070 1094
1071 if (adev->asic_type == CHIP_FIJI) 1095 if ((adev->asic_type == CHIP_FIJI) ||
1096 (adev->asic_type == CHIP_VEGAM))
1072 tmp = RREG32(mmMC_SEQ_MISC0_FIJI); 1097 tmp = RREG32(mmMC_SEQ_MISC0_FIJI);
1073 else 1098 else
1074 tmp = RREG32(mmMC_SEQ_MISC0); 1099 tmp = RREG32(mmMC_SEQ_MISC0);
@@ -1096,8 +1121,6 @@ static int gmc_v8_0_sw_init(void *handle)
1096 */ 1121 */
1097 adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */ 1122 adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
1098 1123
1099 adev->gmc.stolen_size = 256 * 1024;
1100
1101 /* set DMA mask + need_dma32 flags. 1124 /* set DMA mask + need_dma32 flags.
1102 * PCIE - can handle 40-bits. 1125 * PCIE - can handle 40-bits.
1103 * IGP - can handle 40-bits 1126 * IGP - can handle 40-bits
@@ -1128,6 +1151,8 @@ static int gmc_v8_0_sw_init(void *handle)
1128 if (r) 1151 if (r)
1129 return r; 1152 return r;
1130 1153
1154 adev->gmc.stolen_size = gmc_v8_0_get_vbios_fb_size(adev);
1155
1131 /* Memory manager */ 1156 /* Memory manager */
1132 r = amdgpu_bo_init(adev); 1157 r = amdgpu_bo_init(adev);
1133 if (r) 1158 if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index e687363900bb..3c0a85d4e4ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -43,19 +43,13 @@
43#include "gfxhub_v1_0.h" 43#include "gfxhub_v1_0.h"
44#include "mmhub_v1_0.h" 44#include "mmhub_v1_0.h"
45 45
46#define mmDF_CS_AON0_DramBaseAddress0 0x0044 46/* add these here since we already include dce12 headers and these are for DCN */
47#define mmDF_CS_AON0_DramBaseAddress0_BASE_IDX 0 47#define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION 0x055d
48//DF_CS_AON0_DramBaseAddress0 48#define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_BASE_IDX 2
49#define DF_CS_AON0_DramBaseAddress0__AddrRngVal__SHIFT 0x0 49#define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_WIDTH__SHIFT 0x0
50#define DF_CS_AON0_DramBaseAddress0__LgcyMmioHoleEn__SHIFT 0x1 50#define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_HEIGHT__SHIFT 0x10
51#define DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT 0x4 51#define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_WIDTH_MASK 0x00003FFFL
52#define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel__SHIFT 0x8 52#define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_HEIGHT_MASK 0x3FFF0000L
53#define DF_CS_AON0_DramBaseAddress0__DramBaseAddr__SHIFT 0xc
54#define DF_CS_AON0_DramBaseAddress0__AddrRngVal_MASK 0x00000001L
55#define DF_CS_AON0_DramBaseAddress0__LgcyMmioHoleEn_MASK 0x00000002L
56#define DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK 0x000000F0L
57#define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel_MASK 0x00000700L
58#define DF_CS_AON0_DramBaseAddress0__DramBaseAddr_MASK 0xFFFFF000L
59 53
60/* XXX Move this macro to VEGA10 header file, which is like vid.h for VI.*/ 54/* XXX Move this macro to VEGA10 header file, which is like vid.h for VI.*/
61#define AMDGPU_NUM_OF_VMIDS 8 55#define AMDGPU_NUM_OF_VMIDS 8
@@ -385,11 +379,9 @@ static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
385 amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_hi32 + (2 * vmid), 379 amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_hi32 + (2 * vmid),
386 upper_32_bits(pd_addr)); 380 upper_32_bits(pd_addr));
387 381
388 amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_req + eng, req); 382 amdgpu_ring_emit_reg_write_reg_wait(ring, hub->vm_inv_eng0_req + eng,
389 383 hub->vm_inv_eng0_ack + eng,
390 /* wait for the invalidate to complete */ 384 req, 1 << vmid);
391 amdgpu_ring_emit_reg_wait(ring, hub->vm_inv_eng0_ack + eng,
392 1 << vmid, 1 << vmid);
393 385
394 return pd_addr; 386 return pd_addr;
395} 387}
@@ -556,8 +548,7 @@ static int gmc_v9_0_early_init(void *handle)
556 adev->gmc.shared_aperture_start = 0x2000000000000000ULL; 548 adev->gmc.shared_aperture_start = 0x2000000000000000ULL;
557 adev->gmc.shared_aperture_end = 549 adev->gmc.shared_aperture_end =
558 adev->gmc.shared_aperture_start + (4ULL << 30) - 1; 550 adev->gmc.shared_aperture_start + (4ULL << 30) - 1;
559 adev->gmc.private_aperture_start = 551 adev->gmc.private_aperture_start = 0x1000000000000000ULL;
560 adev->gmc.shared_aperture_end + 1;
561 adev->gmc.private_aperture_end = 552 adev->gmc.private_aperture_end =
562 adev->gmc.private_aperture_start + (4ULL << 30) - 1; 553 adev->gmc.private_aperture_start + (4ULL << 30) - 1;
563 554
@@ -659,6 +650,11 @@ static int gmc_v9_0_late_init(void *handle)
659 unsigned i; 650 unsigned i;
660 int r; 651 int r;
661 652
653 /*
654 * TODO - Uncomment once GART corruption issue is fixed.
655 */
656 /* amdgpu_bo_late_init(adev); */
657
662 for(i = 0; i < adev->num_rings; ++i) { 658 for(i = 0; i < adev->num_rings; ++i) {
663 struct amdgpu_ring *ring = adev->rings[i]; 659 struct amdgpu_ring *ring = adev->rings[i];
664 unsigned vmhub = ring->funcs->vmhub; 660 unsigned vmhub = ring->funcs->vmhub;
@@ -679,6 +675,7 @@ static int gmc_v9_0_late_init(void *handle)
679 DRM_INFO("ECC is active.\n"); 675 DRM_INFO("ECC is active.\n");
680 } else if (r == 0) { 676 } else if (r == 0) {
681 DRM_INFO("ECC is not present.\n"); 677 DRM_INFO("ECC is not present.\n");
678 adev->df_funcs->enable_ecc_force_par_wr_rmw(adev, false);
682 } else { 679 } else {
683 DRM_ERROR("gmc_v9_0_ecc_available() failed. r: %d\n", r); 680 DRM_ERROR("gmc_v9_0_ecc_available() failed. r: %d\n", r);
684 return r; 681 return r;
@@ -697,10 +694,7 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev,
697 amdgpu_device_vram_location(adev, &adev->gmc, base); 694 amdgpu_device_vram_location(adev, &adev->gmc, base);
698 amdgpu_device_gart_location(adev, mc); 695 amdgpu_device_gart_location(adev, mc);
699 /* base offset of vram pages */ 696 /* base offset of vram pages */
700 if (adev->flags & AMD_IS_APU) 697 adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev);
701 adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev);
702 else
703 adev->vm_manager.vram_base_offset = 0;
704} 698}
705 699
706/** 700/**
@@ -714,7 +708,6 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev,
714 */ 708 */
715static int gmc_v9_0_mc_init(struct amdgpu_device *adev) 709static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
716{ 710{
717 u32 tmp;
718 int chansize, numchan; 711 int chansize, numchan;
719 int r; 712 int r;
720 713
@@ -727,39 +720,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
727 else 720 else
728 chansize = 128; 721 chansize = 128;
729 722
730 tmp = RREG32_SOC15(DF, 0, mmDF_CS_AON0_DramBaseAddress0); 723 numchan = adev->df_funcs->get_hbm_channel_number(adev);
731 tmp &= DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK;
732 tmp >>= DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
733 switch (tmp) {
734 case 0:
735 default:
736 numchan = 1;
737 break;
738 case 1:
739 numchan = 2;
740 break;
741 case 2:
742 numchan = 0;
743 break;
744 case 3:
745 numchan = 4;
746 break;
747 case 4:
748 numchan = 0;
749 break;
750 case 5:
751 numchan = 8;
752 break;
753 case 6:
754 numchan = 0;
755 break;
756 case 7:
757 numchan = 16;
758 break;
759 case 8:
760 numchan = 2;
761 break;
762 }
763 adev->gmc.vram_width = numchan * chansize; 724 adev->gmc.vram_width = numchan * chansize;
764 } 725 }
765 726
@@ -792,6 +753,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
792 switch (adev->asic_type) { 753 switch (adev->asic_type) {
793 case CHIP_VEGA10: /* all engines support GPUVM */ 754 case CHIP_VEGA10: /* all engines support GPUVM */
794 case CHIP_VEGA12: /* all engines support GPUVM */ 755 case CHIP_VEGA12: /* all engines support GPUVM */
756 case CHIP_VEGA20:
795 default: 757 default:
796 adev->gmc.gart_size = 512ULL << 20; 758 adev->gmc.gart_size = 512ULL << 20;
797 break; 759 break;
@@ -826,6 +788,52 @@ static int gmc_v9_0_gart_init(struct amdgpu_device *adev)
826 return amdgpu_gart_table_vram_alloc(adev); 788 return amdgpu_gart_table_vram_alloc(adev);
827} 789}
828 790
791static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev)
792{
793#if 0
794 u32 d1vga_control = RREG32_SOC15(DCE, 0, mmD1VGA_CONTROL);
795#endif
796 unsigned size;
797
798 /*
799 * TODO Remove once GART corruption is resolved
800 * Check related code in gmc_v9_0_sw_fini
801 * */
802 size = 9 * 1024 * 1024;
803
804#if 0
805 if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL, D1VGA_MODE_ENABLE)) {
806 size = 9 * 1024 * 1024; /* reserve 8MB for vga emulator and 1 MB for FB */
807 } else {
808 u32 viewport;
809
810 switch (adev->asic_type) {
811 case CHIP_RAVEN:
812 viewport = RREG32_SOC15(DCE, 0, mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION);
813 size = (REG_GET_FIELD(viewport,
814 HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT) *
815 REG_GET_FIELD(viewport,
816 HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_WIDTH) *
817 4);
818 break;
819 case CHIP_VEGA10:
820 case CHIP_VEGA12:
821 default:
822 viewport = RREG32_SOC15(DCE, 0, mmSCL0_VIEWPORT_SIZE);
823 size = (REG_GET_FIELD(viewport, SCL0_VIEWPORT_SIZE, VIEWPORT_HEIGHT) *
824 REG_GET_FIELD(viewport, SCL0_VIEWPORT_SIZE, VIEWPORT_WIDTH) *
825 4);
826 break;
827 }
828 }
829 /* return 0 if the pre-OS buffer uses up most of vram */
830 if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024))
831 return 0;
832
833#endif
834 return size;
835}
836
829static int gmc_v9_0_sw_init(void *handle) 837static int gmc_v9_0_sw_init(void *handle)
830{ 838{
831 int r; 839 int r;
@@ -851,6 +859,7 @@ static int gmc_v9_0_sw_init(void *handle)
851 break; 859 break;
852 case CHIP_VEGA10: 860 case CHIP_VEGA10:
853 case CHIP_VEGA12: 861 case CHIP_VEGA12:
862 case CHIP_VEGA20:
854 /* 863 /*
855 * To fulfill 4-level page support, 864 * To fulfill 4-level page support,
856 * vm size is 256TB (48bit), maximum size of Vega10, 865 * vm size is 256TB (48bit), maximum size of Vega10,
@@ -877,12 +886,6 @@ static int gmc_v9_0_sw_init(void *handle)
877 */ 886 */
878 adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */ 887 adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */
879 888
880 /*
881 * It needs to reserve 8M stolen memory for vega10
882 * TODO: Figure out how to avoid that...
883 */
884 adev->gmc.stolen_size = 8 * 1024 * 1024;
885
886 /* set DMA mask + need_dma32 flags. 889 /* set DMA mask + need_dma32 flags.
887 * PCIE - can handle 44-bits. 890 * PCIE - can handle 44-bits.
888 * IGP - can handle 44-bits 891 * IGP - can handle 44-bits
@@ -907,6 +910,8 @@ static int gmc_v9_0_sw_init(void *handle)
907 if (r) 910 if (r)
908 return r; 911 return r;
909 912
913 adev->gmc.stolen_size = gmc_v9_0_get_vbios_fb_size(adev);
914
910 /* Memory manager */ 915 /* Memory manager */
911 r = amdgpu_bo_init(adev); 916 r = amdgpu_bo_init(adev);
912 if (r) 917 if (r)
@@ -950,6 +955,18 @@ static int gmc_v9_0_sw_fini(void *handle)
950 amdgpu_gem_force_release(adev); 955 amdgpu_gem_force_release(adev);
951 amdgpu_vm_manager_fini(adev); 956 amdgpu_vm_manager_fini(adev);
952 gmc_v9_0_gart_fini(adev); 957 gmc_v9_0_gart_fini(adev);
958
959 /*
960 * TODO:
961 * Currently there is a bug where some memory client outside
962 * of the driver writes to first 8M of VRAM on S3 resume,
963 * this overrides GART which by default gets placed in first 8M and
964 * causes VM_FAULTS once GTT is accessed.
965 * Keep the stolen memory reservation until the while this is not solved.
966 * Also check code in gmc_v9_0_get_vbios_fb_size and gmc_v9_0_late_init
967 */
968 amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
969
953 amdgpu_bo_fini(adev); 970 amdgpu_bo_fini(adev);
954 971
955 return 0; 972 return 0;
@@ -960,6 +977,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev)
960 977
961 switch (adev->asic_type) { 978 switch (adev->asic_type) {
962 case CHIP_VEGA10: 979 case CHIP_VEGA10:
980 case CHIP_VEGA20:
963 soc15_program_register_sequence(adev, 981 soc15_program_register_sequence(adev,
964 golden_settings_mmhub_1_0_0, 982 golden_settings_mmhub_1_0_0,
965 ARRAY_SIZE(golden_settings_mmhub_1_0_0)); 983 ARRAY_SIZE(golden_settings_mmhub_1_0_0));
diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
index 26ba984ab2b7..17f7f074cedc 100644
--- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
@@ -2817,7 +2817,7 @@ static int kv_dpm_init(struct amdgpu_device *adev)
2817 pi->caps_tcp_ramping = true; 2817 pi->caps_tcp_ramping = true;
2818 } 2818 }
2819 2819
2820 if (amdgpu_pp_feature_mask & SCLK_DEEP_SLEEP_MASK) 2820 if (adev->powerplay.pp_feature & PP_SCLK_DEEP_SLEEP_MASK)
2821 pi->caps_sclk_ds = true; 2821 pi->caps_sclk_ds = true;
2822 else 2822 else
2823 pi->caps_sclk_ds = false; 2823 pi->caps_sclk_ds = false;
@@ -2974,7 +2974,7 @@ static int kv_dpm_late_init(void *handle)
2974 /* powerdown unused blocks for now */ 2974 /* powerdown unused blocks for now */
2975 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 2975 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
2976 2976
2977 if (!amdgpu_dpm) 2977 if (!adev->pm.dpm_enabled)
2978 return 0; 2978 return 0;
2979 2979
2980 kv_dpm_powergate_acp(adev, true); 2980 kv_dpm_powergate_acp(adev, true);
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
index 43f925773b57..3d53c4413f13 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
@@ -734,6 +734,7 @@ int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev,
734 switch (adev->asic_type) { 734 switch (adev->asic_type) {
735 case CHIP_VEGA10: 735 case CHIP_VEGA10:
736 case CHIP_VEGA12: 736 case CHIP_VEGA12:
737 case CHIP_VEGA20:
737 case CHIP_RAVEN: 738 case CHIP_RAVEN:
738 mmhub_v1_0_update_medium_grain_clock_gating(adev, 739 mmhub_v1_0_update_medium_grain_clock_gating(adev,
739 state == AMD_CG_STATE_GATE ? true : false); 740 state == AMD_CG_STATE_GATE ? true : false);
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
index 493348672475..078f70faedcb 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
@@ -260,8 +260,10 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work)
260 } while (timeout > 1); 260 } while (timeout > 1);
261 261
262flr_done: 262flr_done:
263 if (locked) 263 if (locked) {
264 adev->in_gpu_reset = 0;
264 mutex_unlock(&adev->lock_reset); 265 mutex_unlock(&adev->lock_reset);
266 }
265 267
266 /* Trigger recovery for world switch failure if no TDR */ 268 /* Trigger recovery for world switch failure if no TDR */
267 if (amdgpu_lockup_timeout == 0) 269 if (amdgpu_lockup_timeout == 0)
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
index df34dc79d444..365517c0121e 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
@@ -34,10 +34,19 @@
34#define smnCPM_CONTROL 0x11180460 34#define smnCPM_CONTROL 0x11180460
35#define smnPCIE_CNTL2 0x11180070 35#define smnPCIE_CNTL2 0x11180070
36 36
37/* vega20 */
38#define mmRCC_DEV0_EPF0_STRAP0_VG20 0x0011
39#define mmRCC_DEV0_EPF0_STRAP0_VG20_BASE_IDX 2
40
37static u32 nbio_v7_0_get_rev_id(struct amdgpu_device *adev) 41static u32 nbio_v7_0_get_rev_id(struct amdgpu_device *adev)
38{ 42{
39 u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); 43 u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0);
40 44
45 if (adev->asic_type == CHIP_VEGA20)
46 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0_VG20);
47 else
48 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0);
49
41 tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; 50 tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
42 tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; 51 tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
43 52
@@ -75,10 +84,14 @@ static void nbio_v7_0_sdma_doorbell_range(struct amdgpu_device *adev, int instan
75 SOC15_REG_OFFSET(NBIO, 0, mmBIF_SDMA1_DOORBELL_RANGE); 84 SOC15_REG_OFFSET(NBIO, 0, mmBIF_SDMA1_DOORBELL_RANGE);
76 85
77 u32 doorbell_range = RREG32(reg); 86 u32 doorbell_range = RREG32(reg);
87 u32 range = 2;
88
89 if (adev->asic_type == CHIP_VEGA20)
90 range = 8;
78 91
79 if (use_doorbell) { 92 if (use_doorbell) {
80 doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, OFFSET, doorbell_index); 93 doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, OFFSET, doorbell_index);
81 doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, 2); 94 doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, range);
82 } else 95 } else
83 doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, 0); 96 doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, 0);
84 97
@@ -133,6 +146,9 @@ static void nbio_v7_0_update_medium_grain_clock_gating(struct amdgpu_device *ade
133{ 146{
134 uint32_t def, data; 147 uint32_t def, data;
135 148
149 if (adev->asic_type == CHIP_VEGA20)
150 return;
151
136 /* NBIF_MGCG_CTRL_LCLK */ 152 /* NBIF_MGCG_CTRL_LCLK */
137 def = data = RREG32_PCIE(smnNBIF_MGCG_CTRL_LCLK); 153 def = data = RREG32_PCIE(smnNBIF_MGCG_CTRL_LCLK);
138 154
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
index 8da6da90b1c9..0cf48d26c676 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
+++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
@@ -40,11 +40,20 @@ enum psp_gfx_crtl_cmd_id
40 GFX_CTRL_CMD_ID_INIT_GPCOM_RING = 0x00020000, /* initialize GPCOM ring */ 40 GFX_CTRL_CMD_ID_INIT_GPCOM_RING = 0x00020000, /* initialize GPCOM ring */
41 GFX_CTRL_CMD_ID_DESTROY_RINGS = 0x00030000, /* destroy rings */ 41 GFX_CTRL_CMD_ID_DESTROY_RINGS = 0x00030000, /* destroy rings */
42 GFX_CTRL_CMD_ID_CAN_INIT_RINGS = 0x00040000, /* is it allowed to initialized the rings */ 42 GFX_CTRL_CMD_ID_CAN_INIT_RINGS = 0x00040000, /* is it allowed to initialized the rings */
43 GFX_CTRL_CMD_ID_ENABLE_INT = 0x00050000, /* enable PSP-to-Gfx interrupt */
44 GFX_CTRL_CMD_ID_DISABLE_INT = 0x00060000, /* disable PSP-to-Gfx interrupt */
45 GFX_CTRL_CMD_ID_MODE1_RST = 0x00070000, /* trigger the Mode 1 reset */
43 46
44 GFX_CTRL_CMD_ID_MAX = 0x000F0000, /* max command ID */ 47 GFX_CTRL_CMD_ID_MAX = 0x000F0000, /* max command ID */
45}; 48};
46 49
47 50
51/*-----------------------------------------------------------------------------
52 NOTE: All physical addresses used in this interface are actually
53 GPU Virtual Addresses.
54*/
55
56
48/* Control registers of the TEE Gfx interface. These are located in 57/* Control registers of the TEE Gfx interface. These are located in
49* SRBM-to-PSP mailbox registers (total 8 registers). 58* SRBM-to-PSP mailbox registers (total 8 registers).
50*/ 59*/
@@ -55,8 +64,8 @@ struct psp_gfx_ctrl
55 volatile uint32_t rbi_rptr; /* +8 Read pointer (index) of RBI ring */ 64 volatile uint32_t rbi_rptr; /* +8 Read pointer (index) of RBI ring */
56 volatile uint32_t gpcom_wptr; /* +12 Write pointer (index) of GPCOM ring */ 65 volatile uint32_t gpcom_wptr; /* +12 Write pointer (index) of GPCOM ring */
57 volatile uint32_t gpcom_rptr; /* +16 Read pointer (index) of GPCOM ring */ 66 volatile uint32_t gpcom_rptr; /* +16 Read pointer (index) of GPCOM ring */
58 volatile uint32_t ring_addr_lo; /* +20 bits [31:0] of physical address of ring buffer */ 67 volatile uint32_t ring_addr_lo; /* +20 bits [31:0] of GPU Virtual of ring buffer (VMID=0)*/
59 volatile uint32_t ring_addr_hi; /* +24 bits [63:32] of physical address of ring buffer */ 68 volatile uint32_t ring_addr_hi; /* +24 bits [63:32] of GPU Virtual of ring buffer (VMID=0) */
60 volatile uint32_t ring_buf_size; /* +28 Ring buffer size (in bytes) */ 69 volatile uint32_t ring_buf_size; /* +28 Ring buffer size (in bytes) */
61 70
62}; 71};
@@ -78,6 +87,8 @@ enum psp_gfx_cmd_id
78 GFX_CMD_ID_LOAD_ASD = 0x00000004, /* load ASD Driver */ 87 GFX_CMD_ID_LOAD_ASD = 0x00000004, /* load ASD Driver */
79 GFX_CMD_ID_SETUP_TMR = 0x00000005, /* setup TMR region */ 88 GFX_CMD_ID_SETUP_TMR = 0x00000005, /* setup TMR region */
80 GFX_CMD_ID_LOAD_IP_FW = 0x00000006, /* load HW IP FW */ 89 GFX_CMD_ID_LOAD_IP_FW = 0x00000006, /* load HW IP FW */
90 GFX_CMD_ID_DESTROY_TMR = 0x00000007, /* destroy TMR region */
91 GFX_CMD_ID_SAVE_RESTORE = 0x00000008, /* save/restore HW IP FW */
81 92
82}; 93};
83 94
@@ -85,11 +96,11 @@ enum psp_gfx_cmd_id
85/* Command to load Trusted Application binary into PSP OS. */ 96/* Command to load Trusted Application binary into PSP OS. */
86struct psp_gfx_cmd_load_ta 97struct psp_gfx_cmd_load_ta
87{ 98{
88 uint32_t app_phy_addr_lo; /* bits [31:0] of the physical address of the TA binary (must be 4 KB aligned) */ 99 uint32_t app_phy_addr_lo; /* bits [31:0] of the GPU Virtual address of the TA binary (must be 4 KB aligned) */
89 uint32_t app_phy_addr_hi; /* bits [63:32] of the physical address of the TA binary */ 100 uint32_t app_phy_addr_hi; /* bits [63:32] of the GPU Virtual address of the TA binary */
90 uint32_t app_len; /* length of the TA binary in bytes */ 101 uint32_t app_len; /* length of the TA binary in bytes */
91 uint32_t cmd_buf_phy_addr_lo; /* bits [31:0] of the physical address of CMD buffer (must be 4 KB aligned) */ 102 uint32_t cmd_buf_phy_addr_lo; /* bits [31:0] of the GPU Virtual address of CMD buffer (must be 4 KB aligned) */
92 uint32_t cmd_buf_phy_addr_hi; /* bits [63:32] of the physical address of CMD buffer */ 103 uint32_t cmd_buf_phy_addr_hi; /* bits [63:32] of the GPU Virtual address of CMD buffer */
93 uint32_t cmd_buf_len; /* length of the CMD buffer in bytes; must be multiple of 4 KB */ 104 uint32_t cmd_buf_len; /* length of the CMD buffer in bytes; must be multiple of 4 KB */
94 105
95 /* Note: CmdBufLen can be set to 0. In this case no persistent CMD buffer is provided 106 /* Note: CmdBufLen can be set to 0. In this case no persistent CMD buffer is provided
@@ -111,8 +122,8 @@ struct psp_gfx_cmd_unload_ta
111*/ 122*/
112struct psp_gfx_buf_desc 123struct psp_gfx_buf_desc
113{ 124{
114 uint32_t buf_phy_addr_lo; /* bits [31:0] of physical address of the buffer (must be 4 KB aligned) */ 125 uint32_t buf_phy_addr_lo; /* bits [31:0] of GPU Virtual address of the buffer (must be 4 KB aligned) */
115 uint32_t buf_phy_addr_hi; /* bits [63:32] of physical address of the buffer */ 126 uint32_t buf_phy_addr_hi; /* bits [63:32] of GPU Virtual address of the buffer */
116 uint32_t buf_size; /* buffer size in bytes (must be multiple of 4 KB and no bigger than 64 MB) */ 127 uint32_t buf_size; /* buffer size in bytes (must be multiple of 4 KB and no bigger than 64 MB) */
117 128
118}; 129};
@@ -145,8 +156,8 @@ struct psp_gfx_cmd_invoke_cmd
145/* Command to setup TMR region. */ 156/* Command to setup TMR region. */
146struct psp_gfx_cmd_setup_tmr 157struct psp_gfx_cmd_setup_tmr
147{ 158{
148 uint32_t buf_phy_addr_lo; /* bits [31:0] of physical address of TMR buffer (must be 4 KB aligned) */ 159 uint32_t buf_phy_addr_lo; /* bits [31:0] of GPU Virtual address of TMR buffer (must be 4 KB aligned) */
149 uint32_t buf_phy_addr_hi; /* bits [63:32] of physical address of TMR buffer */ 160 uint32_t buf_phy_addr_hi; /* bits [63:32] of GPU Virtual address of TMR buffer */
150 uint32_t buf_size; /* buffer size in bytes (must be multiple of 4 KB) */ 161 uint32_t buf_size; /* buffer size in bytes (must be multiple of 4 KB) */
151 162
152}; 163};
@@ -174,18 +185,32 @@ enum psp_gfx_fw_type
174 GFX_FW_TYPE_ISP = 16, 185 GFX_FW_TYPE_ISP = 16,
175 GFX_FW_TYPE_ACP = 17, 186 GFX_FW_TYPE_ACP = 17,
176 GFX_FW_TYPE_SMU = 18, 187 GFX_FW_TYPE_SMU = 18,
188 GFX_FW_TYPE_MMSCH = 19,
189 GFX_FW_TYPE_RLC_RESTORE_LIST_GPM_MEM = 20,
190 GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_MEM = 21,
191 GFX_FW_TYPE_RLC_RESTORE_LIST_CNTL = 22,
192 GFX_FW_TYPE_MAX = 23
177}; 193};
178 194
179/* Command to load HW IP FW. */ 195/* Command to load HW IP FW. */
180struct psp_gfx_cmd_load_ip_fw 196struct psp_gfx_cmd_load_ip_fw
181{ 197{
182 uint32_t fw_phy_addr_lo; /* bits [31:0] of physical address of FW location (must be 4 KB aligned) */ 198 uint32_t fw_phy_addr_lo; /* bits [31:0] of GPU Virtual address of FW location (must be 4 KB aligned) */
183 uint32_t fw_phy_addr_hi; /* bits [63:32] of physical address of FW location */ 199 uint32_t fw_phy_addr_hi; /* bits [63:32] of GPU Virtual address of FW location */
184 uint32_t fw_size; /* FW buffer size in bytes */ 200 uint32_t fw_size; /* FW buffer size in bytes */
185 enum psp_gfx_fw_type fw_type; /* FW type */ 201 enum psp_gfx_fw_type fw_type; /* FW type */
186 202
187}; 203};
188 204
205/* Command to save/restore HW IP FW. */
206struct psp_gfx_cmd_save_restore_ip_fw
207{
208 uint32_t save_fw; /* if set, command is used for saving fw otherwise for resetoring*/
209 uint32_t save_restore_addr_lo; /* bits [31:0] of FB address of GART memory used as save/restore buffer (must be 4 KB aligned) */
210 uint32_t save_restore_addr_hi; /* bits [63:32] of FB address of GART memory used as save/restore buffer */
211 uint32_t buf_size; /* Size of the save/restore buffer in bytes */
212 enum psp_gfx_fw_type fw_type; /* FW type */
213};
189 214
190/* All GFX ring buffer commands. */ 215/* All GFX ring buffer commands. */
191union psp_gfx_commands 216union psp_gfx_commands
@@ -195,7 +220,7 @@ union psp_gfx_commands
195 struct psp_gfx_cmd_invoke_cmd cmd_invoke_cmd; 220 struct psp_gfx_cmd_invoke_cmd cmd_invoke_cmd;
196 struct psp_gfx_cmd_setup_tmr cmd_setup_tmr; 221 struct psp_gfx_cmd_setup_tmr cmd_setup_tmr;
197 struct psp_gfx_cmd_load_ip_fw cmd_load_ip_fw; 222 struct psp_gfx_cmd_load_ip_fw cmd_load_ip_fw;
198 223 struct psp_gfx_cmd_save_restore_ip_fw cmd_save_restore_ip_fw;
199}; 224};
200 225
201 226
@@ -226,8 +251,8 @@ struct psp_gfx_cmd_resp
226 251
227 /* These fields are used for RBI only. They are all 0 in GPCOM commands 252 /* These fields are used for RBI only. They are all 0 in GPCOM commands
228 */ 253 */
229 uint32_t resp_buf_addr_lo; /* +12 bits [31:0] of physical address of response buffer (must be 4 KB aligned) */ 254 uint32_t resp_buf_addr_lo; /* +12 bits [31:0] of GPU Virtual address of response buffer (must be 4 KB aligned) */
230 uint32_t resp_buf_addr_hi; /* +16 bits [63:32] of physical address of response buffer */ 255 uint32_t resp_buf_addr_hi; /* +16 bits [63:32] of GPU Virtual address of response buffer */
231 uint32_t resp_offset; /* +20 offset within response buffer */ 256 uint32_t resp_offset; /* +20 offset within response buffer */
232 uint32_t resp_buf_size; /* +24 total size of the response buffer in bytes */ 257 uint32_t resp_buf_size; /* +24 total size of the response buffer in bytes */
233 258
@@ -251,19 +276,19 @@ struct psp_gfx_cmd_resp
251/* Structure of the Ring Buffer Frame */ 276/* Structure of the Ring Buffer Frame */
252struct psp_gfx_rb_frame 277struct psp_gfx_rb_frame
253{ 278{
254 uint32_t cmd_buf_addr_lo; /* +0 bits [31:0] of physical address of command buffer (must be 4 KB aligned) */ 279 uint32_t cmd_buf_addr_lo; /* +0 bits [31:0] of GPU Virtual address of command buffer (must be 4 KB aligned) */
255 uint32_t cmd_buf_addr_hi; /* +4 bits [63:32] of physical address of command buffer */ 280 uint32_t cmd_buf_addr_hi; /* +4 bits [63:32] of GPU Virtual address of command buffer */
256 uint32_t cmd_buf_size; /* +8 command buffer size in bytes */ 281 uint32_t cmd_buf_size; /* +8 command buffer size in bytes */
257 uint32_t fence_addr_lo; /* +12 bits [31:0] of physical address of Fence for this frame */ 282 uint32_t fence_addr_lo; /* +12 bits [31:0] of GPU Virtual address of Fence for this frame */
258 uint32_t fence_addr_hi; /* +16 bits [63:32] of physical address of Fence for this frame */ 283 uint32_t fence_addr_hi; /* +16 bits [63:32] of GPU Virtual address of Fence for this frame */
259 uint32_t fence_value; /* +20 Fence value */ 284 uint32_t fence_value; /* +20 Fence value */
260 uint32_t sid_lo; /* +24 bits [31:0] of SID value (used only for RBI frames) */ 285 uint32_t sid_lo; /* +24 bits [31:0] of SID value (used only for RBI frames) */
261 uint32_t sid_hi; /* +28 bits [63:32] of SID value (used only for RBI frames) */ 286 uint32_t sid_hi; /* +28 bits [63:32] of SID value (used only for RBI frames) */
262 uint8_t vmid; /* +32 VMID value used for mapping of all addresses for this frame */ 287 uint8_t vmid; /* +32 VMID value used for mapping of all addresses for this frame */
263 uint8_t frame_type; /* +33 1: destory context frame, 0: all other frames; used only for RBI frames */ 288 uint8_t frame_type; /* +33 1: destory context frame, 0: all other frames; used only for RBI frames */
264 uint8_t reserved1[2]; /* +34 reserved, must be 0 */ 289 uint8_t reserved1[2]; /* +34 reserved, must be 0 */
265 uint32_t reserved2[7]; /* +40 reserved, must be 0 */ 290 uint32_t reserved2[7]; /* +36 reserved, must be 0 */
266 /* total 64 bytes */ 291 /* total 64 bytes */
267}; 292};
268 293
269#endif /* _PSP_TEE_GFX_IF_H_ */ 294#endif /* _PSP_TEE_GFX_IF_H_ */
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
index 8873d833a7f7..0ff136d02d9b 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
@@ -70,6 +70,15 @@ psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *
70 case AMDGPU_UCODE_ID_RLC_G: 70 case AMDGPU_UCODE_ID_RLC_G:
71 *type = GFX_FW_TYPE_RLC_G; 71 *type = GFX_FW_TYPE_RLC_G;
72 break; 72 break;
73 case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL:
74 *type = GFX_FW_TYPE_RLC_RESTORE_LIST_CNTL;
75 break;
76 case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM:
77 *type = GFX_FW_TYPE_RLC_RESTORE_LIST_GPM_MEM;
78 break;
79 case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM:
80 *type = GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_MEM;
81 break;
73 case AMDGPU_UCODE_ID_SMC: 82 case AMDGPU_UCODE_ID_SMC:
74 *type = GFX_FW_TYPE_SMU; 83 *type = GFX_FW_TYPE_SMU;
75 break; 84 break;
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
index 196e75def1f2..0c768e388ace 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
@@ -41,6 +41,9 @@ MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
41MODULE_FIRMWARE("amdgpu/vega10_asd.bin"); 41MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
42MODULE_FIRMWARE("amdgpu/vega12_sos.bin"); 42MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
43MODULE_FIRMWARE("amdgpu/vega12_asd.bin"); 43MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
44MODULE_FIRMWARE("amdgpu/vega20_sos.bin");
45MODULE_FIRMWARE("amdgpu/vega20_asd.bin");
46
44 47
45#define smnMP1_FIRMWARE_FLAGS 0x3010028 48#define smnMP1_FIRMWARE_FLAGS 0x3010028
46 49
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index be20a387d961..aa9ab299fd32 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -62,6 +62,8 @@ MODULE_FIRMWARE("amdgpu/polaris11_sdma.bin");
62MODULE_FIRMWARE("amdgpu/polaris11_sdma1.bin"); 62MODULE_FIRMWARE("amdgpu/polaris11_sdma1.bin");
63MODULE_FIRMWARE("amdgpu/polaris12_sdma.bin"); 63MODULE_FIRMWARE("amdgpu/polaris12_sdma.bin");
64MODULE_FIRMWARE("amdgpu/polaris12_sdma1.bin"); 64MODULE_FIRMWARE("amdgpu/polaris12_sdma1.bin");
65MODULE_FIRMWARE("amdgpu/vegam_sdma.bin");
66MODULE_FIRMWARE("amdgpu/vegam_sdma1.bin");
65 67
66 68
67static const u32 sdma_offsets[SDMA_MAX_INSTANCE] = 69static const u32 sdma_offsets[SDMA_MAX_INSTANCE] =
@@ -209,6 +211,7 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev)
209 break; 211 break;
210 case CHIP_POLARIS11: 212 case CHIP_POLARIS11:
211 case CHIP_POLARIS12: 213 case CHIP_POLARIS12:
214 case CHIP_VEGAM:
212 amdgpu_device_program_register_sequence(adev, 215 amdgpu_device_program_register_sequence(adev,
213 golden_settings_polaris11_a11, 216 golden_settings_polaris11_a11,
214 ARRAY_SIZE(golden_settings_polaris11_a11)); 217 ARRAY_SIZE(golden_settings_polaris11_a11));
@@ -275,15 +278,18 @@ static int sdma_v3_0_init_microcode(struct amdgpu_device *adev)
275 case CHIP_FIJI: 278 case CHIP_FIJI:
276 chip_name = "fiji"; 279 chip_name = "fiji";
277 break; 280 break;
278 case CHIP_POLARIS11:
279 chip_name = "polaris11";
280 break;
281 case CHIP_POLARIS10: 281 case CHIP_POLARIS10:
282 chip_name = "polaris10"; 282 chip_name = "polaris10";
283 break; 283 break;
284 case CHIP_POLARIS11:
285 chip_name = "polaris11";
286 break;
284 case CHIP_POLARIS12: 287 case CHIP_POLARIS12:
285 chip_name = "polaris12"; 288 chip_name = "polaris12";
286 break; 289 break;
290 case CHIP_VEGAM:
291 chip_name = "vegam";
292 break;
287 case CHIP_CARRIZO: 293 case CHIP_CARRIZO:
288 chip_name = "carrizo"; 294 chip_name = "carrizo";
289 break; 295 break;
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 399f876f9cad..ca53b3fba422 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -42,6 +42,8 @@ MODULE_FIRMWARE("amdgpu/vega10_sdma.bin");
42MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin"); 42MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin");
43MODULE_FIRMWARE("amdgpu/vega12_sdma.bin"); 43MODULE_FIRMWARE("amdgpu/vega12_sdma.bin");
44MODULE_FIRMWARE("amdgpu/vega12_sdma1.bin"); 44MODULE_FIRMWARE("amdgpu/vega12_sdma1.bin");
45MODULE_FIRMWARE("amdgpu/vega20_sdma.bin");
46MODULE_FIRMWARE("amdgpu/vega20_sdma1.bin");
45MODULE_FIRMWARE("amdgpu/raven_sdma.bin"); 47MODULE_FIRMWARE("amdgpu/raven_sdma.bin");
46 48
47#define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L 49#define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L
@@ -107,6 +109,28 @@ static const struct soc15_reg_golden golden_settings_sdma_4_1[] =
107 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0) 109 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0)
108}; 110};
109 111
112static const struct soc15_reg_golden golden_settings_sdma_4_2[] =
113{
114 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CHICKEN_BITS, 0xfe931f07, 0x02831d07),
115 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CLK_CTRL, 0xffffffff, 0x3f000100),
116 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
117 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
118 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GFX_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
119 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_PAGE_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
120 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff0, 0x00403000),
121 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
122 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
123 SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831d07),
124 SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CLK_CTRL, 0xffffffff, 0x3f000100),
125 SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
126 SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
127 SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GFX_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
128 SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_PAGE_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
129 SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
130 SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
131 SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0)
132};
133
110static const struct soc15_reg_golden golden_settings_sdma_rv1[] = 134static const struct soc15_reg_golden golden_settings_sdma_rv1[] =
111{ 135{
112 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00000002), 136 SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00000002),
@@ -139,6 +163,11 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev)
139 golden_settings_sdma_vg12, 163 golden_settings_sdma_vg12,
140 ARRAY_SIZE(golden_settings_sdma_vg12)); 164 ARRAY_SIZE(golden_settings_sdma_vg12));
141 break; 165 break;
166 case CHIP_VEGA20:
167 soc15_program_register_sequence(adev,
168 golden_settings_sdma_4_2,
169 ARRAY_SIZE(golden_settings_sdma_4_2));
170 break;
142 case CHIP_RAVEN: 171 case CHIP_RAVEN:
143 soc15_program_register_sequence(adev, 172 soc15_program_register_sequence(adev,
144 golden_settings_sdma_4_1, 173 golden_settings_sdma_4_1,
@@ -182,6 +211,9 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev)
182 case CHIP_VEGA12: 211 case CHIP_VEGA12:
183 chip_name = "vega12"; 212 chip_name = "vega12";
184 break; 213 break;
214 case CHIP_VEGA20:
215 chip_name = "vega20";
216 break;
185 case CHIP_RAVEN: 217 case CHIP_RAVEN:
186 chip_name = "raven"; 218 chip_name = "raven";
187 break; 219 break;
@@ -360,6 +392,31 @@ static void sdma_v4_0_ring_emit_ib(struct amdgpu_ring *ring,
360 392
361} 393}
362 394
395static void sdma_v4_0_wait_reg_mem(struct amdgpu_ring *ring,
396 int mem_space, int hdp,
397 uint32_t addr0, uint32_t addr1,
398 uint32_t ref, uint32_t mask,
399 uint32_t inv)
400{
401 amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) |
402 SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(hdp) |
403 SDMA_PKT_POLL_REGMEM_HEADER_MEM_POLL(mem_space) |
404 SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3)); /* == */
405 if (mem_space) {
406 /* memory */
407 amdgpu_ring_write(ring, addr0);
408 amdgpu_ring_write(ring, addr1);
409 } else {
410 /* registers */
411 amdgpu_ring_write(ring, addr0 << 2);
412 amdgpu_ring_write(ring, addr1 << 2);
413 }
414 amdgpu_ring_write(ring, ref); /* reference */
415 amdgpu_ring_write(ring, mask); /* mask */
416 amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) |
417 SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(inv)); /* retry count, poll interval */
418}
419
363/** 420/**
364 * sdma_v4_0_ring_emit_hdp_flush - emit an hdp flush on the DMA ring 421 * sdma_v4_0_ring_emit_hdp_flush - emit an hdp flush on the DMA ring
365 * 422 *
@@ -378,15 +435,10 @@ static void sdma_v4_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
378 else 435 else
379 ref_and_mask = nbio_hf_reg->ref_and_mask_sdma1; 436 ref_and_mask = nbio_hf_reg->ref_and_mask_sdma1;
380 437
381 amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) | 438 sdma_v4_0_wait_reg_mem(ring, 0, 1,
382 SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(1) | 439 adev->nbio_funcs->get_hdp_flush_done_offset(adev),
383 SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3)); /* == */ 440 adev->nbio_funcs->get_hdp_flush_req_offset(adev),
384 amdgpu_ring_write(ring, (adev->nbio_funcs->get_hdp_flush_done_offset(adev)) << 2); 441 ref_and_mask, ref_and_mask, 10);
385 amdgpu_ring_write(ring, (adev->nbio_funcs->get_hdp_flush_req_offset(adev)) << 2);
386 amdgpu_ring_write(ring, ref_and_mask); /* reference */
387 amdgpu_ring_write(ring, ref_and_mask); /* mask */
388 amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) |
389 SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10)); /* retry count, poll interval */
390} 442}
391 443
392/** 444/**
@@ -1114,16 +1166,10 @@ static void sdma_v4_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
1114 uint64_t addr = ring->fence_drv.gpu_addr; 1166 uint64_t addr = ring->fence_drv.gpu_addr;
1115 1167
1116 /* wait for idle */ 1168 /* wait for idle */
1117 amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) | 1169 sdma_v4_0_wait_reg_mem(ring, 1, 0,
1118 SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(0) | 1170 addr & 0xfffffffc,
1119 SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3) | /* equal */ 1171 upper_32_bits(addr) & 0xffffffff,
1120 SDMA_PKT_POLL_REGMEM_HEADER_MEM_POLL(1)); 1172 seq, 0xffffffff, 4);
1121 amdgpu_ring_write(ring, addr & 0xfffffffc);
1122 amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
1123 amdgpu_ring_write(ring, seq); /* reference */
1124 amdgpu_ring_write(ring, 0xffffffff); /* mask */
1125 amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) |
1126 SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(4)); /* retry count, poll interval */
1127} 1173}
1128 1174
1129 1175
@@ -1154,15 +1200,7 @@ static void sdma_v4_0_ring_emit_wreg(struct amdgpu_ring *ring,
1154static void sdma_v4_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg, 1200static void sdma_v4_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
1155 uint32_t val, uint32_t mask) 1201 uint32_t val, uint32_t mask)
1156{ 1202{
1157 amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) | 1203 sdma_v4_0_wait_reg_mem(ring, 0, 0, reg, 0, val, mask, 10);
1158 SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(0) |
1159 SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3)); /* equal */
1160 amdgpu_ring_write(ring, reg << 2);
1161 amdgpu_ring_write(ring, 0);
1162 amdgpu_ring_write(ring, val); /* reference */
1163 amdgpu_ring_write(ring, mask); /* mask */
1164 amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) |
1165 SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10));
1166} 1204}
1167 1205
1168static int sdma_v4_0_early_init(void *handle) 1206static int sdma_v4_0_early_init(void *handle)
@@ -1510,6 +1548,7 @@ static int sdma_v4_0_set_clockgating_state(void *handle,
1510 switch (adev->asic_type) { 1548 switch (adev->asic_type) {
1511 case CHIP_VEGA10: 1549 case CHIP_VEGA10:
1512 case CHIP_VEGA12: 1550 case CHIP_VEGA12:
1551 case CHIP_VEGA20:
1513 case CHIP_RAVEN: 1552 case CHIP_RAVEN:
1514 sdma_v4_0_update_medium_grain_clock_gating(adev, 1553 sdma_v4_0_update_medium_grain_clock_gating(adev,
1515 state == AMD_CG_STATE_GATE ? true : false); 1554 state == AMD_CG_STATE_GATE ? true : false);
@@ -1605,6 +1644,7 @@ static const struct amdgpu_ring_funcs sdma_v4_0_ring_funcs = {
1605 .pad_ib = sdma_v4_0_ring_pad_ib, 1644 .pad_ib = sdma_v4_0_ring_pad_ib,
1606 .emit_wreg = sdma_v4_0_ring_emit_wreg, 1645 .emit_wreg = sdma_v4_0_ring_emit_wreg,
1607 .emit_reg_wait = sdma_v4_0_ring_emit_reg_wait, 1646 .emit_reg_wait = sdma_v4_0_ring_emit_reg_wait,
1647 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1608}; 1648};
1609 1649
1610static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev) 1650static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index a675ec6d2811..c364ef94cc36 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -1252,6 +1252,12 @@ static void si_invalidate_hdp(struct amdgpu_device *adev,
1252 } 1252 }
1253} 1253}
1254 1254
1255static bool si_need_full_reset(struct amdgpu_device *adev)
1256{
1257 /* change this when we support soft reset */
1258 return true;
1259}
1260
1255static int si_get_pcie_lanes(struct amdgpu_device *adev) 1261static int si_get_pcie_lanes(struct amdgpu_device *adev)
1256{ 1262{
1257 u32 link_width_cntl; 1263 u32 link_width_cntl;
@@ -1332,6 +1338,7 @@ static const struct amdgpu_asic_funcs si_asic_funcs =
1332 .get_config_memsize = &si_get_config_memsize, 1338 .get_config_memsize = &si_get_config_memsize,
1333 .flush_hdp = &si_flush_hdp, 1339 .flush_hdp = &si_flush_hdp,
1334 .invalidate_hdp = &si_invalidate_hdp, 1340 .invalidate_hdp = &si_invalidate_hdp,
1341 .need_full_reset = &si_need_full_reset,
1335}; 1342};
1336 1343
1337static uint32_t si_get_rev_id(struct amdgpu_device *adev) 1344static uint32_t si_get_rev_id(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
index 797d505bf9ee..b12d7c9d42a0 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
@@ -7580,7 +7580,7 @@ static int si_dpm_late_init(void *handle)
7580 int ret; 7580 int ret;
7581 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 7581 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
7582 7582
7583 if (!amdgpu_dpm) 7583 if (!adev->pm.dpm_enabled)
7584 return 0; 7584 return 0;
7585 7585
7586 ret = si_set_temperature_range(adev); 7586 ret = si_set_temperature_range(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index 51cf8a30f6c2..68b4a22a8892 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -41,8 +41,6 @@
41#include "sdma1/sdma1_4_0_offset.h" 41#include "sdma1/sdma1_4_0_offset.h"
42#include "hdp/hdp_4_0_offset.h" 42#include "hdp/hdp_4_0_offset.h"
43#include "hdp/hdp_4_0_sh_mask.h" 43#include "hdp/hdp_4_0_sh_mask.h"
44#include "mp/mp_9_0_offset.h"
45#include "mp/mp_9_0_sh_mask.h"
46#include "smuio/smuio_9_0_offset.h" 44#include "smuio/smuio_9_0_offset.h"
47#include "smuio/smuio_9_0_sh_mask.h" 45#include "smuio/smuio_9_0_sh_mask.h"
48 46
@@ -52,6 +50,8 @@
52#include "gmc_v9_0.h" 50#include "gmc_v9_0.h"
53#include "gfxhub_v1_0.h" 51#include "gfxhub_v1_0.h"
54#include "mmhub_v1_0.h" 52#include "mmhub_v1_0.h"
53#include "df_v1_7.h"
54#include "df_v3_6.h"
55#include "vega10_ih.h" 55#include "vega10_ih.h"
56#include "sdma_v4_0.h" 56#include "sdma_v4_0.h"
57#include "uvd_v7_0.h" 57#include "uvd_v7_0.h"
@@ -60,33 +60,6 @@
60#include "dce_virtual.h" 60#include "dce_virtual.h"
61#include "mxgpu_ai.h" 61#include "mxgpu_ai.h"
62 62
63#define mmFabricConfigAccessControl 0x0410
64#define mmFabricConfigAccessControl_BASE_IDX 0
65#define mmFabricConfigAccessControl_DEFAULT 0x00000000
66//FabricConfigAccessControl
67#define FabricConfigAccessControl__CfgRegInstAccEn__SHIFT 0x0
68#define FabricConfigAccessControl__CfgRegInstAccRegLock__SHIFT 0x1
69#define FabricConfigAccessControl__CfgRegInstID__SHIFT 0x10
70#define FabricConfigAccessControl__CfgRegInstAccEn_MASK 0x00000001L
71#define FabricConfigAccessControl__CfgRegInstAccRegLock_MASK 0x00000002L
72#define FabricConfigAccessControl__CfgRegInstID_MASK 0x00FF0000L
73
74
75#define mmDF_PIE_AON0_DfGlobalClkGater 0x00fc
76#define mmDF_PIE_AON0_DfGlobalClkGater_BASE_IDX 0
77//DF_PIE_AON0_DfGlobalClkGater
78#define DF_PIE_AON0_DfGlobalClkGater__MGCGMode__SHIFT 0x0
79#define DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK 0x0000000FL
80
81enum {
82 DF_MGCG_DISABLE = 0,
83 DF_MGCG_ENABLE_00_CYCLE_DELAY =1,
84 DF_MGCG_ENABLE_01_CYCLE_DELAY =2,
85 DF_MGCG_ENABLE_15_CYCLE_DELAY =13,
86 DF_MGCG_ENABLE_31_CYCLE_DELAY =14,
87 DF_MGCG_ENABLE_63_CYCLE_DELAY =15
88};
89
90#define mmMP0_MISC_CGTT_CTRL0 0x01b9 63#define mmMP0_MISC_CGTT_CTRL0 0x01b9
91#define mmMP0_MISC_CGTT_CTRL0_BASE_IDX 0 64#define mmMP0_MISC_CGTT_CTRL0_BASE_IDX 0
92#define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba 65#define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba
@@ -313,6 +286,7 @@ static struct soc15_allowed_register_entry soc15_allowed_read_registers[] = {
313 { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)}, 286 { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)},
314 { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)}, 287 { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)},
315 { SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)}, 288 { SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)},
289 { SOC15_REG_ENTRY(GC, 0, mmDB_DEBUG2)},
316}; 290};
317 291
318static uint32_t soc15_read_indexed_register(struct amdgpu_device *adev, u32 se_num, 292static uint32_t soc15_read_indexed_register(struct amdgpu_device *adev, u32 se_num,
@@ -341,6 +315,8 @@ static uint32_t soc15_get_register_value(struct amdgpu_device *adev,
341 } else { 315 } else {
342 if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) 316 if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG))
343 return adev->gfx.config.gb_addr_config; 317 return adev->gfx.config.gb_addr_config;
318 else if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmDB_DEBUG2))
319 return adev->gfx.config.db_debug2;
344 return RREG32(reg_offset); 320 return RREG32(reg_offset);
345 } 321 }
346} 322}
@@ -512,15 +488,24 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
512 case CHIP_RAVEN: 488 case CHIP_RAVEN:
513 vega10_reg_base_init(adev); 489 vega10_reg_base_init(adev);
514 break; 490 break;
491 case CHIP_VEGA20:
492 vega20_reg_base_init(adev);
493 break;
515 default: 494 default:
516 return -EINVAL; 495 return -EINVAL;
517 } 496 }
518 497
519 if (adev->flags & AMD_IS_APU) 498 if (adev->flags & AMD_IS_APU)
520 adev->nbio_funcs = &nbio_v7_0_funcs; 499 adev->nbio_funcs = &nbio_v7_0_funcs;
500 else if (adev->asic_type == CHIP_VEGA20)
501 adev->nbio_funcs = &nbio_v7_0_funcs;
521 else 502 else
522 adev->nbio_funcs = &nbio_v6_1_funcs; 503 adev->nbio_funcs = &nbio_v6_1_funcs;
523 504
505 if (adev->asic_type == CHIP_VEGA20)
506 adev->df_funcs = &df_v3_6_funcs;
507 else
508 adev->df_funcs = &df_v1_7_funcs;
524 adev->nbio_funcs->detect_hw_virt(adev); 509 adev->nbio_funcs->detect_hw_virt(adev);
525 510
526 if (amdgpu_sriov_vf(adev)) 511 if (amdgpu_sriov_vf(adev))
@@ -529,12 +514,15 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
529 switch (adev->asic_type) { 514 switch (adev->asic_type) {
530 case CHIP_VEGA10: 515 case CHIP_VEGA10:
531 case CHIP_VEGA12: 516 case CHIP_VEGA12:
517 case CHIP_VEGA20:
532 amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); 518 amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
533 amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); 519 amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
534 amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); 520 amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
535 amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); 521 if (adev->asic_type != CHIP_VEGA20) {
536 if (!amdgpu_sriov_vf(adev)) 522 amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
537 amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); 523 if (!amdgpu_sriov_vf(adev))
524 amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
525 }
538 if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) 526 if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
539 amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); 527 amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
540#if defined(CONFIG_DRM_AMD_DC) 528#if defined(CONFIG_DRM_AMD_DC)
@@ -593,6 +581,12 @@ static void soc15_invalidate_hdp(struct amdgpu_device *adev,
593 HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1); 581 HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1);
594} 582}
595 583
584static bool soc15_need_full_reset(struct amdgpu_device *adev)
585{
586 /* change this when we implement soft reset */
587 return true;
588}
589
596static const struct amdgpu_asic_funcs soc15_asic_funcs = 590static const struct amdgpu_asic_funcs soc15_asic_funcs =
597{ 591{
598 .read_disabled_bios = &soc15_read_disabled_bios, 592 .read_disabled_bios = &soc15_read_disabled_bios,
@@ -606,6 +600,7 @@ static const struct amdgpu_asic_funcs soc15_asic_funcs =
606 .get_config_memsize = &soc15_get_config_memsize, 600 .get_config_memsize = &soc15_get_config_memsize,
607 .flush_hdp = &soc15_flush_hdp, 601 .flush_hdp = &soc15_flush_hdp,
608 .invalidate_hdp = &soc15_invalidate_hdp, 602 .invalidate_hdp = &soc15_invalidate_hdp,
603 .need_full_reset = &soc15_need_full_reset,
609}; 604};
610 605
611static int soc15_common_early_init(void *handle) 606static int soc15_common_early_init(void *handle)
@@ -675,6 +670,27 @@ static int soc15_common_early_init(void *handle)
675 adev->pg_flags = 0; 670 adev->pg_flags = 0;
676 adev->external_rev_id = adev->rev_id + 0x14; 671 adev->external_rev_id = adev->rev_id + 0x14;
677 break; 672 break;
673 case CHIP_VEGA20:
674 adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
675 AMD_CG_SUPPORT_GFX_MGLS |
676 AMD_CG_SUPPORT_GFX_CGCG |
677 AMD_CG_SUPPORT_GFX_CGLS |
678 AMD_CG_SUPPORT_GFX_3D_CGCG |
679 AMD_CG_SUPPORT_GFX_3D_CGLS |
680 AMD_CG_SUPPORT_GFX_CP_LS |
681 AMD_CG_SUPPORT_MC_LS |
682 AMD_CG_SUPPORT_MC_MGCG |
683 AMD_CG_SUPPORT_SDMA_MGCG |
684 AMD_CG_SUPPORT_SDMA_LS |
685 AMD_CG_SUPPORT_BIF_MGCG |
686 AMD_CG_SUPPORT_BIF_LS |
687 AMD_CG_SUPPORT_HDP_MGCG |
688 AMD_CG_SUPPORT_ROM_MGCG |
689 AMD_CG_SUPPORT_VCE_MGCG |
690 AMD_CG_SUPPORT_UVD_MGCG;
691 adev->pg_flags = 0;
692 adev->external_rev_id = adev->rev_id + 0x28;
693 break;
678 case CHIP_RAVEN: 694 case CHIP_RAVEN:
679 adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 695 adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
680 AMD_CG_SUPPORT_GFX_MGLS | 696 AMD_CG_SUPPORT_GFX_MGLS |
@@ -694,8 +710,15 @@ static int soc15_common_early_init(void *handle)
694 AMD_CG_SUPPORT_MC_MGCG | 710 AMD_CG_SUPPORT_MC_MGCG |
695 AMD_CG_SUPPORT_MC_LS | 711 AMD_CG_SUPPORT_MC_LS |
696 AMD_CG_SUPPORT_SDMA_MGCG | 712 AMD_CG_SUPPORT_SDMA_MGCG |
697 AMD_CG_SUPPORT_SDMA_LS; 713 AMD_CG_SUPPORT_SDMA_LS |
698 adev->pg_flags = AMD_PG_SUPPORT_SDMA; 714 AMD_CG_SUPPORT_VCN_MGCG;
715
716 adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN;
717
718 if (adev->powerplay.pp_feature & PP_GFXOFF_MASK)
719 adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
720 AMD_PG_SUPPORT_CP |
721 AMD_PG_SUPPORT_RLC_SMU_HS;
699 722
700 adev->external_rev_id = 0x1; 723 adev->external_rev_id = 0x1;
701 break; 724 break;
@@ -871,32 +894,6 @@ static void soc15_update_rom_medium_grain_clock_gating(struct amdgpu_device *ade
871 WREG32(SOC15_REG_OFFSET(SMUIO, 0, mmCGTT_ROM_CLK_CTRL0), data); 894 WREG32(SOC15_REG_OFFSET(SMUIO, 0, mmCGTT_ROM_CLK_CTRL0), data);
872} 895}
873 896
874static void soc15_update_df_medium_grain_clock_gating(struct amdgpu_device *adev,
875 bool enable)
876{
877 uint32_t data;
878
879 /* Put DF on broadcast mode */
880 data = RREG32(SOC15_REG_OFFSET(DF, 0, mmFabricConfigAccessControl));
881 data &= ~FabricConfigAccessControl__CfgRegInstAccEn_MASK;
882 WREG32(SOC15_REG_OFFSET(DF, 0, mmFabricConfigAccessControl), data);
883
884 if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG)) {
885 data = RREG32(SOC15_REG_OFFSET(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater));
886 data &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
887 data |= DF_MGCG_ENABLE_15_CYCLE_DELAY;
888 WREG32(SOC15_REG_OFFSET(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater), data);
889 } else {
890 data = RREG32(SOC15_REG_OFFSET(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater));
891 data &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
892 data |= DF_MGCG_DISABLE;
893 WREG32(SOC15_REG_OFFSET(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater), data);
894 }
895
896 WREG32(SOC15_REG_OFFSET(DF, 0, mmFabricConfigAccessControl),
897 mmFabricConfigAccessControl_DEFAULT);
898}
899
900static int soc15_common_set_clockgating_state(void *handle, 897static int soc15_common_set_clockgating_state(void *handle,
901 enum amd_clockgating_state state) 898 enum amd_clockgating_state state)
902{ 899{
@@ -908,6 +905,7 @@ static int soc15_common_set_clockgating_state(void *handle,
908 switch (adev->asic_type) { 905 switch (adev->asic_type) {
909 case CHIP_VEGA10: 906 case CHIP_VEGA10:
910 case CHIP_VEGA12: 907 case CHIP_VEGA12:
908 case CHIP_VEGA20:
911 adev->nbio_funcs->update_medium_grain_clock_gating(adev, 909 adev->nbio_funcs->update_medium_grain_clock_gating(adev,
912 state == AMD_CG_STATE_GATE ? true : false); 910 state == AMD_CG_STATE_GATE ? true : false);
913 adev->nbio_funcs->update_medium_grain_light_sleep(adev, 911 adev->nbio_funcs->update_medium_grain_light_sleep(adev,
@@ -920,7 +918,7 @@ static int soc15_common_set_clockgating_state(void *handle,
920 state == AMD_CG_STATE_GATE ? true : false); 918 state == AMD_CG_STATE_GATE ? true : false);
921 soc15_update_rom_medium_grain_clock_gating(adev, 919 soc15_update_rom_medium_grain_clock_gating(adev,
922 state == AMD_CG_STATE_GATE ? true : false); 920 state == AMD_CG_STATE_GATE ? true : false);
923 soc15_update_df_medium_grain_clock_gating(adev, 921 adev->df_funcs->update_medium_grain_clock_gating(adev,
924 state == AMD_CG_STATE_GATE ? true : false); 922 state == AMD_CG_STATE_GATE ? true : false);
925 break; 923 break;
926 case CHIP_RAVEN: 924 case CHIP_RAVEN:
@@ -973,10 +971,7 @@ static void soc15_common_get_clockgating_state(void *handle, u32 *flags)
973 if (!(data & CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK)) 971 if (!(data & CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK))
974 *flags |= AMD_CG_SUPPORT_ROM_MGCG; 972 *flags |= AMD_CG_SUPPORT_ROM_MGCG;
975 973
976 /* AMD_CG_SUPPORT_DF_MGCG */ 974 adev->df_funcs->get_clockgating_state(adev, flags);
977 data = RREG32(SOC15_REG_OFFSET(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater));
978 if (data & DF_MGCG_ENABLE_15_CYCLE_DELAY)
979 *flags |= AMD_CG_SUPPORT_DF_MGCG;
980} 975}
981 976
982static int soc15_common_set_powergating_state(void *handle, 977static int soc15_common_set_powergating_state(void *handle,
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.h b/drivers/gpu/drm/amd/amdgpu/soc15.h
index f70da8a29f86..1f714b7af520 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.h
@@ -55,5 +55,6 @@ void soc15_program_register_sequence(struct amdgpu_device *adev,
55 const u32 array_size); 55 const u32 array_size);
56 56
57int vega10_reg_base_init(struct amdgpu_device *adev); 57int vega10_reg_base_init(struct amdgpu_device *adev);
58int vega20_reg_base_init(struct amdgpu_device *adev);
58 59
59#endif 60#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
index def865067edd..0942f492d2e1 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
@@ -47,6 +47,21 @@
47#define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \ 47#define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \
48 WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, value) 48 WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, value)
49 49
50#define SOC15_WAIT_ON_RREG(ip, inst, reg, expected_value, mask, ret) \
51 do { \
52 uint32_t tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \
53 uint32_t loop = adev->usec_timeout; \
54 while ((tmp_ & (mask)) != (expected_value)) { \
55 udelay(2); \
56 tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \
57 loop--; \
58 if (!loop) { \
59 ret = -ETIMEDOUT; \
60 break; \
61 } \
62 } \
63 } while (0)
64
50#endif 65#endif
51 66
52 67
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15d.h b/drivers/gpu/drm/amd/amdgpu/soc15d.h
index 7f408f85fdb6..8dc29107228f 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15d.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15d.h
@@ -159,6 +159,7 @@
159#define EOP_TC_WB_ACTION_EN (1 << 15) /* L2 */ 159#define EOP_TC_WB_ACTION_EN (1 << 15) /* L2 */
160#define EOP_TCL1_ACTION_EN (1 << 16) 160#define EOP_TCL1_ACTION_EN (1 << 16)
161#define EOP_TC_ACTION_EN (1 << 17) /* L2 */ 161#define EOP_TC_ACTION_EN (1 << 17) /* L2 */
162#define EOP_TC_NC_ACTION_EN (1 << 19)
162#define EOP_TC_MD_ACTION_EN (1 << 21) /* L2 metadata */ 163#define EOP_TC_MD_ACTION_EN (1 << 21) /* L2 metadata */
163 164
164#define DATA_SEL(x) ((x) << 29) 165#define DATA_SEL(x) ((x) << 29)
@@ -268,6 +269,11 @@
268 * x=1: tmz_end 269 * x=1: tmz_end
269 */ 270 */
270 271
272#define PACKET3_INVALIDATE_TLBS 0x98
273# define PACKET3_INVALIDATE_TLBS_DST_SEL(x) ((x) << 0)
274# define PACKET3_INVALIDATE_TLBS_ALL_HUB(x) ((x) << 4)
275# define PACKET3_INVALIDATE_TLBS_PASID(x) ((x) << 5)
276# define PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(x) ((x) << 29)
271#define PACKET3_SET_RESOURCES 0xA0 277#define PACKET3_SET_RESOURCES 0xA0
272/* 1. header 278/* 1. header
273 * 2. CONTROL 279 * 2. CONTROL
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
index 948bb9437757..6fed3d7797a8 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
@@ -93,6 +93,7 @@ static void uvd_v4_2_ring_set_wptr(struct amdgpu_ring *ring)
93static int uvd_v4_2_early_init(void *handle) 93static int uvd_v4_2_early_init(void *handle)
94{ 94{
95 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 95 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
96 adev->uvd.num_uvd_inst = 1;
96 97
97 uvd_v4_2_set_ring_funcs(adev); 98 uvd_v4_2_set_ring_funcs(adev);
98 uvd_v4_2_set_irq_funcs(adev); 99 uvd_v4_2_set_irq_funcs(adev);
@@ -107,7 +108,7 @@ static int uvd_v4_2_sw_init(void *handle)
107 int r; 108 int r;
108 109
109 /* UVD TRAP */ 110 /* UVD TRAP */
110 r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.irq); 111 r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq);
111 if (r) 112 if (r)
112 return r; 113 return r;
113 114
@@ -119,9 +120,9 @@ static int uvd_v4_2_sw_init(void *handle)
119 if (r) 120 if (r)
120 return r; 121 return r;
121 122
122 ring = &adev->uvd.ring; 123 ring = &adev->uvd.inst->ring;
123 sprintf(ring->name, "uvd"); 124 sprintf(ring->name, "uvd");
124 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); 125 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
125 126
126 return r; 127 return r;
127} 128}
@@ -150,7 +151,7 @@ static void uvd_v4_2_enable_mgcg(struct amdgpu_device *adev,
150static int uvd_v4_2_hw_init(void *handle) 151static int uvd_v4_2_hw_init(void *handle)
151{ 152{
152 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 153 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
153 struct amdgpu_ring *ring = &adev->uvd.ring; 154 struct amdgpu_ring *ring = &adev->uvd.inst->ring;
154 uint32_t tmp; 155 uint32_t tmp;
155 int r; 156 int r;
156 157
@@ -208,7 +209,7 @@ done:
208static int uvd_v4_2_hw_fini(void *handle) 209static int uvd_v4_2_hw_fini(void *handle)
209{ 210{
210 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 211 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
211 struct amdgpu_ring *ring = &adev->uvd.ring; 212 struct amdgpu_ring *ring = &adev->uvd.inst->ring;
212 213
213 if (RREG32(mmUVD_STATUS) != 0) 214 if (RREG32(mmUVD_STATUS) != 0)
214 uvd_v4_2_stop(adev); 215 uvd_v4_2_stop(adev);
@@ -251,7 +252,7 @@ static int uvd_v4_2_resume(void *handle)
251 */ 252 */
252static int uvd_v4_2_start(struct amdgpu_device *adev) 253static int uvd_v4_2_start(struct amdgpu_device *adev)
253{ 254{
254 struct amdgpu_ring *ring = &adev->uvd.ring; 255 struct amdgpu_ring *ring = &adev->uvd.inst->ring;
255 uint32_t rb_bufsz; 256 uint32_t rb_bufsz;
256 int i, j, r; 257 int i, j, r;
257 u32 tmp; 258 u32 tmp;
@@ -523,6 +524,18 @@ static void uvd_v4_2_ring_emit_ib(struct amdgpu_ring *ring,
523 amdgpu_ring_write(ring, ib->length_dw); 524 amdgpu_ring_write(ring, ib->length_dw);
524} 525}
525 526
527static void uvd_v4_2_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
528{
529 int i;
530
531 WARN_ON(ring->wptr % 2 || count % 2);
532
533 for (i = 0; i < count / 2; i++) {
534 amdgpu_ring_write(ring, PACKET0(mmUVD_NO_OP, 0));
535 amdgpu_ring_write(ring, 0);
536 }
537}
538
526/** 539/**
527 * uvd_v4_2_mc_resume - memory controller programming 540 * uvd_v4_2_mc_resume - memory controller programming
528 * 541 *
@@ -536,7 +549,7 @@ static void uvd_v4_2_mc_resume(struct amdgpu_device *adev)
536 uint32_t size; 549 uint32_t size;
537 550
538 /* programm the VCPU memory controller bits 0-27 */ 551 /* programm the VCPU memory controller bits 0-27 */
539 addr = (adev->uvd.gpu_addr + AMDGPU_UVD_FIRMWARE_OFFSET) >> 3; 552 addr = (adev->uvd.inst->gpu_addr + AMDGPU_UVD_FIRMWARE_OFFSET) >> 3;
540 size = AMDGPU_UVD_FIRMWARE_SIZE(adev) >> 3; 553 size = AMDGPU_UVD_FIRMWARE_SIZE(adev) >> 3;
541 WREG32(mmUVD_VCPU_CACHE_OFFSET0, addr); 554 WREG32(mmUVD_VCPU_CACHE_OFFSET0, addr);
542 WREG32(mmUVD_VCPU_CACHE_SIZE0, size); 555 WREG32(mmUVD_VCPU_CACHE_SIZE0, size);
@@ -553,11 +566,11 @@ static void uvd_v4_2_mc_resume(struct amdgpu_device *adev)
553 WREG32(mmUVD_VCPU_CACHE_SIZE2, size); 566 WREG32(mmUVD_VCPU_CACHE_SIZE2, size);
554 567
555 /* bits 28-31 */ 568 /* bits 28-31 */
556 addr = (adev->uvd.gpu_addr >> 28) & 0xF; 569 addr = (adev->uvd.inst->gpu_addr >> 28) & 0xF;
557 WREG32(mmUVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0)); 570 WREG32(mmUVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
558 571
559 /* bits 32-39 */ 572 /* bits 32-39 */
560 addr = (adev->uvd.gpu_addr >> 32) & 0xFF; 573 addr = (adev->uvd.inst->gpu_addr >> 32) & 0xFF;
561 WREG32(mmUVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); 574 WREG32(mmUVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
562 575
563 WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config); 576 WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
@@ -664,7 +677,7 @@ static int uvd_v4_2_process_interrupt(struct amdgpu_device *adev,
664 struct amdgpu_iv_entry *entry) 677 struct amdgpu_iv_entry *entry)
665{ 678{
666 DRM_DEBUG("IH: UVD TRAP\n"); 679 DRM_DEBUG("IH: UVD TRAP\n");
667 amdgpu_fence_process(&adev->uvd.ring); 680 amdgpu_fence_process(&adev->uvd.inst->ring);
668 return 0; 681 return 0;
669} 682}
670 683
@@ -688,7 +701,7 @@ static int uvd_v4_2_set_powergating_state(void *handle,
688 701
689 if (state == AMD_PG_STATE_GATE) { 702 if (state == AMD_PG_STATE_GATE) {
690 uvd_v4_2_stop(adev); 703 uvd_v4_2_stop(adev);
691 if (adev->pg_flags & AMD_PG_SUPPORT_UVD && amdgpu_dpm == 0) { 704 if (adev->pg_flags & AMD_PG_SUPPORT_UVD && !adev->pm.dpm_enabled) {
692 if (!(RREG32_SMC(ixCURRENT_PG_STATUS) & 705 if (!(RREG32_SMC(ixCURRENT_PG_STATUS) &
693 CURRENT_PG_STATUS__UVD_PG_STATUS_MASK)) { 706 CURRENT_PG_STATUS__UVD_PG_STATUS_MASK)) {
694 WREG32(mmUVD_PGFSM_CONFIG, (UVD_PGFSM_CONFIG__UVD_PGFSM_FSM_ADDR_MASK | 707 WREG32(mmUVD_PGFSM_CONFIG, (UVD_PGFSM_CONFIG__UVD_PGFSM_FSM_ADDR_MASK |
@@ -699,7 +712,7 @@ static int uvd_v4_2_set_powergating_state(void *handle,
699 } 712 }
700 return 0; 713 return 0;
701 } else { 714 } else {
702 if (adev->pg_flags & AMD_PG_SUPPORT_UVD && amdgpu_dpm == 0) { 715 if (adev->pg_flags & AMD_PG_SUPPORT_UVD && !adev->pm.dpm_enabled) {
703 if (RREG32_SMC(ixCURRENT_PG_STATUS) & 716 if (RREG32_SMC(ixCURRENT_PG_STATUS) &
704 CURRENT_PG_STATUS__UVD_PG_STATUS_MASK) { 717 CURRENT_PG_STATUS__UVD_PG_STATUS_MASK) {
705 WREG32(mmUVD_PGFSM_CONFIG, (UVD_PGFSM_CONFIG__UVD_PGFSM_FSM_ADDR_MASK | 718 WREG32(mmUVD_PGFSM_CONFIG, (UVD_PGFSM_CONFIG__UVD_PGFSM_FSM_ADDR_MASK |
@@ -732,7 +745,6 @@ static const struct amd_ip_funcs uvd_v4_2_ip_funcs = {
732static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = { 745static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = {
733 .type = AMDGPU_RING_TYPE_UVD, 746 .type = AMDGPU_RING_TYPE_UVD,
734 .align_mask = 0xf, 747 .align_mask = 0xf,
735 .nop = PACKET0(mmUVD_NO_OP, 0),
736 .support_64bit_ptrs = false, 748 .support_64bit_ptrs = false,
737 .get_rptr = uvd_v4_2_ring_get_rptr, 749 .get_rptr = uvd_v4_2_ring_get_rptr,
738 .get_wptr = uvd_v4_2_ring_get_wptr, 750 .get_wptr = uvd_v4_2_ring_get_wptr,
@@ -745,7 +757,7 @@ static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = {
745 .emit_fence = uvd_v4_2_ring_emit_fence, 757 .emit_fence = uvd_v4_2_ring_emit_fence,
746 .test_ring = uvd_v4_2_ring_test_ring, 758 .test_ring = uvd_v4_2_ring_test_ring,
747 .test_ib = amdgpu_uvd_ring_test_ib, 759 .test_ib = amdgpu_uvd_ring_test_ib,
748 .insert_nop = amdgpu_ring_insert_nop, 760 .insert_nop = uvd_v4_2_ring_insert_nop,
749 .pad_ib = amdgpu_ring_generic_pad_ib, 761 .pad_ib = amdgpu_ring_generic_pad_ib,
750 .begin_use = amdgpu_uvd_ring_begin_use, 762 .begin_use = amdgpu_uvd_ring_begin_use,
751 .end_use = amdgpu_uvd_ring_end_use, 763 .end_use = amdgpu_uvd_ring_end_use,
@@ -753,7 +765,7 @@ static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = {
753 765
754static void uvd_v4_2_set_ring_funcs(struct amdgpu_device *adev) 766static void uvd_v4_2_set_ring_funcs(struct amdgpu_device *adev)
755{ 767{
756 adev->uvd.ring.funcs = &uvd_v4_2_ring_funcs; 768 adev->uvd.inst->ring.funcs = &uvd_v4_2_ring_funcs;
757} 769}
758 770
759static const struct amdgpu_irq_src_funcs uvd_v4_2_irq_funcs = { 771static const struct amdgpu_irq_src_funcs uvd_v4_2_irq_funcs = {
@@ -763,8 +775,8 @@ static const struct amdgpu_irq_src_funcs uvd_v4_2_irq_funcs = {
763 775
764static void uvd_v4_2_set_irq_funcs(struct amdgpu_device *adev) 776static void uvd_v4_2_set_irq_funcs(struct amdgpu_device *adev)
765{ 777{
766 adev->uvd.irq.num_types = 1; 778 adev->uvd.inst->irq.num_types = 1;
767 adev->uvd.irq.funcs = &uvd_v4_2_irq_funcs; 779 adev->uvd.inst->irq.funcs = &uvd_v4_2_irq_funcs;
768} 780}
769 781
770const struct amdgpu_ip_block_version uvd_v4_2_ip_block = 782const struct amdgpu_ip_block_version uvd_v4_2_ip_block =
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
index 6445d55e7d5a..341ee6d55ce8 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
@@ -89,6 +89,7 @@ static void uvd_v5_0_ring_set_wptr(struct amdgpu_ring *ring)
89static int uvd_v5_0_early_init(void *handle) 89static int uvd_v5_0_early_init(void *handle)
90{ 90{
91 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 91 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
92 adev->uvd.num_uvd_inst = 1;
92 93
93 uvd_v5_0_set_ring_funcs(adev); 94 uvd_v5_0_set_ring_funcs(adev);
94 uvd_v5_0_set_irq_funcs(adev); 95 uvd_v5_0_set_irq_funcs(adev);
@@ -103,7 +104,7 @@ static int uvd_v5_0_sw_init(void *handle)
103 int r; 104 int r;
104 105
105 /* UVD TRAP */ 106 /* UVD TRAP */
106 r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.irq); 107 r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq);
107 if (r) 108 if (r)
108 return r; 109 return r;
109 110
@@ -115,9 +116,9 @@ static int uvd_v5_0_sw_init(void *handle)
115 if (r) 116 if (r)
116 return r; 117 return r;
117 118
118 ring = &adev->uvd.ring; 119 ring = &adev->uvd.inst->ring;
119 sprintf(ring->name, "uvd"); 120 sprintf(ring->name, "uvd");
120 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); 121 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
121 122
122 return r; 123 return r;
123} 124}
@@ -144,7 +145,7 @@ static int uvd_v5_0_sw_fini(void *handle)
144static int uvd_v5_0_hw_init(void *handle) 145static int uvd_v5_0_hw_init(void *handle)
145{ 146{
146 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 147 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
147 struct amdgpu_ring *ring = &adev->uvd.ring; 148 struct amdgpu_ring *ring = &adev->uvd.inst->ring;
148 uint32_t tmp; 149 uint32_t tmp;
149 int r; 150 int r;
150 151
@@ -204,7 +205,7 @@ done:
204static int uvd_v5_0_hw_fini(void *handle) 205static int uvd_v5_0_hw_fini(void *handle)
205{ 206{
206 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 207 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
207 struct amdgpu_ring *ring = &adev->uvd.ring; 208 struct amdgpu_ring *ring = &adev->uvd.inst->ring;
208 209
209 if (RREG32(mmUVD_STATUS) != 0) 210 if (RREG32(mmUVD_STATUS) != 0)
210 uvd_v5_0_stop(adev); 211 uvd_v5_0_stop(adev);
@@ -253,9 +254,9 @@ static void uvd_v5_0_mc_resume(struct amdgpu_device *adev)
253 254
254 /* programm memory controller bits 0-27 */ 255 /* programm memory controller bits 0-27 */
255 WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 256 WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
256 lower_32_bits(adev->uvd.gpu_addr)); 257 lower_32_bits(adev->uvd.inst->gpu_addr));
257 WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 258 WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
258 upper_32_bits(adev->uvd.gpu_addr)); 259 upper_32_bits(adev->uvd.inst->gpu_addr));
259 260
260 offset = AMDGPU_UVD_FIRMWARE_OFFSET; 261 offset = AMDGPU_UVD_FIRMWARE_OFFSET;
261 size = AMDGPU_UVD_FIRMWARE_SIZE(adev); 262 size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
@@ -287,7 +288,7 @@ static void uvd_v5_0_mc_resume(struct amdgpu_device *adev)
287 */ 288 */
288static int uvd_v5_0_start(struct amdgpu_device *adev) 289static int uvd_v5_0_start(struct amdgpu_device *adev)
289{ 290{
290 struct amdgpu_ring *ring = &adev->uvd.ring; 291 struct amdgpu_ring *ring = &adev->uvd.inst->ring;
291 uint32_t rb_bufsz, tmp; 292 uint32_t rb_bufsz, tmp;
292 uint32_t lmi_swap_cntl; 293 uint32_t lmi_swap_cntl;
293 uint32_t mp_swap_cntl; 294 uint32_t mp_swap_cntl;
@@ -540,6 +541,18 @@ static void uvd_v5_0_ring_emit_ib(struct amdgpu_ring *ring,
540 amdgpu_ring_write(ring, ib->length_dw); 541 amdgpu_ring_write(ring, ib->length_dw);
541} 542}
542 543
544static void uvd_v5_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
545{
546 int i;
547
548 WARN_ON(ring->wptr % 2 || count % 2);
549
550 for (i = 0; i < count / 2; i++) {
551 amdgpu_ring_write(ring, PACKET0(mmUVD_NO_OP, 0));
552 amdgpu_ring_write(ring, 0);
553 }
554}
555
543static bool uvd_v5_0_is_idle(void *handle) 556static bool uvd_v5_0_is_idle(void *handle)
544{ 557{
545 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 558 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -586,7 +599,7 @@ static int uvd_v5_0_process_interrupt(struct amdgpu_device *adev,
586 struct amdgpu_iv_entry *entry) 599 struct amdgpu_iv_entry *entry)
587{ 600{
588 DRM_DEBUG("IH: UVD TRAP\n"); 601 DRM_DEBUG("IH: UVD TRAP\n");
589 amdgpu_fence_process(&adev->uvd.ring); 602 amdgpu_fence_process(&adev->uvd.inst->ring);
590 return 0; 603 return 0;
591} 604}
592 605
@@ -840,7 +853,6 @@ static const struct amd_ip_funcs uvd_v5_0_ip_funcs = {
840static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = { 853static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = {
841 .type = AMDGPU_RING_TYPE_UVD, 854 .type = AMDGPU_RING_TYPE_UVD,
842 .align_mask = 0xf, 855 .align_mask = 0xf,
843 .nop = PACKET0(mmUVD_NO_OP, 0),
844 .support_64bit_ptrs = false, 856 .support_64bit_ptrs = false,
845 .get_rptr = uvd_v5_0_ring_get_rptr, 857 .get_rptr = uvd_v5_0_ring_get_rptr,
846 .get_wptr = uvd_v5_0_ring_get_wptr, 858 .get_wptr = uvd_v5_0_ring_get_wptr,
@@ -853,7 +865,7 @@ static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = {
853 .emit_fence = uvd_v5_0_ring_emit_fence, 865 .emit_fence = uvd_v5_0_ring_emit_fence,
854 .test_ring = uvd_v5_0_ring_test_ring, 866 .test_ring = uvd_v5_0_ring_test_ring,
855 .test_ib = amdgpu_uvd_ring_test_ib, 867 .test_ib = amdgpu_uvd_ring_test_ib,
856 .insert_nop = amdgpu_ring_insert_nop, 868 .insert_nop = uvd_v5_0_ring_insert_nop,
857 .pad_ib = amdgpu_ring_generic_pad_ib, 869 .pad_ib = amdgpu_ring_generic_pad_ib,
858 .begin_use = amdgpu_uvd_ring_begin_use, 870 .begin_use = amdgpu_uvd_ring_begin_use,
859 .end_use = amdgpu_uvd_ring_end_use, 871 .end_use = amdgpu_uvd_ring_end_use,
@@ -861,7 +873,7 @@ static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = {
861 873
862static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev) 874static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev)
863{ 875{
864 adev->uvd.ring.funcs = &uvd_v5_0_ring_funcs; 876 adev->uvd.inst->ring.funcs = &uvd_v5_0_ring_funcs;
865} 877}
866 878
867static const struct amdgpu_irq_src_funcs uvd_v5_0_irq_funcs = { 879static const struct amdgpu_irq_src_funcs uvd_v5_0_irq_funcs = {
@@ -871,8 +883,8 @@ static const struct amdgpu_irq_src_funcs uvd_v5_0_irq_funcs = {
871 883
872static void uvd_v5_0_set_irq_funcs(struct amdgpu_device *adev) 884static void uvd_v5_0_set_irq_funcs(struct amdgpu_device *adev)
873{ 885{
874 adev->uvd.irq.num_types = 1; 886 adev->uvd.inst->irq.num_types = 1;
875 adev->uvd.irq.funcs = &uvd_v5_0_irq_funcs; 887 adev->uvd.inst->irq.funcs = &uvd_v5_0_irq_funcs;
876} 888}
877 889
878const struct amdgpu_ip_block_version uvd_v5_0_ip_block = 890const struct amdgpu_ip_block_version uvd_v5_0_ip_block =
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
index f26f515db2fb..bfddf97dd13e 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
@@ -62,7 +62,7 @@ static void uvd_v6_0_enable_mgcg(struct amdgpu_device *adev,
62static inline bool uvd_v6_0_enc_support(struct amdgpu_device *adev) 62static inline bool uvd_v6_0_enc_support(struct amdgpu_device *adev)
63{ 63{
64 return ((adev->asic_type >= CHIP_POLARIS10) && 64 return ((adev->asic_type >= CHIP_POLARIS10) &&
65 (adev->asic_type <= CHIP_POLARIS12) && 65 (adev->asic_type <= CHIP_VEGAM) &&
66 (!adev->uvd.fw_version || adev->uvd.fw_version >= FW_1_130_16)); 66 (!adev->uvd.fw_version || adev->uvd.fw_version >= FW_1_130_16));
67} 67}
68 68
@@ -91,7 +91,7 @@ static uint64_t uvd_v6_0_enc_ring_get_rptr(struct amdgpu_ring *ring)
91{ 91{
92 struct amdgpu_device *adev = ring->adev; 92 struct amdgpu_device *adev = ring->adev;
93 93
94 if (ring == &adev->uvd.ring_enc[0]) 94 if (ring == &adev->uvd.inst->ring_enc[0])
95 return RREG32(mmUVD_RB_RPTR); 95 return RREG32(mmUVD_RB_RPTR);
96 else 96 else
97 return RREG32(mmUVD_RB_RPTR2); 97 return RREG32(mmUVD_RB_RPTR2);
@@ -121,7 +121,7 @@ static uint64_t uvd_v6_0_enc_ring_get_wptr(struct amdgpu_ring *ring)
121{ 121{
122 struct amdgpu_device *adev = ring->adev; 122 struct amdgpu_device *adev = ring->adev;
123 123
124 if (ring == &adev->uvd.ring_enc[0]) 124 if (ring == &adev->uvd.inst->ring_enc[0])
125 return RREG32(mmUVD_RB_WPTR); 125 return RREG32(mmUVD_RB_WPTR);
126 else 126 else
127 return RREG32(mmUVD_RB_WPTR2); 127 return RREG32(mmUVD_RB_WPTR2);
@@ -152,7 +152,7 @@ static void uvd_v6_0_enc_ring_set_wptr(struct amdgpu_ring *ring)
152{ 152{
153 struct amdgpu_device *adev = ring->adev; 153 struct amdgpu_device *adev = ring->adev;
154 154
155 if (ring == &adev->uvd.ring_enc[0]) 155 if (ring == &adev->uvd.inst->ring_enc[0])
156 WREG32(mmUVD_RB_WPTR, 156 WREG32(mmUVD_RB_WPTR,
157 lower_32_bits(ring->wptr)); 157 lower_32_bits(ring->wptr));
158 else 158 else
@@ -375,6 +375,7 @@ error:
375static int uvd_v6_0_early_init(void *handle) 375static int uvd_v6_0_early_init(void *handle)
376{ 376{
377 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 377 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
378 adev->uvd.num_uvd_inst = 1;
378 379
379 if (!(adev->flags & AMD_IS_APU) && 380 if (!(adev->flags & AMD_IS_APU) &&
380 (RREG32_SMC(ixCC_HARVEST_FUSES) & CC_HARVEST_FUSES__UVD_DISABLE_MASK)) 381 (RREG32_SMC(ixCC_HARVEST_FUSES) & CC_HARVEST_FUSES__UVD_DISABLE_MASK))
@@ -399,14 +400,14 @@ static int uvd_v6_0_sw_init(void *handle)
399 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 400 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
400 401
401 /* UVD TRAP */ 402 /* UVD TRAP */
402 r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.irq); 403 r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq);
403 if (r) 404 if (r)
404 return r; 405 return r;
405 406
406 /* UVD ENC TRAP */ 407 /* UVD ENC TRAP */
407 if (uvd_v6_0_enc_support(adev)) { 408 if (uvd_v6_0_enc_support(adev)) {
408 for (i = 0; i < adev->uvd.num_enc_rings; ++i) { 409 for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
409 r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 119, &adev->uvd.irq); 410 r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 119, &adev->uvd.inst->irq);
410 if (r) 411 if (r)
411 return r; 412 return r;
412 } 413 }
@@ -418,18 +419,18 @@ static int uvd_v6_0_sw_init(void *handle)
418 419
419 if (!uvd_v6_0_enc_support(adev)) { 420 if (!uvd_v6_0_enc_support(adev)) {
420 for (i = 0; i < adev->uvd.num_enc_rings; ++i) 421 for (i = 0; i < adev->uvd.num_enc_rings; ++i)
421 adev->uvd.ring_enc[i].funcs = NULL; 422 adev->uvd.inst->ring_enc[i].funcs = NULL;
422 423
423 adev->uvd.irq.num_types = 1; 424 adev->uvd.inst->irq.num_types = 1;
424 adev->uvd.num_enc_rings = 0; 425 adev->uvd.num_enc_rings = 0;
425 426
426 DRM_INFO("UVD ENC is disabled\n"); 427 DRM_INFO("UVD ENC is disabled\n");
427 } else { 428 } else {
428 struct drm_sched_rq *rq; 429 struct drm_sched_rq *rq;
429 ring = &adev->uvd.ring_enc[0]; 430 ring = &adev->uvd.inst->ring_enc[0];
430 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 431 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL];
431 r = drm_sched_entity_init(&ring->sched, &adev->uvd.entity_enc, 432 r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst->entity_enc,
432 rq, amdgpu_sched_jobs, NULL); 433 rq, NULL);
433 if (r) { 434 if (r) {
434 DRM_ERROR("Failed setting up UVD ENC run queue.\n"); 435 DRM_ERROR("Failed setting up UVD ENC run queue.\n");
435 return r; 436 return r;
@@ -440,17 +441,17 @@ static int uvd_v6_0_sw_init(void *handle)
440 if (r) 441 if (r)
441 return r; 442 return r;
442 443
443 ring = &adev->uvd.ring; 444 ring = &adev->uvd.inst->ring;
444 sprintf(ring->name, "uvd"); 445 sprintf(ring->name, "uvd");
445 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); 446 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
446 if (r) 447 if (r)
447 return r; 448 return r;
448 449
449 if (uvd_v6_0_enc_support(adev)) { 450 if (uvd_v6_0_enc_support(adev)) {
450 for (i = 0; i < adev->uvd.num_enc_rings; ++i) { 451 for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
451 ring = &adev->uvd.ring_enc[i]; 452 ring = &adev->uvd.inst->ring_enc[i];
452 sprintf(ring->name, "uvd_enc%d", i); 453 sprintf(ring->name, "uvd_enc%d", i);
453 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); 454 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
454 if (r) 455 if (r)
455 return r; 456 return r;
456 } 457 }
@@ -469,10 +470,10 @@ static int uvd_v6_0_sw_fini(void *handle)
469 return r; 470 return r;
470 471
471 if (uvd_v6_0_enc_support(adev)) { 472 if (uvd_v6_0_enc_support(adev)) {
472 drm_sched_entity_fini(&adev->uvd.ring_enc[0].sched, &adev->uvd.entity_enc); 473 drm_sched_entity_fini(&adev->uvd.inst->ring_enc[0].sched, &adev->uvd.inst->entity_enc);
473 474
474 for (i = 0; i < adev->uvd.num_enc_rings; ++i) 475 for (i = 0; i < adev->uvd.num_enc_rings; ++i)
475 amdgpu_ring_fini(&adev->uvd.ring_enc[i]); 476 amdgpu_ring_fini(&adev->uvd.inst->ring_enc[i]);
476 } 477 }
477 478
478 return amdgpu_uvd_sw_fini(adev); 479 return amdgpu_uvd_sw_fini(adev);
@@ -488,7 +489,7 @@ static int uvd_v6_0_sw_fini(void *handle)
488static int uvd_v6_0_hw_init(void *handle) 489static int uvd_v6_0_hw_init(void *handle)
489{ 490{
490 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 491 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
491 struct amdgpu_ring *ring = &adev->uvd.ring; 492 struct amdgpu_ring *ring = &adev->uvd.inst->ring;
492 uint32_t tmp; 493 uint32_t tmp;
493 int i, r; 494 int i, r;
494 495
@@ -532,7 +533,7 @@ static int uvd_v6_0_hw_init(void *handle)
532 533
533 if (uvd_v6_0_enc_support(adev)) { 534 if (uvd_v6_0_enc_support(adev)) {
534 for (i = 0; i < adev->uvd.num_enc_rings; ++i) { 535 for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
535 ring = &adev->uvd.ring_enc[i]; 536 ring = &adev->uvd.inst->ring_enc[i];
536 ring->ready = true; 537 ring->ready = true;
537 r = amdgpu_ring_test_ring(ring); 538 r = amdgpu_ring_test_ring(ring);
538 if (r) { 539 if (r) {
@@ -563,7 +564,7 @@ done:
563static int uvd_v6_0_hw_fini(void *handle) 564static int uvd_v6_0_hw_fini(void *handle)
564{ 565{
565 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 566 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
566 struct amdgpu_ring *ring = &adev->uvd.ring; 567 struct amdgpu_ring *ring = &adev->uvd.inst->ring;
567 568
568 if (RREG32(mmUVD_STATUS) != 0) 569 if (RREG32(mmUVD_STATUS) != 0)
569 uvd_v6_0_stop(adev); 570 uvd_v6_0_stop(adev);
@@ -611,9 +612,9 @@ static void uvd_v6_0_mc_resume(struct amdgpu_device *adev)
611 612
612 /* programm memory controller bits 0-27 */ 613 /* programm memory controller bits 0-27 */
613 WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 614 WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
614 lower_32_bits(adev->uvd.gpu_addr)); 615 lower_32_bits(adev->uvd.inst->gpu_addr));
615 WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 616 WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
616 upper_32_bits(adev->uvd.gpu_addr)); 617 upper_32_bits(adev->uvd.inst->gpu_addr));
617 618
618 offset = AMDGPU_UVD_FIRMWARE_OFFSET; 619 offset = AMDGPU_UVD_FIRMWARE_OFFSET;
619 size = AMDGPU_UVD_FIRMWARE_SIZE(adev); 620 size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
@@ -726,7 +727,7 @@ static void cz_set_uvd_clock_gating_branches(struct amdgpu_device *adev,
726 */ 727 */
727static int uvd_v6_0_start(struct amdgpu_device *adev) 728static int uvd_v6_0_start(struct amdgpu_device *adev)
728{ 729{
729 struct amdgpu_ring *ring = &adev->uvd.ring; 730 struct amdgpu_ring *ring = &adev->uvd.inst->ring;
730 uint32_t rb_bufsz, tmp; 731 uint32_t rb_bufsz, tmp;
731 uint32_t lmi_swap_cntl; 732 uint32_t lmi_swap_cntl;
732 uint32_t mp_swap_cntl; 733 uint32_t mp_swap_cntl;
@@ -866,14 +867,14 @@ static int uvd_v6_0_start(struct amdgpu_device *adev)
866 WREG32_FIELD(UVD_RBC_RB_CNTL, RB_NO_FETCH, 0); 867 WREG32_FIELD(UVD_RBC_RB_CNTL, RB_NO_FETCH, 0);
867 868
868 if (uvd_v6_0_enc_support(adev)) { 869 if (uvd_v6_0_enc_support(adev)) {
869 ring = &adev->uvd.ring_enc[0]; 870 ring = &adev->uvd.inst->ring_enc[0];
870 WREG32(mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); 871 WREG32(mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
871 WREG32(mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); 872 WREG32(mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
872 WREG32(mmUVD_RB_BASE_LO, ring->gpu_addr); 873 WREG32(mmUVD_RB_BASE_LO, ring->gpu_addr);
873 WREG32(mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 874 WREG32(mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
874 WREG32(mmUVD_RB_SIZE, ring->ring_size / 4); 875 WREG32(mmUVD_RB_SIZE, ring->ring_size / 4);
875 876
876 ring = &adev->uvd.ring_enc[1]; 877 ring = &adev->uvd.inst->ring_enc[1];
877 WREG32(mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); 878 WREG32(mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
878 WREG32(mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); 879 WREG32(mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
879 WREG32(mmUVD_RB_BASE_LO2, ring->gpu_addr); 880 WREG32(mmUVD_RB_BASE_LO2, ring->gpu_addr);
@@ -964,6 +965,16 @@ static void uvd_v6_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,
964} 965}
965 966
966/** 967/**
968 * uvd_v6_0_ring_emit_hdp_flush - skip HDP flushing
969 *
970 * @ring: amdgpu_ring pointer
971 */
972static void uvd_v6_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
973{
974 /* The firmware doesn't seem to like touching registers at this point. */
975}
976
977/**
967 * uvd_v6_0_ring_test_ring - register write test 978 * uvd_v6_0_ring_test_ring - register write test
968 * 979 *
969 * @ring: amdgpu_ring pointer 980 * @ring: amdgpu_ring pointer
@@ -1089,6 +1100,18 @@ static void uvd_v6_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
1089 amdgpu_ring_write(ring, 0xE); 1100 amdgpu_ring_write(ring, 0xE);
1090} 1101}
1091 1102
1103static void uvd_v6_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
1104{
1105 int i;
1106
1107 WARN_ON(ring->wptr % 2 || count % 2);
1108
1109 for (i = 0; i < count / 2; i++) {
1110 amdgpu_ring_write(ring, PACKET0(mmUVD_NO_OP, 0));
1111 amdgpu_ring_write(ring, 0);
1112 }
1113}
1114
1092static void uvd_v6_0_enc_ring_emit_pipeline_sync(struct amdgpu_ring *ring) 1115static void uvd_v6_0_enc_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
1093{ 1116{
1094 uint32_t seq = ring->fence_drv.sync_seq; 1117 uint32_t seq = ring->fence_drv.sync_seq;
@@ -1148,10 +1171,10 @@ static bool uvd_v6_0_check_soft_reset(void *handle)
1148 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); 1171 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_UVD, 1);
1149 1172
1150 if (srbm_soft_reset) { 1173 if (srbm_soft_reset) {
1151 adev->uvd.srbm_soft_reset = srbm_soft_reset; 1174 adev->uvd.inst->srbm_soft_reset = srbm_soft_reset;
1152 return true; 1175 return true;
1153 } else { 1176 } else {
1154 adev->uvd.srbm_soft_reset = 0; 1177 adev->uvd.inst->srbm_soft_reset = 0;
1155 return false; 1178 return false;
1156 } 1179 }
1157} 1180}
@@ -1160,7 +1183,7 @@ static int uvd_v6_0_pre_soft_reset(void *handle)
1160{ 1183{
1161 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1184 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1162 1185
1163 if (!adev->uvd.srbm_soft_reset) 1186 if (!adev->uvd.inst->srbm_soft_reset)
1164 return 0; 1187 return 0;
1165 1188
1166 uvd_v6_0_stop(adev); 1189 uvd_v6_0_stop(adev);
@@ -1172,9 +1195,9 @@ static int uvd_v6_0_soft_reset(void *handle)
1172 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1195 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1173 u32 srbm_soft_reset; 1196 u32 srbm_soft_reset;
1174 1197
1175 if (!adev->uvd.srbm_soft_reset) 1198 if (!adev->uvd.inst->srbm_soft_reset)
1176 return 0; 1199 return 0;
1177 srbm_soft_reset = adev->uvd.srbm_soft_reset; 1200 srbm_soft_reset = adev->uvd.inst->srbm_soft_reset;
1178 1201
1179 if (srbm_soft_reset) { 1202 if (srbm_soft_reset) {
1180 u32 tmp; 1203 u32 tmp;
@@ -1202,7 +1225,7 @@ static int uvd_v6_0_post_soft_reset(void *handle)
1202{ 1225{
1203 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1226 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1204 1227
1205 if (!adev->uvd.srbm_soft_reset) 1228 if (!adev->uvd.inst->srbm_soft_reset)
1206 return 0; 1229 return 0;
1207 1230
1208 mdelay(5); 1231 mdelay(5);
@@ -1228,17 +1251,17 @@ static int uvd_v6_0_process_interrupt(struct amdgpu_device *adev,
1228 1251
1229 switch (entry->src_id) { 1252 switch (entry->src_id) {
1230 case 124: 1253 case 124:
1231 amdgpu_fence_process(&adev->uvd.ring); 1254 amdgpu_fence_process(&adev->uvd.inst->ring);
1232 break; 1255 break;
1233 case 119: 1256 case 119:
1234 if (likely(uvd_v6_0_enc_support(adev))) 1257 if (likely(uvd_v6_0_enc_support(adev)))
1235 amdgpu_fence_process(&adev->uvd.ring_enc[0]); 1258 amdgpu_fence_process(&adev->uvd.inst->ring_enc[0]);
1236 else 1259 else
1237 int_handled = false; 1260 int_handled = false;
1238 break; 1261 break;
1239 case 120: 1262 case 120:
1240 if (likely(uvd_v6_0_enc_support(adev))) 1263 if (likely(uvd_v6_0_enc_support(adev)))
1241 amdgpu_fence_process(&adev->uvd.ring_enc[1]); 1264 amdgpu_fence_process(&adev->uvd.inst->ring_enc[1]);
1242 else 1265 else
1243 int_handled = false; 1266 int_handled = false;
1244 break; 1267 break;
@@ -1521,22 +1544,22 @@ static const struct amd_ip_funcs uvd_v6_0_ip_funcs = {
1521static const struct amdgpu_ring_funcs uvd_v6_0_ring_phys_funcs = { 1544static const struct amdgpu_ring_funcs uvd_v6_0_ring_phys_funcs = {
1522 .type = AMDGPU_RING_TYPE_UVD, 1545 .type = AMDGPU_RING_TYPE_UVD,
1523 .align_mask = 0xf, 1546 .align_mask = 0xf,
1524 .nop = PACKET0(mmUVD_NO_OP, 0),
1525 .support_64bit_ptrs = false, 1547 .support_64bit_ptrs = false,
1526 .get_rptr = uvd_v6_0_ring_get_rptr, 1548 .get_rptr = uvd_v6_0_ring_get_rptr,
1527 .get_wptr = uvd_v6_0_ring_get_wptr, 1549 .get_wptr = uvd_v6_0_ring_get_wptr,
1528 .set_wptr = uvd_v6_0_ring_set_wptr, 1550 .set_wptr = uvd_v6_0_ring_set_wptr,
1529 .parse_cs = amdgpu_uvd_ring_parse_cs, 1551 .parse_cs = amdgpu_uvd_ring_parse_cs,
1530 .emit_frame_size = 1552 .emit_frame_size =
1531 6 + 6 + /* hdp flush / invalidate */ 1553 6 + /* hdp invalidate */
1532 10 + /* uvd_v6_0_ring_emit_pipeline_sync */ 1554 10 + /* uvd_v6_0_ring_emit_pipeline_sync */
1533 14, /* uvd_v6_0_ring_emit_fence x1 no user fence */ 1555 14, /* uvd_v6_0_ring_emit_fence x1 no user fence */
1534 .emit_ib_size = 8, /* uvd_v6_0_ring_emit_ib */ 1556 .emit_ib_size = 8, /* uvd_v6_0_ring_emit_ib */
1535 .emit_ib = uvd_v6_0_ring_emit_ib, 1557 .emit_ib = uvd_v6_0_ring_emit_ib,
1536 .emit_fence = uvd_v6_0_ring_emit_fence, 1558 .emit_fence = uvd_v6_0_ring_emit_fence,
1559 .emit_hdp_flush = uvd_v6_0_ring_emit_hdp_flush,
1537 .test_ring = uvd_v6_0_ring_test_ring, 1560 .test_ring = uvd_v6_0_ring_test_ring,
1538 .test_ib = amdgpu_uvd_ring_test_ib, 1561 .test_ib = amdgpu_uvd_ring_test_ib,
1539 .insert_nop = amdgpu_ring_insert_nop, 1562 .insert_nop = uvd_v6_0_ring_insert_nop,
1540 .pad_ib = amdgpu_ring_generic_pad_ib, 1563 .pad_ib = amdgpu_ring_generic_pad_ib,
1541 .begin_use = amdgpu_uvd_ring_begin_use, 1564 .begin_use = amdgpu_uvd_ring_begin_use,
1542 .end_use = amdgpu_uvd_ring_end_use, 1565 .end_use = amdgpu_uvd_ring_end_use,
@@ -1552,7 +1575,7 @@ static const struct amdgpu_ring_funcs uvd_v6_0_ring_vm_funcs = {
1552 .get_wptr = uvd_v6_0_ring_get_wptr, 1575 .get_wptr = uvd_v6_0_ring_get_wptr,
1553 .set_wptr = uvd_v6_0_ring_set_wptr, 1576 .set_wptr = uvd_v6_0_ring_set_wptr,
1554 .emit_frame_size = 1577 .emit_frame_size =
1555 6 + 6 + /* hdp flush / invalidate */ 1578 6 + /* hdp invalidate */
1556 10 + /* uvd_v6_0_ring_emit_pipeline_sync */ 1579 10 + /* uvd_v6_0_ring_emit_pipeline_sync */
1557 VI_FLUSH_GPU_TLB_NUM_WREG * 6 + 8 + /* uvd_v6_0_ring_emit_vm_flush */ 1580 VI_FLUSH_GPU_TLB_NUM_WREG * 6 + 8 + /* uvd_v6_0_ring_emit_vm_flush */
1558 14 + 14, /* uvd_v6_0_ring_emit_fence x2 vm fence */ 1581 14 + 14, /* uvd_v6_0_ring_emit_fence x2 vm fence */
@@ -1561,6 +1584,7 @@ static const struct amdgpu_ring_funcs uvd_v6_0_ring_vm_funcs = {
1561 .emit_fence = uvd_v6_0_ring_emit_fence, 1584 .emit_fence = uvd_v6_0_ring_emit_fence,
1562 .emit_vm_flush = uvd_v6_0_ring_emit_vm_flush, 1585 .emit_vm_flush = uvd_v6_0_ring_emit_vm_flush,
1563 .emit_pipeline_sync = uvd_v6_0_ring_emit_pipeline_sync, 1586 .emit_pipeline_sync = uvd_v6_0_ring_emit_pipeline_sync,
1587 .emit_hdp_flush = uvd_v6_0_ring_emit_hdp_flush,
1564 .test_ring = uvd_v6_0_ring_test_ring, 1588 .test_ring = uvd_v6_0_ring_test_ring,
1565 .test_ib = amdgpu_uvd_ring_test_ib, 1589 .test_ib = amdgpu_uvd_ring_test_ib,
1566 .insert_nop = amdgpu_ring_insert_nop, 1590 .insert_nop = amdgpu_ring_insert_nop,
@@ -1600,10 +1624,10 @@ static const struct amdgpu_ring_funcs uvd_v6_0_enc_ring_vm_funcs = {
1600static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev) 1624static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev)
1601{ 1625{
1602 if (adev->asic_type >= CHIP_POLARIS10) { 1626 if (adev->asic_type >= CHIP_POLARIS10) {
1603 adev->uvd.ring.funcs = &uvd_v6_0_ring_vm_funcs; 1627 adev->uvd.inst->ring.funcs = &uvd_v6_0_ring_vm_funcs;
1604 DRM_INFO("UVD is enabled in VM mode\n"); 1628 DRM_INFO("UVD is enabled in VM mode\n");
1605 } else { 1629 } else {
1606 adev->uvd.ring.funcs = &uvd_v6_0_ring_phys_funcs; 1630 adev->uvd.inst->ring.funcs = &uvd_v6_0_ring_phys_funcs;
1607 DRM_INFO("UVD is enabled in physical mode\n"); 1631 DRM_INFO("UVD is enabled in physical mode\n");
1608 } 1632 }
1609} 1633}
@@ -1613,7 +1637,7 @@ static void uvd_v6_0_set_enc_ring_funcs(struct amdgpu_device *adev)
1613 int i; 1637 int i;
1614 1638
1615 for (i = 0; i < adev->uvd.num_enc_rings; ++i) 1639 for (i = 0; i < adev->uvd.num_enc_rings; ++i)
1616 adev->uvd.ring_enc[i].funcs = &uvd_v6_0_enc_ring_vm_funcs; 1640 adev->uvd.inst->ring_enc[i].funcs = &uvd_v6_0_enc_ring_vm_funcs;
1617 1641
1618 DRM_INFO("UVD ENC is enabled in VM mode\n"); 1642 DRM_INFO("UVD ENC is enabled in VM mode\n");
1619} 1643}
@@ -1626,11 +1650,11 @@ static const struct amdgpu_irq_src_funcs uvd_v6_0_irq_funcs = {
1626static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev) 1650static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev)
1627{ 1651{
1628 if (uvd_v6_0_enc_support(adev)) 1652 if (uvd_v6_0_enc_support(adev))
1629 adev->uvd.irq.num_types = adev->uvd.num_enc_rings + 1; 1653 adev->uvd.inst->irq.num_types = adev->uvd.num_enc_rings + 1;
1630 else 1654 else
1631 adev->uvd.irq.num_types = 1; 1655 adev->uvd.inst->irq.num_types = 1;
1632 1656
1633 adev->uvd.irq.funcs = &uvd_v6_0_irq_funcs; 1657 adev->uvd.inst->irq.funcs = &uvd_v6_0_irq_funcs;
1634} 1658}
1635 1659
1636const struct amdgpu_ip_block_version uvd_v6_0_ip_block = 1660const struct amdgpu_ip_block_version uvd_v6_0_ip_block =
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
index eddc57f3b72a..57d32f21b3a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
@@ -40,6 +40,8 @@
40#include "mmhub/mmhub_1_0_offset.h" 40#include "mmhub/mmhub_1_0_offset.h"
41#include "mmhub/mmhub_1_0_sh_mask.h" 41#include "mmhub/mmhub_1_0_sh_mask.h"
42 42
43#define UVD7_MAX_HW_INSTANCES_VEGA20 2
44
43static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev); 45static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev);
44static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev); 46static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev);
45static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev); 47static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev);
@@ -47,6 +49,11 @@ static int uvd_v7_0_start(struct amdgpu_device *adev);
47static void uvd_v7_0_stop(struct amdgpu_device *adev); 49static void uvd_v7_0_stop(struct amdgpu_device *adev);
48static int uvd_v7_0_sriov_start(struct amdgpu_device *adev); 50static int uvd_v7_0_sriov_start(struct amdgpu_device *adev);
49 51
52static int amdgpu_ih_clientid_uvds[] = {
53 SOC15_IH_CLIENTID_UVD,
54 SOC15_IH_CLIENTID_UVD1
55};
56
50/** 57/**
51 * uvd_v7_0_ring_get_rptr - get read pointer 58 * uvd_v7_0_ring_get_rptr - get read pointer
52 * 59 *
@@ -58,7 +65,7 @@ static uint64_t uvd_v7_0_ring_get_rptr(struct amdgpu_ring *ring)
58{ 65{
59 struct amdgpu_device *adev = ring->adev; 66 struct amdgpu_device *adev = ring->adev;
60 67
61 return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR); 68 return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_RPTR);
62} 69}
63 70
64/** 71/**
@@ -72,10 +79,10 @@ static uint64_t uvd_v7_0_enc_ring_get_rptr(struct amdgpu_ring *ring)
72{ 79{
73 struct amdgpu_device *adev = ring->adev; 80 struct amdgpu_device *adev = ring->adev;
74 81
75 if (ring == &adev->uvd.ring_enc[0]) 82 if (ring == &adev->uvd.inst[ring->me].ring_enc[0])
76 return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR); 83 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR);
77 else 84 else
78 return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2); 85 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR2);
79} 86}
80 87
81/** 88/**
@@ -89,7 +96,7 @@ static uint64_t uvd_v7_0_ring_get_wptr(struct amdgpu_ring *ring)
89{ 96{
90 struct amdgpu_device *adev = ring->adev; 97 struct amdgpu_device *adev = ring->adev;
91 98
92 return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR); 99 return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR);
93} 100}
94 101
95/** 102/**
@@ -106,10 +113,10 @@ static uint64_t uvd_v7_0_enc_ring_get_wptr(struct amdgpu_ring *ring)
106 if (ring->use_doorbell) 113 if (ring->use_doorbell)
107 return adev->wb.wb[ring->wptr_offs]; 114 return adev->wb.wb[ring->wptr_offs];
108 115
109 if (ring == &adev->uvd.ring_enc[0]) 116 if (ring == &adev->uvd.inst[ring->me].ring_enc[0])
110 return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR); 117 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR);
111 else 118 else
112 return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2); 119 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2);
113} 120}
114 121
115/** 122/**
@@ -123,7 +130,7 @@ static void uvd_v7_0_ring_set_wptr(struct amdgpu_ring *ring)
123{ 130{
124 struct amdgpu_device *adev = ring->adev; 131 struct amdgpu_device *adev = ring->adev;
125 132
126 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); 133 WREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
127} 134}
128 135
129/** 136/**
@@ -144,11 +151,11 @@ static void uvd_v7_0_enc_ring_set_wptr(struct amdgpu_ring *ring)
144 return; 151 return;
145 } 152 }
146 153
147 if (ring == &adev->uvd.ring_enc[0]) 154 if (ring == &adev->uvd.inst[ring->me].ring_enc[0])
148 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, 155 WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR,
149 lower_32_bits(ring->wptr)); 156 lower_32_bits(ring->wptr));
150 else 157 else
151 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, 158 WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2,
152 lower_32_bits(ring->wptr)); 159 lower_32_bits(ring->wptr));
153} 160}
154 161
@@ -170,8 +177,8 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring)
170 177
171 r = amdgpu_ring_alloc(ring, 16); 178 r = amdgpu_ring_alloc(ring, 16);
172 if (r) { 179 if (r) {
173 DRM_ERROR("amdgpu: uvd enc failed to lock ring %d (%d).\n", 180 DRM_ERROR("amdgpu: uvd enc failed to lock (%d)ring %d (%d).\n",
174 ring->idx, r); 181 ring->me, ring->idx, r);
175 return r; 182 return r;
176 } 183 }
177 amdgpu_ring_write(ring, HEVC_ENC_CMD_END); 184 amdgpu_ring_write(ring, HEVC_ENC_CMD_END);
@@ -184,11 +191,11 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring)
184 } 191 }
185 192
186 if (i < adev->usec_timeout) { 193 if (i < adev->usec_timeout) {
187 DRM_DEBUG("ring test on %d succeeded in %d usecs\n", 194 DRM_DEBUG("(%d)ring test on %d succeeded in %d usecs\n",
188 ring->idx, i); 195 ring->me, ring->idx, i);
189 } else { 196 } else {
190 DRM_ERROR("amdgpu: ring %d test failed\n", 197 DRM_ERROR("amdgpu: (%d)ring %d test failed\n",
191 ring->idx); 198 ring->me, ring->idx);
192 r = -ETIMEDOUT; 199 r = -ETIMEDOUT;
193 } 200 }
194 201
@@ -342,24 +349,24 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
342 349
343 r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL); 350 r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL);
344 if (r) { 351 if (r) {
345 DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); 352 DRM_ERROR("amdgpu: (%d)failed to get create msg (%ld).\n", ring->me, r);
346 goto error; 353 goto error;
347 } 354 }
348 355
349 r = uvd_v7_0_enc_get_destroy_msg(ring, 1, true, &fence); 356 r = uvd_v7_0_enc_get_destroy_msg(ring, 1, true, &fence);
350 if (r) { 357 if (r) {
351 DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); 358 DRM_ERROR("amdgpu: (%d)failed to get destroy ib (%ld).\n", ring->me, r);
352 goto error; 359 goto error;
353 } 360 }
354 361
355 r = dma_fence_wait_timeout(fence, false, timeout); 362 r = dma_fence_wait_timeout(fence, false, timeout);
356 if (r == 0) { 363 if (r == 0) {
357 DRM_ERROR("amdgpu: IB test timed out.\n"); 364 DRM_ERROR("amdgpu: (%d)IB test timed out.\n", ring->me);
358 r = -ETIMEDOUT; 365 r = -ETIMEDOUT;
359 } else if (r < 0) { 366 } else if (r < 0) {
360 DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); 367 DRM_ERROR("amdgpu: (%d)fence wait failed (%ld).\n", ring->me, r);
361 } else { 368 } else {
362 DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); 369 DRM_DEBUG("ib test on (%d)ring %d succeeded\n", ring->me, ring->idx);
363 r = 0; 370 r = 0;
364 } 371 }
365error: 372error:
@@ -370,6 +377,10 @@ error:
370static int uvd_v7_0_early_init(void *handle) 377static int uvd_v7_0_early_init(void *handle)
371{ 378{
372 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 379 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
380 if (adev->asic_type == CHIP_VEGA20)
381 adev->uvd.num_uvd_inst = UVD7_MAX_HW_INSTANCES_VEGA20;
382 else
383 adev->uvd.num_uvd_inst = 1;
373 384
374 if (amdgpu_sriov_vf(adev)) 385 if (amdgpu_sriov_vf(adev))
375 adev->uvd.num_enc_rings = 1; 386 adev->uvd.num_enc_rings = 1;
@@ -386,19 +397,21 @@ static int uvd_v7_0_sw_init(void *handle)
386{ 397{
387 struct amdgpu_ring *ring; 398 struct amdgpu_ring *ring;
388 struct drm_sched_rq *rq; 399 struct drm_sched_rq *rq;
389 int i, r; 400 int i, j, r;
390 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 401 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
391 402
392 /* UVD TRAP */ 403 for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
393 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UVD, 124, &adev->uvd.irq); 404 /* UVD TRAP */
394 if (r) 405 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], 124, &adev->uvd.inst[j].irq);
395 return r;
396
397 /* UVD ENC TRAP */
398 for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
399 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UVD, i + 119, &adev->uvd.irq);
400 if (r) 406 if (r)
401 return r; 407 return r;
408
409 /* UVD ENC TRAP */
410 for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
411 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], i + 119, &adev->uvd.inst[j].irq);
412 if (r)
413 return r;
414 }
402 } 415 }
403 416
404 r = amdgpu_uvd_sw_init(adev); 417 r = amdgpu_uvd_sw_init(adev);
@@ -415,43 +428,48 @@ static int uvd_v7_0_sw_init(void *handle)
415 DRM_INFO("PSP loading UVD firmware\n"); 428 DRM_INFO("PSP loading UVD firmware\n");
416 } 429 }
417 430
418 ring = &adev->uvd.ring_enc[0]; 431 for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
419 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; 432 ring = &adev->uvd.inst[j].ring_enc[0];
420 r = drm_sched_entity_init(&ring->sched, &adev->uvd.entity_enc, 433 rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL];
421 rq, amdgpu_sched_jobs, NULL); 434 r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst[j].entity_enc,
422 if (r) { 435 rq, NULL);
423 DRM_ERROR("Failed setting up UVD ENC run queue.\n"); 436 if (r) {
424 return r; 437 DRM_ERROR("(%d)Failed setting up UVD ENC run queue.\n", j);
438 return r;
439 }
425 } 440 }
426 441
427 r = amdgpu_uvd_resume(adev); 442 r = amdgpu_uvd_resume(adev);
428 if (r) 443 if (r)
429 return r; 444 return r;
430 if (!amdgpu_sriov_vf(adev)) {
431 ring = &adev->uvd.ring;
432 sprintf(ring->name, "uvd");
433 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0);
434 if (r)
435 return r;
436 }
437 445
438 for (i = 0; i < adev->uvd.num_enc_rings; ++i) { 446 for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
439 ring = &adev->uvd.ring_enc[i]; 447 if (!amdgpu_sriov_vf(adev)) {
440 sprintf(ring->name, "uvd_enc%d", i); 448 ring = &adev->uvd.inst[j].ring;
441 if (amdgpu_sriov_vf(adev)) { 449 sprintf(ring->name, "uvd<%d>", j);
442 ring->use_doorbell = true; 450 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0);
443 451 if (r)
444 /* currently only use the first enconding ring for 452 return r;
445 * sriov, so set unused location for other unused rings. 453 }
446 */ 454
447 if (i == 0) 455 for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
448 ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2; 456 ring = &adev->uvd.inst[j].ring_enc[i];
449 else 457 sprintf(ring->name, "uvd_enc%d<%d>", i, j);
450 ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING2_3 * 2 + 1; 458 if (amdgpu_sriov_vf(adev)) {
459 ring->use_doorbell = true;
460
461 /* currently only use the first enconding ring for
462 * sriov, so set unused location for other unused rings.
463 */
464 if (i == 0)
465 ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2;
466 else
467 ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING2_3 * 2 + 1;
468 }
469 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0);
470 if (r)
471 return r;
451 } 472 }
452 r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0);
453 if (r)
454 return r;
455 } 473 }
456 474
457 r = amdgpu_virt_alloc_mm_table(adev); 475 r = amdgpu_virt_alloc_mm_table(adev);
@@ -463,7 +481,7 @@ static int uvd_v7_0_sw_init(void *handle)
463 481
464static int uvd_v7_0_sw_fini(void *handle) 482static int uvd_v7_0_sw_fini(void *handle)
465{ 483{
466 int i, r; 484 int i, j, r;
467 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 485 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
468 486
469 amdgpu_virt_free_mm_table(adev); 487 amdgpu_virt_free_mm_table(adev);
@@ -472,11 +490,12 @@ static int uvd_v7_0_sw_fini(void *handle)
472 if (r) 490 if (r)
473 return r; 491 return r;
474 492
475 drm_sched_entity_fini(&adev->uvd.ring_enc[0].sched, &adev->uvd.entity_enc); 493 for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
476 494 drm_sched_entity_fini(&adev->uvd.inst[j].ring_enc[0].sched, &adev->uvd.inst[j].entity_enc);
477 for (i = 0; i < adev->uvd.num_enc_rings; ++i)
478 amdgpu_ring_fini(&adev->uvd.ring_enc[i]);
479 495
496 for (i = 0; i < adev->uvd.num_enc_rings; ++i)
497 amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]);
498 }
480 return amdgpu_uvd_sw_fini(adev); 499 return amdgpu_uvd_sw_fini(adev);
481} 500}
482 501
@@ -490,9 +509,9 @@ static int uvd_v7_0_sw_fini(void *handle)
490static int uvd_v7_0_hw_init(void *handle) 509static int uvd_v7_0_hw_init(void *handle)
491{ 510{
492 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 511 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
493 struct amdgpu_ring *ring = &adev->uvd.ring; 512 struct amdgpu_ring *ring;
494 uint32_t tmp; 513 uint32_t tmp;
495 int i, r; 514 int i, j, r;
496 515
497 if (amdgpu_sriov_vf(adev)) 516 if (amdgpu_sriov_vf(adev))
498 r = uvd_v7_0_sriov_start(adev); 517 r = uvd_v7_0_sriov_start(adev);
@@ -501,57 +520,60 @@ static int uvd_v7_0_hw_init(void *handle)
501 if (r) 520 if (r)
502 goto done; 521 goto done;
503 522
504 if (!amdgpu_sriov_vf(adev)) { 523 for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
505 ring->ready = true; 524 ring = &adev->uvd.inst[j].ring;
506 r = amdgpu_ring_test_ring(ring); 525
507 if (r) { 526 if (!amdgpu_sriov_vf(adev)) {
508 ring->ready = false; 527 ring->ready = true;
509 goto done; 528 r = amdgpu_ring_test_ring(ring);
529 if (r) {
530 ring->ready = false;
531 goto done;
532 }
533
534 r = amdgpu_ring_alloc(ring, 10);
535 if (r) {
536 DRM_ERROR("amdgpu: (%d)ring failed to lock UVD ring (%d).\n", j, r);
537 goto done;
538 }
539
540 tmp = PACKET0(SOC15_REG_OFFSET(UVD, j,
541 mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL), 0);
542 amdgpu_ring_write(ring, tmp);
543 amdgpu_ring_write(ring, 0xFFFFF);
544
545 tmp = PACKET0(SOC15_REG_OFFSET(UVD, j,
546 mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL), 0);
547 amdgpu_ring_write(ring, tmp);
548 amdgpu_ring_write(ring, 0xFFFFF);
549
550 tmp = PACKET0(SOC15_REG_OFFSET(UVD, j,
551 mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL), 0);
552 amdgpu_ring_write(ring, tmp);
553 amdgpu_ring_write(ring, 0xFFFFF);
554
555 /* Clear timeout status bits */
556 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, j,
557 mmUVD_SEMA_TIMEOUT_STATUS), 0));
558 amdgpu_ring_write(ring, 0x8);
559
560 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, j,
561 mmUVD_SEMA_CNTL), 0));
562 amdgpu_ring_write(ring, 3);
563
564 amdgpu_ring_commit(ring);
510 } 565 }
511 566
512 r = amdgpu_ring_alloc(ring, 10); 567 for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
513 if (r) { 568 ring = &adev->uvd.inst[j].ring_enc[i];
514 DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r); 569 ring->ready = true;
515 goto done; 570 r = amdgpu_ring_test_ring(ring);
571 if (r) {
572 ring->ready = false;
573 goto done;
574 }
516 } 575 }
517
518 tmp = PACKET0(SOC15_REG_OFFSET(UVD, 0,
519 mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL), 0);
520 amdgpu_ring_write(ring, tmp);
521 amdgpu_ring_write(ring, 0xFFFFF);
522
523 tmp = PACKET0(SOC15_REG_OFFSET(UVD, 0,
524 mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL), 0);
525 amdgpu_ring_write(ring, tmp);
526 amdgpu_ring_write(ring, 0xFFFFF);
527
528 tmp = PACKET0(SOC15_REG_OFFSET(UVD, 0,
529 mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL), 0);
530 amdgpu_ring_write(ring, tmp);
531 amdgpu_ring_write(ring, 0xFFFFF);
532
533 /* Clear timeout status bits */
534 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0,
535 mmUVD_SEMA_TIMEOUT_STATUS), 0));
536 amdgpu_ring_write(ring, 0x8);
537
538 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0,
539 mmUVD_SEMA_CNTL), 0));
540 amdgpu_ring_write(ring, 3);
541
542 amdgpu_ring_commit(ring);
543 } 576 }
544
545 for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
546 ring = &adev->uvd.ring_enc[i];
547 ring->ready = true;
548 r = amdgpu_ring_test_ring(ring);
549 if (r) {
550 ring->ready = false;
551 goto done;
552 }
553 }
554
555done: 577done:
556 if (!r) 578 if (!r)
557 DRM_INFO("UVD and UVD ENC initialized successfully.\n"); 579 DRM_INFO("UVD and UVD ENC initialized successfully.\n");
@@ -569,7 +591,7 @@ done:
569static int uvd_v7_0_hw_fini(void *handle) 591static int uvd_v7_0_hw_fini(void *handle)
570{ 592{
571 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 593 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
572 struct amdgpu_ring *ring = &adev->uvd.ring; 594 int i;
573 595
574 if (!amdgpu_sriov_vf(adev)) 596 if (!amdgpu_sriov_vf(adev))
575 uvd_v7_0_stop(adev); 597 uvd_v7_0_stop(adev);
@@ -578,7 +600,8 @@ static int uvd_v7_0_hw_fini(void *handle)
578 DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); 600 DRM_DEBUG("For SRIOV client, shouldn't do anything.\n");
579 } 601 }
580 602
581 ring->ready = false; 603 for (i = 0; i < adev->uvd.num_uvd_inst; ++i)
604 adev->uvd.inst[i].ring.ready = false;
582 605
583 return 0; 606 return 0;
584} 607}
@@ -618,48 +641,51 @@ static void uvd_v7_0_mc_resume(struct amdgpu_device *adev)
618{ 641{
619 uint32_t size = AMDGPU_UVD_FIRMWARE_SIZE(adev); 642 uint32_t size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
620 uint32_t offset; 643 uint32_t offset;
644 int i;
621 645
622 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 646 for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
623 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 647 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
624 lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); 648 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
625 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 649 lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr));
626 upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); 650 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
627 offset = 0; 651 upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr));
628 } else { 652 offset = 0;
629 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 653 } else {
630 lower_32_bits(adev->uvd.gpu_addr)); 654 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
631 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 655 lower_32_bits(adev->uvd.inst[i].gpu_addr));
632 upper_32_bits(adev->uvd.gpu_addr)); 656 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
633 offset = size; 657 upper_32_bits(adev->uvd.inst[i].gpu_addr));
634 } 658 offset = size;
659 }
635 660
636 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, 661 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0,
637 AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 662 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
638 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size); 663 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE0, size);
639 664
640 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, 665 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
641 lower_32_bits(adev->uvd.gpu_addr + offset)); 666 lower_32_bits(adev->uvd.inst[i].gpu_addr + offset));
642 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, 667 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
643 upper_32_bits(adev->uvd.gpu_addr + offset)); 668 upper_32_bits(adev->uvd.inst[i].gpu_addr + offset));
644 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, (1 << 21)); 669 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET1, (1 << 21));
645 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_UVD_HEAP_SIZE); 670 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_UVD_HEAP_SIZE);
646 671
647 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, 672 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
648 lower_32_bits(adev->uvd.gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); 673 lower_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
649 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, 674 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
650 upper_32_bits(adev->uvd.gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); 675 upper_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
651 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, (2 << 21)); 676 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET2, (2 << 21));
652 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, 677 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE2,
653 AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40)); 678 AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40));
654 679
655 WREG32_SOC15(UVD, 0, mmUVD_UDEC_ADDR_CONFIG, 680 WREG32_SOC15(UVD, i, mmUVD_UDEC_ADDR_CONFIG,
656 adev->gfx.config.gb_addr_config); 681 adev->gfx.config.gb_addr_config);
657 WREG32_SOC15(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG, 682 WREG32_SOC15(UVD, i, mmUVD_UDEC_DB_ADDR_CONFIG,
658 adev->gfx.config.gb_addr_config); 683 adev->gfx.config.gb_addr_config);
659 WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG, 684 WREG32_SOC15(UVD, i, mmUVD_UDEC_DBW_ADDR_CONFIG,
660 adev->gfx.config.gb_addr_config); 685 adev->gfx.config.gb_addr_config);
661 686
662 WREG32_SOC15(UVD, 0, mmUVD_GP_SCRATCH4, adev->uvd.max_handles); 687 WREG32_SOC15(UVD, i, mmUVD_GP_SCRATCH4, adev->uvd.max_handles);
688 }
663} 689}
664 690
665static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, 691static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev,
@@ -669,6 +695,7 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev,
669 uint64_t addr = table->gpu_addr; 695 uint64_t addr = table->gpu_addr;
670 struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)table->cpu_addr; 696 struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)table->cpu_addr;
671 uint32_t size; 697 uint32_t size;
698 int i;
672 699
673 size = header->header_size + header->vce_table_size + header->uvd_table_size; 700 size = header->header_size + header->vce_table_size + header->uvd_table_size;
674 701
@@ -688,11 +715,12 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev,
688 /* 4, set resp to zero */ 715 /* 4, set resp to zero */
689 WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0); 716 WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0);
690 717
691 WDOORBELL32(adev->uvd.ring_enc[0].doorbell_index, 0); 718 for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
692 adev->wb.wb[adev->uvd.ring_enc[0].wptr_offs] = 0; 719 WDOORBELL32(adev->uvd.inst[i].ring_enc[0].doorbell_index, 0);
693 adev->uvd.ring_enc[0].wptr = 0; 720 adev->wb.wb[adev->uvd.inst[i].ring_enc[0].wptr_offs] = 0;
694 adev->uvd.ring_enc[0].wptr_old = 0; 721 adev->uvd.inst[i].ring_enc[0].wptr = 0;
695 722 adev->uvd.inst[i].ring_enc[0].wptr_old = 0;
723 }
696 /* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */ 724 /* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */
697 WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST, 0x10000001); 725 WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST, 0x10000001);
698 726
@@ -725,6 +753,7 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
725 struct mmsch_v1_0_cmd_end end = { {0} }; 753 struct mmsch_v1_0_cmd_end end = { {0} };
726 uint32_t *init_table = adev->virt.mm_table.cpu_addr; 754 uint32_t *init_table = adev->virt.mm_table.cpu_addr;
727 struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)init_table; 755 struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)init_table;
756 uint8_t i = 0;
728 757
729 direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE; 758 direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE;
730 direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; 759 direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
@@ -742,120 +771,121 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
742 771
743 init_table += header->uvd_table_offset; 772 init_table += header->uvd_table_offset;
744 773
745 ring = &adev->uvd.ring; 774 for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
746 ring->wptr = 0; 775 ring = &adev->uvd.inst[i].ring;
747 size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4); 776 ring->wptr = 0;
748 777 size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
749 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 778
750 0xFFFFFFFF, 0x00000004); 779 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS),
751 /* mc resume*/ 780 0xFFFFFFFF, 0x00000004);
752 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 781 /* mc resume*/
753 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 782 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
754 lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); 783 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
755 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 784 lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr));
756 upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); 785 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
757 offset = 0; 786 upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr));
758 } else { 787 offset = 0;
759 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 788 } else {
760 lower_32_bits(adev->uvd.gpu_addr)); 789 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
761 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 790 lower_32_bits(adev->uvd.inst[i].gpu_addr));
762 upper_32_bits(adev->uvd.gpu_addr)); 791 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
763 offset = size; 792 upper_32_bits(adev->uvd.inst[i].gpu_addr));
793 offset = size;
794 }
795
796 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET0),
797 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
798 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE0), size);
799
800 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
801 lower_32_bits(adev->uvd.inst[i].gpu_addr + offset));
802 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
803 upper_32_bits(adev->uvd.inst[i].gpu_addr + offset));
804 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET1), (1 << 21));
805 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_UVD_HEAP_SIZE);
806
807 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
808 lower_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
809 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
810 upper_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
811 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET2), (2 << 21));
812 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE2),
813 AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40));
814
815 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_GP_SCRATCH4), adev->uvd.max_handles);
816 /* mc resume end*/
817
818 /* disable clock gating */
819 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_CGC_CTRL),
820 ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK, 0);
821
822 /* disable interupt */
823 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN),
824 ~UVD_MASTINT_EN__VCPU_EN_MASK, 0);
825
826 /* stall UMC and register bus before resetting VCPU */
827 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2),
828 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
829 UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
830
831 /* put LMI, VCPU, RBC etc... into reset */
832 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET),
833 (uint32_t)(UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
834 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK |
835 UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
836 UVD_SOFT_RESET__RBC_SOFT_RESET_MASK |
837 UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
838 UVD_SOFT_RESET__CXW_SOFT_RESET_MASK |
839 UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
840 UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK));
841
842 /* initialize UVD memory controller */
843 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL),
844 (uint32_t)((0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
845 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
846 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
847 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
848 UVD_LMI_CTRL__REQ_MODE_MASK |
849 0x00100000L));
850
851 /* take all subblocks out of reset, except VCPU */
852 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET),
853 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
854
855 /* enable VCPU clock */
856 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
857 UVD_VCPU_CNTL__CLK_EN_MASK);
858
859 /* enable master interrupt */
860 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN),
861 ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
862 (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK));
863
864 /* clear the bit 4 of UVD_STATUS */
865 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS),
866 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT), 0);
867
868 /* force RBC into idle state */
869 size = order_base_2(ring->ring_size);
870 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, size);
871 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
872 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RBC_RB_CNTL), tmp);
873
874 ring = &adev->uvd.inst[i].ring_enc[0];
875 ring->wptr = 0;
876 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_BASE_LO), ring->gpu_addr);
877 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr));
878 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_SIZE), ring->ring_size / 4);
879
880 /* boot up the VCPU */
881 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET), 0);
882
883 /* enable UMC */
884 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2),
885 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0);
886
887 MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), 0x02, 0x02);
764 } 888 }
765
766 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0),
767 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
768 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE0), size);
769
770 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
771 lower_32_bits(adev->uvd.gpu_addr + offset));
772 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
773 upper_32_bits(adev->uvd.gpu_addr + offset));
774 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), (1 << 21));
775 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_UVD_HEAP_SIZE);
776
777 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
778 lower_32_bits(adev->uvd.gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
779 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
780 upper_32_bits(adev->uvd.gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
781 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2), (2 << 21));
782 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE2),
783 AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40));
784
785 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH4), adev->uvd.max_handles);
786 /* mc resume end*/
787
788 /* disable clock gating */
789 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_CGC_CTRL),
790 ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK, 0);
791
792 /* disable interupt */
793 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),
794 ~UVD_MASTINT_EN__VCPU_EN_MASK, 0);
795
796 /* stall UMC and register bus before resetting VCPU */
797 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
798 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
799 UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
800
801 /* put LMI, VCPU, RBC etc... into reset */
802 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
803 (uint32_t)(UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
804 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK |
805 UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
806 UVD_SOFT_RESET__RBC_SOFT_RESET_MASK |
807 UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
808 UVD_SOFT_RESET__CXW_SOFT_RESET_MASK |
809 UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
810 UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK));
811
812 /* initialize UVD memory controller */
813 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL),
814 (uint32_t)((0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
815 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
816 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
817 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
818 UVD_LMI_CTRL__REQ_MODE_MASK |
819 0x00100000L));
820
821 /* take all subblocks out of reset, except VCPU */
822 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
823 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
824
825 /* enable VCPU clock */
826 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL),
827 UVD_VCPU_CNTL__CLK_EN_MASK);
828
829 /* enable master interrupt */
830 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),
831 ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
832 (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK));
833
834 /* clear the bit 4 of UVD_STATUS */
835 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS),
836 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT), 0);
837
838 /* force RBC into idle state */
839 size = order_base_2(ring->ring_size);
840 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, size);
841 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
842 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), tmp);
843
844 ring = &adev->uvd.ring_enc[0];
845 ring->wptr = 0;
846 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_LO), ring->gpu_addr);
847 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr));
848 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_SIZE), ring->ring_size / 4);
849
850 /* boot up the VCPU */
851 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0);
852
853 /* enable UMC */
854 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
855 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0);
856
857 MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0x02, 0x02);
858
859 /* add end packet */ 889 /* add end packet */
860 memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end)); 890 memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
861 table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4; 891 table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
@@ -874,15 +904,17 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
874 */ 904 */
875static int uvd_v7_0_start(struct amdgpu_device *adev) 905static int uvd_v7_0_start(struct amdgpu_device *adev)
876{ 906{
877 struct amdgpu_ring *ring = &adev->uvd.ring; 907 struct amdgpu_ring *ring;
878 uint32_t rb_bufsz, tmp; 908 uint32_t rb_bufsz, tmp;
879 uint32_t lmi_swap_cntl; 909 uint32_t lmi_swap_cntl;
880 uint32_t mp_swap_cntl; 910 uint32_t mp_swap_cntl;
881 int i, j, r; 911 int i, j, k, r;
882 912
883 /* disable DPG */ 913 for (k = 0; k < adev->uvd.num_uvd_inst; ++k) {
884 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0, 914 /* disable DPG */
885 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); 915 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_POWER_STATUS), 0,
916 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
917 }
886 918
887 /* disable byte swapping */ 919 /* disable byte swapping */
888 lmi_swap_cntl = 0; 920 lmi_swap_cntl = 0;
@@ -890,157 +922,159 @@ static int uvd_v7_0_start(struct amdgpu_device *adev)
890 922
891 uvd_v7_0_mc_resume(adev); 923 uvd_v7_0_mc_resume(adev);
892 924
893 /* disable clock gating */ 925 for (k = 0; k < adev->uvd.num_uvd_inst; ++k) {
894 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_CGC_CTRL), 0, 926 ring = &adev->uvd.inst[k].ring;
895 ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK); 927 /* disable clock gating */
896 928 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_CGC_CTRL), 0,
897 /* disable interupt */ 929 ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK);
898 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0,
899 ~UVD_MASTINT_EN__VCPU_EN_MASK);
900
901 /* stall UMC and register bus before resetting VCPU */
902 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
903 UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
904 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
905 mdelay(1);
906
907 /* put LMI, VCPU, RBC etc... into reset */
908 WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET,
909 UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
910 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK |
911 UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
912 UVD_SOFT_RESET__RBC_SOFT_RESET_MASK |
913 UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
914 UVD_SOFT_RESET__CXW_SOFT_RESET_MASK |
915 UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
916 UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
917 mdelay(5);
918 930
919 /* initialize UVD memory controller */ 931 /* disable interupt */
920 WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL, 932 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_MASTINT_EN), 0,
921 (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | 933 ~UVD_MASTINT_EN__VCPU_EN_MASK);
922 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 934
923 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 935 /* stall UMC and register bus before resetting VCPU */
924 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | 936 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_LMI_CTRL2),
925 UVD_LMI_CTRL__REQ_MODE_MASK | 937 UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
926 0x00100000L); 938 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
939 mdelay(1);
940
941 /* put LMI, VCPU, RBC etc... into reset */
942 WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET,
943 UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
944 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK |
945 UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
946 UVD_SOFT_RESET__RBC_SOFT_RESET_MASK |
947 UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
948 UVD_SOFT_RESET__CXW_SOFT_RESET_MASK |
949 UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
950 UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
951 mdelay(5);
952
953 /* initialize UVD memory controller */
954 WREG32_SOC15(UVD, k, mmUVD_LMI_CTRL,
955 (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
956 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
957 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
958 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
959 UVD_LMI_CTRL__REQ_MODE_MASK |
960 0x00100000L);
927 961
928#ifdef __BIG_ENDIAN 962#ifdef __BIG_ENDIAN
929 /* swap (8 in 32) RB and IB */ 963 /* swap (8 in 32) RB and IB */
930 lmi_swap_cntl = 0xa; 964 lmi_swap_cntl = 0xa;
931 mp_swap_cntl = 0; 965 mp_swap_cntl = 0;
932#endif 966#endif
933 WREG32_SOC15(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl); 967 WREG32_SOC15(UVD, k, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl);
934 WREG32_SOC15(UVD, 0, mmUVD_MP_SWAP_CNTL, mp_swap_cntl); 968 WREG32_SOC15(UVD, k, mmUVD_MP_SWAP_CNTL, mp_swap_cntl);
935
936 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0, 0x40c2040);
937 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA1, 0x0);
938 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0, 0x40c2040);
939 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB1, 0x0);
940 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_ALU, 0);
941 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX, 0x88);
942
943 /* take all subblocks out of reset, except VCPU */
944 WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET,
945 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
946 mdelay(5);
947 969
948 /* enable VCPU clock */ 970 WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXA0, 0x40c2040);
949 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, 971 WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXA1, 0x0);
950 UVD_VCPU_CNTL__CLK_EN_MASK); 972 WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXB0, 0x40c2040);
973 WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXB1, 0x0);
974 WREG32_SOC15(UVD, k, mmUVD_MPC_SET_ALU, 0);
975 WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUX, 0x88);
951 976
952 /* enable UMC */ 977 /* take all subblocks out of reset, except VCPU */
953 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, 978 WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET,
954 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 979 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
980 mdelay(5);
955 981
956 /* boot up the VCPU */ 982 /* enable VCPU clock */
957 WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, 0); 983 WREG32_SOC15(UVD, k, mmUVD_VCPU_CNTL,
958 mdelay(10); 984 UVD_VCPU_CNTL__CLK_EN_MASK);
959 985
960 for (i = 0; i < 10; ++i) { 986 /* enable UMC */
961 uint32_t status; 987 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_LMI_CTRL2), 0,
988 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
962 989
963 for (j = 0; j < 100; ++j) { 990 /* boot up the VCPU */
964 status = RREG32_SOC15(UVD, 0, mmUVD_STATUS); 991 WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET, 0);
992 mdelay(10);
993
994 for (i = 0; i < 10; ++i) {
995 uint32_t status;
996
997 for (j = 0; j < 100; ++j) {
998 status = RREG32_SOC15(UVD, k, mmUVD_STATUS);
999 if (status & 2)
1000 break;
1001 mdelay(10);
1002 }
1003 r = 0;
965 if (status & 2) 1004 if (status & 2)
966 break; 1005 break;
1006
1007 DRM_ERROR("UVD(%d) not responding, trying to reset the VCPU!!!\n", k);
1008 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_SOFT_RESET),
1009 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
1010 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
967 mdelay(10); 1011 mdelay(10);
1012 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_SOFT_RESET), 0,
1013 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
1014 mdelay(10);
1015 r = -1;
968 } 1016 }
969 r = 0;
970 if (status & 2)
971 break;
972
973 DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
974 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
975 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
976 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
977 mdelay(10);
978 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0,
979 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
980 mdelay(10);
981 r = -1;
982 }
983
984 if (r) {
985 DRM_ERROR("UVD not responding, giving up!!!\n");
986 return r;
987 }
988 /* enable master interrupt */
989 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),
990 (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
991 ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK));
992
993 /* clear the bit 4 of UVD_STATUS */
994 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0,
995 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
996
997 /* force RBC into idle state */
998 rb_bufsz = order_base_2(ring->ring_size);
999 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1000 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1001 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1002 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0);
1003 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1004 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1005 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);
1006
1007 /* set the write pointer delay */
1008 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0);
1009
1010 /* set the wb address */
1011 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR,
1012 (upper_32_bits(ring->gpu_addr) >> 2));
1013
1014 /* programm the RB_BASE for ring buffer */
1015 WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1016 lower_32_bits(ring->gpu_addr));
1017 WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1018 upper_32_bits(ring->gpu_addr));
1019
1020 /* Initialize the ring buffer's read and write pointers */
1021 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0);
1022
1023 ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);
1024 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
1025 lower_32_bits(ring->wptr));
1026 1017
1027 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0, 1018 if (r) {
1028 ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); 1019 DRM_ERROR("UVD(%d) not responding, giving up!!!\n", k);
1029 1020 return r;
1030 ring = &adev->uvd.ring_enc[0]; 1021 }
1031 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); 1022 /* enable master interrupt */
1032 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); 1023 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_MASTINT_EN),
1033 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr); 1024 (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
1034 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 1025 ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK));
1035 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);
1036 1026
1037 ring = &adev->uvd.ring_enc[1]; 1027 /* clear the bit 4 of UVD_STATUS */
1038 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); 1028 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_STATUS), 0,
1039 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); 1029 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
1040 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1041 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1042 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);
1043 1030
1031 /* force RBC into idle state */
1032 rb_bufsz = order_base_2(ring->ring_size);
1033 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1034 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1035 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1036 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0);
1037 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1038 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1039 WREG32_SOC15(UVD, k, mmUVD_RBC_RB_CNTL, tmp);
1040
1041 /* set the write pointer delay */
1042 WREG32_SOC15(UVD, k, mmUVD_RBC_RB_WPTR_CNTL, 0);
1043
1044 /* set the wb address */
1045 WREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR_ADDR,
1046 (upper_32_bits(ring->gpu_addr) >> 2));
1047
1048 /* programm the RB_BASE for ring buffer */
1049 WREG32_SOC15(UVD, k, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1050 lower_32_bits(ring->gpu_addr));
1051 WREG32_SOC15(UVD, k, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1052 upper_32_bits(ring->gpu_addr));
1053
1054 /* Initialize the ring buffer's read and write pointers */
1055 WREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR, 0);
1056
1057 ring->wptr = RREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR);
1058 WREG32_SOC15(UVD, k, mmUVD_RBC_RB_WPTR,
1059 lower_32_bits(ring->wptr));
1060
1061 WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_RBC_RB_CNTL), 0,
1062 ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);
1063
1064 ring = &adev->uvd.inst[k].ring_enc[0];
1065 WREG32_SOC15(UVD, k, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1066 WREG32_SOC15(UVD, k, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1067 WREG32_SOC15(UVD, k, mmUVD_RB_BASE_LO, ring->gpu_addr);
1068 WREG32_SOC15(UVD, k, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1069 WREG32_SOC15(UVD, k, mmUVD_RB_SIZE, ring->ring_size / 4);
1070
1071 ring = &adev->uvd.inst[k].ring_enc[1];
1072 WREG32_SOC15(UVD, k, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1073 WREG32_SOC15(UVD, k, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1074 WREG32_SOC15(UVD, k, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1075 WREG32_SOC15(UVD, k, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1076 WREG32_SOC15(UVD, k, mmUVD_RB_SIZE2, ring->ring_size / 4);
1077 }
1044 return 0; 1078 return 0;
1045} 1079}
1046 1080
@@ -1053,26 +1087,30 @@ static int uvd_v7_0_start(struct amdgpu_device *adev)
1053 */ 1087 */
1054static void uvd_v7_0_stop(struct amdgpu_device *adev) 1088static void uvd_v7_0_stop(struct amdgpu_device *adev)
1055{ 1089{
1056 /* force RBC into idle state */ 1090 uint8_t i = 0;
1057 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, 0x11010101);
1058
1059 /* Stall UMC and register bus before resetting VCPU */
1060 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
1061 UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
1062 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1063 mdelay(1);
1064
1065 /* put VCPU into reset */
1066 WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET,
1067 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
1068 mdelay(5);
1069 1091
1070 /* disable VCPU clock */ 1092 for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
1071 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, 0x0); 1093 /* force RBC into idle state */
1094 WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, 0x11010101);
1072 1095
1073 /* Unstall UMC and register bus */ 1096 /* Stall UMC and register bus before resetting VCPU */
1074 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, 1097 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2),
1075 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 1098 UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
1099 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1100 mdelay(1);
1101
1102 /* put VCPU into reset */
1103 WREG32_SOC15(UVD, i, mmUVD_SOFT_RESET,
1104 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
1105 mdelay(5);
1106
1107 /* disable VCPU clock */
1108 WREG32_SOC15(UVD, i, mmUVD_VCPU_CNTL, 0x0);
1109
1110 /* Unstall UMC and register bus */
1111 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), 0,
1112 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1113 }
1076} 1114}
1077 1115
1078/** 1116/**
@@ -1091,26 +1129,26 @@ static void uvd_v7_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq
1091 WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); 1129 WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
1092 1130
1093 amdgpu_ring_write(ring, 1131 amdgpu_ring_write(ring,
1094 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); 1132 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0));
1095 amdgpu_ring_write(ring, seq); 1133 amdgpu_ring_write(ring, seq);
1096 amdgpu_ring_write(ring, 1134 amdgpu_ring_write(ring,
1097 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); 1135 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0));
1098 amdgpu_ring_write(ring, addr & 0xffffffff); 1136 amdgpu_ring_write(ring, addr & 0xffffffff);
1099 amdgpu_ring_write(ring, 1137 amdgpu_ring_write(ring,
1100 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); 1138 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0));
1101 amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff); 1139 amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff);
1102 amdgpu_ring_write(ring, 1140 amdgpu_ring_write(ring,
1103 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); 1141 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0));
1104 amdgpu_ring_write(ring, 0); 1142 amdgpu_ring_write(ring, 0);
1105 1143
1106 amdgpu_ring_write(ring, 1144 amdgpu_ring_write(ring,
1107 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); 1145 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0));
1108 amdgpu_ring_write(ring, 0); 1146 amdgpu_ring_write(ring, 0);
1109 amdgpu_ring_write(ring, 1147 amdgpu_ring_write(ring,
1110 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); 1148 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0));
1111 amdgpu_ring_write(ring, 0); 1149 amdgpu_ring_write(ring, 0);
1112 amdgpu_ring_write(ring, 1150 amdgpu_ring_write(ring,
1113 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); 1151 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0));
1114 amdgpu_ring_write(ring, 2); 1152 amdgpu_ring_write(ring, 2);
1115} 1153}
1116 1154
@@ -1136,6 +1174,16 @@ static void uvd_v7_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,
1136} 1174}
1137 1175
1138/** 1176/**
1177 * uvd_v7_0_ring_emit_hdp_flush - skip HDP flushing
1178 *
1179 * @ring: amdgpu_ring pointer
1180 */
1181static void uvd_v7_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
1182{
1183 /* The firmware doesn't seem to like touching registers at this point. */
1184}
1185
1186/**
1139 * uvd_v7_0_ring_test_ring - register write test 1187 * uvd_v7_0_ring_test_ring - register write test
1140 * 1188 *
1141 * @ring: amdgpu_ring pointer 1189 * @ring: amdgpu_ring pointer
@@ -1149,30 +1197,30 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring)
1149 unsigned i; 1197 unsigned i;
1150 int r; 1198 int r;
1151 1199
1152 WREG32_SOC15(UVD, 0, mmUVD_CONTEXT_ID, 0xCAFEDEAD); 1200 WREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID, 0xCAFEDEAD);
1153 r = amdgpu_ring_alloc(ring, 3); 1201 r = amdgpu_ring_alloc(ring, 3);
1154 if (r) { 1202 if (r) {
1155 DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", 1203 DRM_ERROR("amdgpu: (%d)cp failed to lock ring %d (%d).\n",
1156 ring->idx, r); 1204 ring->me, ring->idx, r);
1157 return r; 1205 return r;
1158 } 1206 }
1159 amdgpu_ring_write(ring, 1207 amdgpu_ring_write(ring,
1160 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); 1208 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0));
1161 amdgpu_ring_write(ring, 0xDEADBEEF); 1209 amdgpu_ring_write(ring, 0xDEADBEEF);
1162 amdgpu_ring_commit(ring); 1210 amdgpu_ring_commit(ring);
1163 for (i = 0; i < adev->usec_timeout; i++) { 1211 for (i = 0; i < adev->usec_timeout; i++) {
1164 tmp = RREG32_SOC15(UVD, 0, mmUVD_CONTEXT_ID); 1212 tmp = RREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID);
1165 if (tmp == 0xDEADBEEF) 1213 if (tmp == 0xDEADBEEF)
1166 break; 1214 break;
1167 DRM_UDELAY(1); 1215 DRM_UDELAY(1);
1168 } 1216 }
1169 1217
1170 if (i < adev->usec_timeout) { 1218 if (i < adev->usec_timeout) {
1171 DRM_DEBUG("ring test on %d succeeded in %d usecs\n", 1219 DRM_DEBUG("(%d)ring test on %d succeeded in %d usecs\n",
1172 ring->idx, i); 1220 ring->me, ring->idx, i);
1173 } else { 1221 } else {
1174 DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", 1222 DRM_ERROR("(%d)amdgpu: ring %d test failed (0x%08X)\n",
1175 ring->idx, tmp); 1223 ring->me, ring->idx, tmp);
1176 r = -EINVAL; 1224 r = -EINVAL;
1177 } 1225 }
1178 return r; 1226 return r;
@@ -1193,17 +1241,17 @@ static void uvd_v7_0_ring_emit_ib(struct amdgpu_ring *ring,
1193 struct amdgpu_device *adev = ring->adev; 1241 struct amdgpu_device *adev = ring->adev;
1194 1242
1195 amdgpu_ring_write(ring, 1243 amdgpu_ring_write(ring,
1196 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0)); 1244 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_VMID), 0));
1197 amdgpu_ring_write(ring, vmid); 1245 amdgpu_ring_write(ring, vmid);
1198 1246
1199 amdgpu_ring_write(ring, 1247 amdgpu_ring_write(ring,
1200 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0)); 1248 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0));
1201 amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); 1249 amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
1202 amdgpu_ring_write(ring, 1250 amdgpu_ring_write(ring,
1203 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0)); 1251 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0));
1204 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); 1252 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
1205 amdgpu_ring_write(ring, 1253 amdgpu_ring_write(ring,
1206 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_IB_SIZE), 0)); 1254 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_RBC_IB_SIZE), 0));
1207 amdgpu_ring_write(ring, ib->length_dw); 1255 amdgpu_ring_write(ring, ib->length_dw);
1208} 1256}
1209 1257
@@ -1231,13 +1279,13 @@ static void uvd_v7_0_ring_emit_wreg(struct amdgpu_ring *ring,
1231 struct amdgpu_device *adev = ring->adev; 1279 struct amdgpu_device *adev = ring->adev;
1232 1280
1233 amdgpu_ring_write(ring, 1281 amdgpu_ring_write(ring,
1234 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); 1282 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0));
1235 amdgpu_ring_write(ring, reg << 2); 1283 amdgpu_ring_write(ring, reg << 2);
1236 amdgpu_ring_write(ring, 1284 amdgpu_ring_write(ring,
1237 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); 1285 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0));
1238 amdgpu_ring_write(ring, val); 1286 amdgpu_ring_write(ring, val);
1239 amdgpu_ring_write(ring, 1287 amdgpu_ring_write(ring,
1240 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); 1288 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0));
1241 amdgpu_ring_write(ring, 8); 1289 amdgpu_ring_write(ring, 8);
1242} 1290}
1243 1291
@@ -1247,16 +1295,16 @@ static void uvd_v7_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
1247 struct amdgpu_device *adev = ring->adev; 1295 struct amdgpu_device *adev = ring->adev;
1248 1296
1249 amdgpu_ring_write(ring, 1297 amdgpu_ring_write(ring,
1250 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); 1298 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0));
1251 amdgpu_ring_write(ring, reg << 2); 1299 amdgpu_ring_write(ring, reg << 2);
1252 amdgpu_ring_write(ring, 1300 amdgpu_ring_write(ring,
1253 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); 1301 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0));
1254 amdgpu_ring_write(ring, val); 1302 amdgpu_ring_write(ring, val);
1255 amdgpu_ring_write(ring, 1303 amdgpu_ring_write(ring,
1256 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH8), 0)); 1304 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GP_SCRATCH8), 0));
1257 amdgpu_ring_write(ring, mask); 1305 amdgpu_ring_write(ring, mask);
1258 amdgpu_ring_write(ring, 1306 amdgpu_ring_write(ring,
1259 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); 1307 PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0));
1260 amdgpu_ring_write(ring, 12); 1308 amdgpu_ring_write(ring, 12);
1261} 1309}
1262 1310
@@ -1277,12 +1325,15 @@ static void uvd_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
1277 1325
1278static void uvd_v7_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) 1326static void uvd_v7_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
1279{ 1327{
1280 int i;
1281 struct amdgpu_device *adev = ring->adev; 1328 struct amdgpu_device *adev = ring->adev;
1329 int i;
1282 1330
1283 for (i = 0; i < count; i++) 1331 WARN_ON(ring->wptr % 2 || count % 2);
1284 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0));
1285 1332
1333 for (i = 0; i < count / 2; i++) {
1334 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_NO_OP), 0));
1335 amdgpu_ring_write(ring, 0);
1336 }
1286} 1337}
1287 1338
1288static void uvd_v7_0_enc_ring_insert_end(struct amdgpu_ring *ring) 1339static void uvd_v7_0_enc_ring_insert_end(struct amdgpu_ring *ring)
@@ -1349,16 +1400,16 @@ static bool uvd_v7_0_check_soft_reset(void *handle)
1349 1400
1350 if (REG_GET_FIELD(tmp, SRBM_STATUS, UVD_RQ_PENDING) || 1401 if (REG_GET_FIELD(tmp, SRBM_STATUS, UVD_RQ_PENDING) ||
1351 REG_GET_FIELD(tmp, SRBM_STATUS, UVD_BUSY) || 1402 REG_GET_FIELD(tmp, SRBM_STATUS, UVD_BUSY) ||
1352 (RREG32_SOC15(UVD, 0, mmUVD_STATUS) & 1403 (RREG32_SOC15(UVD, ring->me, mmUVD_STATUS) &
1353 AMDGPU_UVD_STATUS_BUSY_MASK)) 1404 AMDGPU_UVD_STATUS_BUSY_MASK))
1354 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, 1405 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
1355 SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); 1406 SRBM_SOFT_RESET, SOFT_RESET_UVD, 1);
1356 1407
1357 if (srbm_soft_reset) { 1408 if (srbm_soft_reset) {
1358 adev->uvd.srbm_soft_reset = srbm_soft_reset; 1409 adev->uvd.inst[ring->me].srbm_soft_reset = srbm_soft_reset;
1359 return true; 1410 return true;
1360 } else { 1411 } else {
1361 adev->uvd.srbm_soft_reset = 0; 1412 adev->uvd.inst[ring->me].srbm_soft_reset = 0;
1362 return false; 1413 return false;
1363 } 1414 }
1364} 1415}
@@ -1367,7 +1418,7 @@ static int uvd_v7_0_pre_soft_reset(void *handle)
1367{ 1418{
1368 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1419 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1369 1420
1370 if (!adev->uvd.srbm_soft_reset) 1421 if (!adev->uvd.inst[ring->me].srbm_soft_reset)
1371 return 0; 1422 return 0;
1372 1423
1373 uvd_v7_0_stop(adev); 1424 uvd_v7_0_stop(adev);
@@ -1379,9 +1430,9 @@ static int uvd_v7_0_soft_reset(void *handle)
1379 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1430 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1380 u32 srbm_soft_reset; 1431 u32 srbm_soft_reset;
1381 1432
1382 if (!adev->uvd.srbm_soft_reset) 1433 if (!adev->uvd.inst[ring->me].srbm_soft_reset)
1383 return 0; 1434 return 0;
1384 srbm_soft_reset = adev->uvd.srbm_soft_reset; 1435 srbm_soft_reset = adev->uvd.inst[ring->me].srbm_soft_reset;
1385 1436
1386 if (srbm_soft_reset) { 1437 if (srbm_soft_reset) {
1387 u32 tmp; 1438 u32 tmp;
@@ -1409,7 +1460,7 @@ static int uvd_v7_0_post_soft_reset(void *handle)
1409{ 1460{
1410 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1461 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1411 1462
1412 if (!adev->uvd.srbm_soft_reset) 1463 if (!adev->uvd.inst[ring->me].srbm_soft_reset)
1413 return 0; 1464 return 0;
1414 1465
1415 mdelay(5); 1466 mdelay(5);
@@ -1431,17 +1482,32 @@ static int uvd_v7_0_process_interrupt(struct amdgpu_device *adev,
1431 struct amdgpu_irq_src *source, 1482 struct amdgpu_irq_src *source,
1432 struct amdgpu_iv_entry *entry) 1483 struct amdgpu_iv_entry *entry)
1433{ 1484{
1485 uint32_t ip_instance;
1486
1487 switch (entry->client_id) {
1488 case SOC15_IH_CLIENTID_UVD:
1489 ip_instance = 0;
1490 break;
1491 case SOC15_IH_CLIENTID_UVD1:
1492 ip_instance = 1;
1493 break;
1494 default:
1495 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
1496 return 0;
1497 }
1498
1434 DRM_DEBUG("IH: UVD TRAP\n"); 1499 DRM_DEBUG("IH: UVD TRAP\n");
1500
1435 switch (entry->src_id) { 1501 switch (entry->src_id) {
1436 case 124: 1502 case 124:
1437 amdgpu_fence_process(&adev->uvd.ring); 1503 amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring);
1438 break; 1504 break;
1439 case 119: 1505 case 119:
1440 amdgpu_fence_process(&adev->uvd.ring_enc[0]); 1506 amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring_enc[0]);
1441 break; 1507 break;
1442 case 120: 1508 case 120:
1443 if (!amdgpu_sriov_vf(adev)) 1509 if (!amdgpu_sriov_vf(adev))
1444 amdgpu_fence_process(&adev->uvd.ring_enc[1]); 1510 amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring_enc[1]);
1445 break; 1511 break;
1446 default: 1512 default:
1447 DRM_ERROR("Unhandled interrupt: %d %d\n", 1513 DRM_ERROR("Unhandled interrupt: %d %d\n",
@@ -1457,9 +1523,9 @@ static void uvd_v7_0_set_sw_clock_gating(struct amdgpu_device *adev)
1457{ 1523{
1458 uint32_t data, data1, data2, suvd_flags; 1524 uint32_t data, data1, data2, suvd_flags;
1459 1525
1460 data = RREG32_SOC15(UVD, 0, mmUVD_CGC_CTRL); 1526 data = RREG32_SOC15(UVD, ring->me, mmUVD_CGC_CTRL);
1461 data1 = RREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE); 1527 data1 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE);
1462 data2 = RREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_CTRL); 1528 data2 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_CTRL);
1463 1529
1464 data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK | 1530 data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK |
1465 UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK); 1531 UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK);
@@ -1503,18 +1569,18 @@ static void uvd_v7_0_set_sw_clock_gating(struct amdgpu_device *adev)
1503 UVD_SUVD_CGC_CTRL__SDB_MODE_MASK); 1569 UVD_SUVD_CGC_CTRL__SDB_MODE_MASK);
1504 data1 |= suvd_flags; 1570 data1 |= suvd_flags;
1505 1571
1506 WREG32_SOC15(UVD, 0, mmUVD_CGC_CTRL, data); 1572 WREG32_SOC15(UVD, ring->me, mmUVD_CGC_CTRL, data);
1507 WREG32_SOC15(UVD, 0, mmUVD_CGC_GATE, 0); 1573 WREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE, 0);
1508 WREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE, data1); 1574 WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE, data1);
1509 WREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_CTRL, data2); 1575 WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_CTRL, data2);
1510} 1576}
1511 1577
1512static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev) 1578static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev)
1513{ 1579{
1514 uint32_t data, data1, cgc_flags, suvd_flags; 1580 uint32_t data, data1, cgc_flags, suvd_flags;
1515 1581
1516 data = RREG32_SOC15(UVD, 0, mmUVD_CGC_GATE); 1582 data = RREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE);
1517 data1 = RREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE); 1583 data1 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE);
1518 1584
1519 cgc_flags = UVD_CGC_GATE__SYS_MASK | 1585 cgc_flags = UVD_CGC_GATE__SYS_MASK |
1520 UVD_CGC_GATE__UDEC_MASK | 1586 UVD_CGC_GATE__UDEC_MASK |
@@ -1546,8 +1612,8 @@ static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev)
1546 data |= cgc_flags; 1612 data |= cgc_flags;
1547 data1 |= suvd_flags; 1613 data1 |= suvd_flags;
1548 1614
1549 WREG32_SOC15(UVD, 0, mmUVD_CGC_GATE, data); 1615 WREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE, data);
1550 WREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE, data1); 1616 WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE, data1);
1551} 1617}
1552 1618
1553static void uvd_v7_0_set_bypass_mode(struct amdgpu_device *adev, bool enable) 1619static void uvd_v7_0_set_bypass_mode(struct amdgpu_device *adev, bool enable)
@@ -1606,7 +1672,7 @@ static int uvd_v7_0_set_powergating_state(void *handle,
1606 if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD)) 1672 if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD))
1607 return 0; 1673 return 0;
1608 1674
1609 WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK); 1675 WREG32_SOC15(UVD, ring->me, mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK);
1610 1676
1611 if (state == AMD_PG_STATE_GATE) { 1677 if (state == AMD_PG_STATE_GATE) {
1612 uvd_v7_0_stop(adev); 1678 uvd_v7_0_stop(adev);
@@ -1647,14 +1713,13 @@ const struct amd_ip_funcs uvd_v7_0_ip_funcs = {
1647static const struct amdgpu_ring_funcs uvd_v7_0_ring_vm_funcs = { 1713static const struct amdgpu_ring_funcs uvd_v7_0_ring_vm_funcs = {
1648 .type = AMDGPU_RING_TYPE_UVD, 1714 .type = AMDGPU_RING_TYPE_UVD,
1649 .align_mask = 0xf, 1715 .align_mask = 0xf,
1650 .nop = PACKET0(0x81ff, 0),
1651 .support_64bit_ptrs = false, 1716 .support_64bit_ptrs = false,
1652 .vmhub = AMDGPU_MMHUB, 1717 .vmhub = AMDGPU_MMHUB,
1653 .get_rptr = uvd_v7_0_ring_get_rptr, 1718 .get_rptr = uvd_v7_0_ring_get_rptr,
1654 .get_wptr = uvd_v7_0_ring_get_wptr, 1719 .get_wptr = uvd_v7_0_ring_get_wptr,
1655 .set_wptr = uvd_v7_0_ring_set_wptr, 1720 .set_wptr = uvd_v7_0_ring_set_wptr,
1656 .emit_frame_size = 1721 .emit_frame_size =
1657 6 + 6 + /* hdp flush / invalidate */ 1722 6 + /* hdp invalidate */
1658 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 1723 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1659 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 1724 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1660 8 + /* uvd_v7_0_ring_emit_vm_flush */ 1725 8 + /* uvd_v7_0_ring_emit_vm_flush */
@@ -1663,6 +1728,7 @@ static const struct amdgpu_ring_funcs uvd_v7_0_ring_vm_funcs = {
1663 .emit_ib = uvd_v7_0_ring_emit_ib, 1728 .emit_ib = uvd_v7_0_ring_emit_ib,
1664 .emit_fence = uvd_v7_0_ring_emit_fence, 1729 .emit_fence = uvd_v7_0_ring_emit_fence,
1665 .emit_vm_flush = uvd_v7_0_ring_emit_vm_flush, 1730 .emit_vm_flush = uvd_v7_0_ring_emit_vm_flush,
1731 .emit_hdp_flush = uvd_v7_0_ring_emit_hdp_flush,
1666 .test_ring = uvd_v7_0_ring_test_ring, 1732 .test_ring = uvd_v7_0_ring_test_ring,
1667 .test_ib = amdgpu_uvd_ring_test_ib, 1733 .test_ib = amdgpu_uvd_ring_test_ib,
1668 .insert_nop = uvd_v7_0_ring_insert_nop, 1734 .insert_nop = uvd_v7_0_ring_insert_nop,
@@ -1671,6 +1737,7 @@ static const struct amdgpu_ring_funcs uvd_v7_0_ring_vm_funcs = {
1671 .end_use = amdgpu_uvd_ring_end_use, 1737 .end_use = amdgpu_uvd_ring_end_use,
1672 .emit_wreg = uvd_v7_0_ring_emit_wreg, 1738 .emit_wreg = uvd_v7_0_ring_emit_wreg,
1673 .emit_reg_wait = uvd_v7_0_ring_emit_reg_wait, 1739 .emit_reg_wait = uvd_v7_0_ring_emit_reg_wait,
1740 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1674}; 1741};
1675 1742
1676static const struct amdgpu_ring_funcs uvd_v7_0_enc_ring_vm_funcs = { 1743static const struct amdgpu_ring_funcs uvd_v7_0_enc_ring_vm_funcs = {
@@ -1702,22 +1769,32 @@ static const struct amdgpu_ring_funcs uvd_v7_0_enc_ring_vm_funcs = {
1702 .end_use = amdgpu_uvd_ring_end_use, 1769 .end_use = amdgpu_uvd_ring_end_use,
1703 .emit_wreg = uvd_v7_0_enc_ring_emit_wreg, 1770 .emit_wreg = uvd_v7_0_enc_ring_emit_wreg,
1704 .emit_reg_wait = uvd_v7_0_enc_ring_emit_reg_wait, 1771 .emit_reg_wait = uvd_v7_0_enc_ring_emit_reg_wait,
1772 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1705}; 1773};
1706 1774
1707static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev) 1775static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev)
1708{ 1776{
1709 adev->uvd.ring.funcs = &uvd_v7_0_ring_vm_funcs; 1777 int i;
1710 DRM_INFO("UVD is enabled in VM mode\n"); 1778
1779 for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
1780 adev->uvd.inst[i].ring.funcs = &uvd_v7_0_ring_vm_funcs;
1781 adev->uvd.inst[i].ring.me = i;
1782 DRM_INFO("UVD(%d) is enabled in VM mode\n", i);
1783 }
1711} 1784}
1712 1785
1713static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev) 1786static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev)
1714{ 1787{
1715 int i; 1788 int i, j;
1716 1789
1717 for (i = 0; i < adev->uvd.num_enc_rings; ++i) 1790 for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
1718 adev->uvd.ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs; 1791 for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
1792 adev->uvd.inst[j].ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs;
1793 adev->uvd.inst[j].ring_enc[i].me = j;
1794 }
1719 1795
1720 DRM_INFO("UVD ENC is enabled in VM mode\n"); 1796 DRM_INFO("UVD(%d) ENC is enabled in VM mode\n", j);
1797 }
1721} 1798}
1722 1799
1723static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = { 1800static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = {
@@ -1727,8 +1804,12 @@ static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = {
1727 1804
1728static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev) 1805static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev)
1729{ 1806{
1730 adev->uvd.irq.num_types = adev->uvd.num_enc_rings + 1; 1807 int i;
1731 adev->uvd.irq.funcs = &uvd_v7_0_irq_funcs; 1808
1809 for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
1810 adev->uvd.inst[i].irq.num_types = adev->uvd.num_enc_rings + 1;
1811 adev->uvd.inst[i].irq.funcs = &uvd_v7_0_irq_funcs;
1812 }
1732} 1813}
1733 1814
1734const struct amdgpu_ip_block_version uvd_v7_0_ip_block = 1815const struct amdgpu_ip_block_version uvd_v7_0_ip_block =
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
index 428d1928e44e..0999c843f623 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
@@ -388,7 +388,8 @@ static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
388 default: 388 default:
389 if ((adev->asic_type == CHIP_POLARIS10) || 389 if ((adev->asic_type == CHIP_POLARIS10) ||
390 (adev->asic_type == CHIP_POLARIS11) || 390 (adev->asic_type == CHIP_POLARIS11) ||
391 (adev->asic_type == CHIP_POLARIS12)) 391 (adev->asic_type == CHIP_POLARIS12) ||
392 (adev->asic_type == CHIP_VEGAM))
392 return AMDGPU_VCE_HARVEST_VCE1; 393 return AMDGPU_VCE_HARVEST_VCE1;
393 394
394 return 0; 395 return 0;
@@ -467,8 +468,8 @@ static int vce_v3_0_hw_init(void *handle)
467 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 468 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
468 469
469 vce_v3_0_override_vce_clock_gating(adev, true); 470 vce_v3_0_override_vce_clock_gating(adev, true);
470 if (!(adev->flags & AMD_IS_APU)) 471
471 amdgpu_asic_set_vce_clocks(adev, 10000, 10000); 472 amdgpu_asic_set_vce_clocks(adev, 10000, 10000);
472 473
473 for (i = 0; i < adev->vce.num_rings; i++) 474 for (i = 0; i < adev->vce.num_rings; i++)
474 adev->vce.ring[i].ready = false; 475 adev->vce.ring[i].ready = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
index 73fd48d6c756..8fd1b742985a 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
@@ -1081,6 +1081,7 @@ static const struct amdgpu_ring_funcs vce_v4_0_ring_vm_funcs = {
1081 .end_use = amdgpu_vce_ring_end_use, 1081 .end_use = amdgpu_vce_ring_end_use,
1082 .emit_wreg = vce_v4_0_emit_wreg, 1082 .emit_wreg = vce_v4_0_emit_wreg,
1083 .emit_reg_wait = vce_v4_0_emit_reg_wait, 1083 .emit_reg_wait = vce_v4_0_emit_reg_wait,
1084 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1084}; 1085};
1085 1086
1086static void vce_v4_0_set_ring_funcs(struct amdgpu_device *adev) 1087static void vce_v4_0_set_ring_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
index 8c132673bc79..110b294ebed3 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
@@ -35,7 +35,6 @@
35#include "mmhub/mmhub_9_1_offset.h" 35#include "mmhub/mmhub_9_1_offset.h"
36#include "mmhub/mmhub_9_1_sh_mask.h" 36#include "mmhub/mmhub_9_1_sh_mask.h"
37 37
38static int vcn_v1_0_start(struct amdgpu_device *adev);
39static int vcn_v1_0_stop(struct amdgpu_device *adev); 38static int vcn_v1_0_stop(struct amdgpu_device *adev);
40static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); 39static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
41static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); 40static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev);
@@ -146,10 +145,6 @@ static int vcn_v1_0_hw_init(void *handle)
146 struct amdgpu_ring *ring = &adev->vcn.ring_dec; 145 struct amdgpu_ring *ring = &adev->vcn.ring_dec;
147 int i, r; 146 int i, r;
148 147
149 r = vcn_v1_0_start(adev);
150 if (r)
151 goto done;
152
153 ring->ready = true; 148 ring->ready = true;
154 r = amdgpu_ring_test_ring(ring); 149 r = amdgpu_ring_test_ring(ring);
155 if (r) { 150 if (r) {
@@ -185,11 +180,9 @@ static int vcn_v1_0_hw_fini(void *handle)
185{ 180{
186 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 181 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
187 struct amdgpu_ring *ring = &adev->vcn.ring_dec; 182 struct amdgpu_ring *ring = &adev->vcn.ring_dec;
188 int r;
189 183
190 r = vcn_v1_0_stop(adev); 184 if (RREG32_SOC15(VCN, 0, mmUVD_STATUS))
191 if (r) 185 vcn_v1_0_stop(adev);
192 return r;
193 186
194 ring->ready = false; 187 ring->ready = false;
195 188
@@ -288,14 +281,14 @@ static void vcn_v1_0_mc_resume(struct amdgpu_device *adev)
288 * 281 *
289 * Disable clock gating for VCN block 282 * Disable clock gating for VCN block
290 */ 283 */
291static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev, bool sw) 284static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev)
292{ 285{
293 uint32_t data; 286 uint32_t data;
294 287
295 /* JPEG disable CGC */ 288 /* JPEG disable CGC */
296 data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL); 289 data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL);
297 290
298 if (sw) 291 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
299 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 292 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
300 else 293 else
301 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE_MASK; 294 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE_MASK;
@@ -310,7 +303,7 @@ static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev, bool sw)
310 303
311 /* UVD disable CGC */ 304 /* UVD disable CGC */
312 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL); 305 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
313 if (sw) 306 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
314 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 307 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
315 else 308 else
316 data &= ~ UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; 309 data &= ~ UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
@@ -415,13 +408,13 @@ static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev, bool sw)
415 * 408 *
416 * Enable clock gating for VCN block 409 * Enable clock gating for VCN block
417 */ 410 */
418static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev, bool sw) 411static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev)
419{ 412{
420 uint32_t data = 0; 413 uint32_t data = 0;
421 414
422 /* enable JPEG CGC */ 415 /* enable JPEG CGC */
423 data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL); 416 data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL);
424 if (sw) 417 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
425 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 418 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
426 else 419 else
427 data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 420 data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
@@ -435,7 +428,7 @@ static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev, bool sw)
435 428
436 /* enable UVD CGC */ 429 /* enable UVD CGC */
437 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL); 430 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
438 if (sw) 431 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
439 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 432 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
440 else 433 else
441 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 434 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
@@ -480,6 +473,94 @@ static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev, bool sw)
480 WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data); 473 WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data);
481} 474}
482 475
476static void vcn_1_0_disable_static_power_gating(struct amdgpu_device *adev)
477{
478 uint32_t data = 0;
479 int ret;
480
481 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
482 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
483 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
484 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
485 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
486 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
487 | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT
488 | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT
489 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
490 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
491 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
492 | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);
493
494 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);
495 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON, 0xFFFFFF, ret);
496 } else {
497 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
498 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
499 | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
500 | 1 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
501 | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
502 | 1 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT
503 | 1 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT
504 | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
505 | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
506 | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
507 | 1 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);
508 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);
509 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, 0, 0xFFFFFFFF, ret);
510 }
511
512 /* polling UVD_PGFSM_STATUS to confirm UVDM_PWR_STATUS , UVDU_PWR_STATUS are 0 (power on) */
513
514 data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS);
515 data &= ~0x103;
516 if (adev->pg_flags & AMD_PG_SUPPORT_VCN)
517 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON | UVD_POWER_STATUS__UVD_PG_EN_MASK;
518
519 WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data);
520}
521
522static void vcn_1_0_enable_static_power_gating(struct amdgpu_device *adev)
523{
524 uint32_t data = 0;
525 int ret;
526
527 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
528 /* Before power off, this indicator has to be turned on */
529 data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS);
530 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK;
531 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF;
532 WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data);
533
534
535 data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
536 | 2 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
537 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
538 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
539 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
540 | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT
541 | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT
542 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
543 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
544 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
545 | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);
546
547 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);
548
549 data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT
550 | 2 << UVD_PGFSM_STATUS__UVDU_PWR_STATUS__SHIFT
551 | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT
552 | 2 << UVD_PGFSM_STATUS__UVDC_PWR_STATUS__SHIFT
553 | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT
554 | 2 << UVD_PGFSM_STATUS__UVDIL_PWR_STATUS__SHIFT
555 | 2 << UVD_PGFSM_STATUS__UVDIR_PWR_STATUS__SHIFT
556 | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT
557 | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT
558 | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT
559 | 2 << UVD_PGFSM_STATUS__UVDW_PWR_STATUS__SHIFT);
560 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, data, 0xFFFFFFFF, ret);
561 }
562}
563
483/** 564/**
484 * vcn_v1_0_start - start VCN block 565 * vcn_v1_0_start - start VCN block
485 * 566 *
@@ -499,8 +580,9 @@ static int vcn_v1_0_start(struct amdgpu_device *adev)
499 580
500 vcn_v1_0_mc_resume(adev); 581 vcn_v1_0_mc_resume(adev);
501 582
583 vcn_1_0_disable_static_power_gating(adev);
502 /* disable clock gating */ 584 /* disable clock gating */
503 vcn_v1_0_disable_clock_gating(adev, true); 585 vcn_v1_0_disable_clock_gating(adev);
504 586
505 /* disable interupt */ 587 /* disable interupt */
506 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0, 588 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0,
@@ -680,16 +762,45 @@ static int vcn_v1_0_stop(struct amdgpu_device *adev)
680 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, 762 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0,
681 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 763 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
682 764
683 /* enable clock gating */ 765 WREG32_SOC15(VCN, 0, mmUVD_STATUS, 0);
684 vcn_v1_0_enable_clock_gating(adev, true);
685 766
767 vcn_v1_0_enable_clock_gating(adev);
768 vcn_1_0_enable_static_power_gating(adev);
686 return 0; 769 return 0;
687} 770}
688 771
772bool vcn_v1_0_is_idle(void *handle)
773{
774 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
775
776 return (RREG32_SOC15(VCN, 0, mmUVD_STATUS) == 0x2);
777}
778
779int vcn_v1_0_wait_for_idle(void *handle)
780{
781 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
782 int ret = 0;
783
784 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, 0x2, 0x2, ret);
785
786 return ret;
787}
788
689static int vcn_v1_0_set_clockgating_state(void *handle, 789static int vcn_v1_0_set_clockgating_state(void *handle,
690 enum amd_clockgating_state state) 790 enum amd_clockgating_state state)
691{ 791{
692 /* needed for driver unload*/ 792 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
793 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
794
795 if (enable) {
796 /* wait for STATUS to clear */
797 if (vcn_v1_0_is_idle(handle))
798 return -EBUSY;
799 vcn_v1_0_enable_clock_gating(adev);
800 } else {
801 /* disable HW gating and enable Sw gating */
802 vcn_v1_0_disable_clock_gating(adev);
803 }
693 return 0; 804 return 0;
694} 805}
695 806
@@ -1048,16 +1159,36 @@ static int vcn_v1_0_process_interrupt(struct amdgpu_device *adev,
1048 return 0; 1159 return 0;
1049} 1160}
1050 1161
1051static void vcn_v1_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) 1162static void vcn_v1_0_dec_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
1052{ 1163{
1053 int i;
1054 struct amdgpu_device *adev = ring->adev; 1164 struct amdgpu_device *adev = ring->adev;
1165 int i;
1055 1166
1056 for (i = 0; i < count; i++) 1167 WARN_ON(ring->wptr % 2 || count % 2);
1057 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0));
1058 1168
1169 for (i = 0; i < count / 2; i++) {
1170 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0));
1171 amdgpu_ring_write(ring, 0);
1172 }
1059} 1173}
1060 1174
1175static int vcn_v1_0_set_powergating_state(void *handle,
1176 enum amd_powergating_state state)
1177{
1178 /* This doesn't actually powergate the VCN block.
1179 * That's done in the dpm code via the SMC. This
1180 * just re-inits the block as necessary. The actual
1181 * gating still happens in the dpm code. We should
1182 * revisit this when there is a cleaner line between
1183 * the smc and the hw blocks
1184 */
1185 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1186
1187 if (state == AMD_PG_STATE_GATE)
1188 return vcn_v1_0_stop(adev);
1189 else
1190 return vcn_v1_0_start(adev);
1191}
1061 1192
1062static const struct amd_ip_funcs vcn_v1_0_ip_funcs = { 1193static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {
1063 .name = "vcn_v1_0", 1194 .name = "vcn_v1_0",
@@ -1069,20 +1200,19 @@ static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {
1069 .hw_fini = vcn_v1_0_hw_fini, 1200 .hw_fini = vcn_v1_0_hw_fini,
1070 .suspend = vcn_v1_0_suspend, 1201 .suspend = vcn_v1_0_suspend,
1071 .resume = vcn_v1_0_resume, 1202 .resume = vcn_v1_0_resume,
1072 .is_idle = NULL /* vcn_v1_0_is_idle */, 1203 .is_idle = vcn_v1_0_is_idle,
1073 .wait_for_idle = NULL /* vcn_v1_0_wait_for_idle */, 1204 .wait_for_idle = vcn_v1_0_wait_for_idle,
1074 .check_soft_reset = NULL /* vcn_v1_0_check_soft_reset */, 1205 .check_soft_reset = NULL /* vcn_v1_0_check_soft_reset */,
1075 .pre_soft_reset = NULL /* vcn_v1_0_pre_soft_reset */, 1206 .pre_soft_reset = NULL /* vcn_v1_0_pre_soft_reset */,
1076 .soft_reset = NULL /* vcn_v1_0_soft_reset */, 1207 .soft_reset = NULL /* vcn_v1_0_soft_reset */,
1077 .post_soft_reset = NULL /* vcn_v1_0_post_soft_reset */, 1208 .post_soft_reset = NULL /* vcn_v1_0_post_soft_reset */,
1078 .set_clockgating_state = vcn_v1_0_set_clockgating_state, 1209 .set_clockgating_state = vcn_v1_0_set_clockgating_state,
1079 .set_powergating_state = NULL /* vcn_v1_0_set_powergating_state */, 1210 .set_powergating_state = vcn_v1_0_set_powergating_state,
1080}; 1211};
1081 1212
1082static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { 1213static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = {
1083 .type = AMDGPU_RING_TYPE_VCN_DEC, 1214 .type = AMDGPU_RING_TYPE_VCN_DEC,
1084 .align_mask = 0xf, 1215 .align_mask = 0xf,
1085 .nop = PACKET0(0x81ff, 0),
1086 .support_64bit_ptrs = false, 1216 .support_64bit_ptrs = false,
1087 .vmhub = AMDGPU_MMHUB, 1217 .vmhub = AMDGPU_MMHUB,
1088 .get_rptr = vcn_v1_0_dec_ring_get_rptr, 1218 .get_rptr = vcn_v1_0_dec_ring_get_rptr,
@@ -1101,7 +1231,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = {
1101 .emit_vm_flush = vcn_v1_0_dec_ring_emit_vm_flush, 1231 .emit_vm_flush = vcn_v1_0_dec_ring_emit_vm_flush,
1102 .test_ring = amdgpu_vcn_dec_ring_test_ring, 1232 .test_ring = amdgpu_vcn_dec_ring_test_ring,
1103 .test_ib = amdgpu_vcn_dec_ring_test_ib, 1233 .test_ib = amdgpu_vcn_dec_ring_test_ib,
1104 .insert_nop = vcn_v1_0_ring_insert_nop, 1234 .insert_nop = vcn_v1_0_dec_ring_insert_nop,
1105 .insert_start = vcn_v1_0_dec_ring_insert_start, 1235 .insert_start = vcn_v1_0_dec_ring_insert_start,
1106 .insert_end = vcn_v1_0_dec_ring_insert_end, 1236 .insert_end = vcn_v1_0_dec_ring_insert_end,
1107 .pad_ib = amdgpu_ring_generic_pad_ib, 1237 .pad_ib = amdgpu_ring_generic_pad_ib,
@@ -1109,6 +1239,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = {
1109 .end_use = amdgpu_vcn_ring_end_use, 1239 .end_use = amdgpu_vcn_ring_end_use,
1110 .emit_wreg = vcn_v1_0_dec_ring_emit_wreg, 1240 .emit_wreg = vcn_v1_0_dec_ring_emit_wreg,
1111 .emit_reg_wait = vcn_v1_0_dec_ring_emit_reg_wait, 1241 .emit_reg_wait = vcn_v1_0_dec_ring_emit_reg_wait,
1242 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1112}; 1243};
1113 1244
1114static const struct amdgpu_ring_funcs vcn_v1_0_enc_ring_vm_funcs = { 1245static const struct amdgpu_ring_funcs vcn_v1_0_enc_ring_vm_funcs = {
@@ -1139,6 +1270,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_enc_ring_vm_funcs = {
1139 .end_use = amdgpu_vcn_ring_end_use, 1270 .end_use = amdgpu_vcn_ring_end_use,
1140 .emit_wreg = vcn_v1_0_enc_ring_emit_wreg, 1271 .emit_wreg = vcn_v1_0_enc_ring_emit_wreg,
1141 .emit_reg_wait = vcn_v1_0_enc_ring_emit_reg_wait, 1272 .emit_reg_wait = vcn_v1_0_enc_ring_emit_reg_wait,
1273 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1142}; 1274};
1143 1275
1144static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) 1276static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c
new file mode 100644
index 000000000000..52778de93ab0
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#include "amdgpu.h"
24#include "soc15.h"
25
26#include "soc15_common.h"
27#include "soc15_hw_ip.h"
28#include "vega20_ip_offset.h"
29
30int vega20_reg_base_init(struct amdgpu_device *adev)
31{
32 /* HW has more IP blocks, only initialized the blocke beend by our driver */
33 uint32_t i;
34 for (i = 0 ; i < MAX_INSTANCE ; ++i) {
35 adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
36 adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
37 adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
38 adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
39 adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
40 adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
41 adev->reg_offset[UVD_HWIP][i] = (uint32_t *)(&(UVD_BASE.instance[i]));
42 adev->reg_offset[VCE_HWIP][i] = (uint32_t *)(&(VCE_BASE.instance[i]));
43 adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
44 adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCE_BASE.instance[i]));
45 adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
46 adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(SDMA0_BASE.instance[i]));
47 adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(SDMA1_BASE.instance[i]));
48 adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
49 }
50 return 0;
51}
52
53
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 126f1276d347..4ac1288ab7df 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -305,9 +305,10 @@ static void vi_init_golden_registers(struct amdgpu_device *adev)
305 stoney_mgcg_cgcg_init, 305 stoney_mgcg_cgcg_init,
306 ARRAY_SIZE(stoney_mgcg_cgcg_init)); 306 ARRAY_SIZE(stoney_mgcg_cgcg_init));
307 break; 307 break;
308 case CHIP_POLARIS11:
309 case CHIP_POLARIS10: 308 case CHIP_POLARIS10:
309 case CHIP_POLARIS11:
310 case CHIP_POLARIS12: 310 case CHIP_POLARIS12:
311 case CHIP_VEGAM:
311 default: 312 default:
312 break; 313 break;
313 } 314 }
@@ -728,33 +729,59 @@ static int vi_set_uvd_clock(struct amdgpu_device *adev, u32 clock,
728 return r; 729 return r;
729 730
730 tmp = RREG32_SMC(cntl_reg); 731 tmp = RREG32_SMC(cntl_reg);
731 tmp &= ~(CG_DCLK_CNTL__DCLK_DIR_CNTL_EN_MASK | 732
732 CG_DCLK_CNTL__DCLK_DIVIDER_MASK); 733 if (adev->flags & AMD_IS_APU)
734 tmp &= ~CG_DCLK_CNTL__DCLK_DIVIDER_MASK;
735 else
736 tmp &= ~(CG_DCLK_CNTL__DCLK_DIR_CNTL_EN_MASK |
737 CG_DCLK_CNTL__DCLK_DIVIDER_MASK);
733 tmp |= dividers.post_divider; 738 tmp |= dividers.post_divider;
734 WREG32_SMC(cntl_reg, tmp); 739 WREG32_SMC(cntl_reg, tmp);
735 740
736 for (i = 0; i < 100; i++) { 741 for (i = 0; i < 100; i++) {
737 if (RREG32_SMC(status_reg) & CG_DCLK_STATUS__DCLK_STATUS_MASK) 742 tmp = RREG32_SMC(status_reg);
738 break; 743 if (adev->flags & AMD_IS_APU) {
744 if (tmp & 0x10000)
745 break;
746 } else {
747 if (tmp & CG_DCLK_STATUS__DCLK_STATUS_MASK)
748 break;
749 }
739 mdelay(10); 750 mdelay(10);
740 } 751 }
741 if (i == 100) 752 if (i == 100)
742 return -ETIMEDOUT; 753 return -ETIMEDOUT;
743
744 return 0; 754 return 0;
745} 755}
746 756
757#define ixGNB_CLK1_DFS_CNTL 0xD82200F0
758#define ixGNB_CLK1_STATUS 0xD822010C
759#define ixGNB_CLK2_DFS_CNTL 0xD8220110
760#define ixGNB_CLK2_STATUS 0xD822012C
761#define ixGNB_CLK3_DFS_CNTL 0xD8220130
762#define ixGNB_CLK3_STATUS 0xD822014C
763
747static int vi_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk) 764static int vi_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk)
748{ 765{
749 int r; 766 int r;
750 767
751 r = vi_set_uvd_clock(adev, vclk, ixCG_VCLK_CNTL, ixCG_VCLK_STATUS); 768 if (adev->flags & AMD_IS_APU) {
752 if (r) 769 r = vi_set_uvd_clock(adev, vclk, ixGNB_CLK2_DFS_CNTL, ixGNB_CLK2_STATUS);
753 return r; 770 if (r)
771 return r;
754 772
755 r = vi_set_uvd_clock(adev, dclk, ixCG_DCLK_CNTL, ixCG_DCLK_STATUS); 773 r = vi_set_uvd_clock(adev, dclk, ixGNB_CLK1_DFS_CNTL, ixGNB_CLK1_STATUS);
756 if (r) 774 if (r)
757 return r; 775 return r;
776 } else {
777 r = vi_set_uvd_clock(adev, vclk, ixCG_VCLK_CNTL, ixCG_VCLK_STATUS);
778 if (r)
779 return r;
780
781 r = vi_set_uvd_clock(adev, dclk, ixCG_DCLK_CNTL, ixCG_DCLK_STATUS);
782 if (r)
783 return r;
784 }
758 785
759 return 0; 786 return 0;
760} 787}
@@ -764,6 +791,22 @@ static int vi_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
764 int r, i; 791 int r, i;
765 struct atom_clock_dividers dividers; 792 struct atom_clock_dividers dividers;
766 u32 tmp; 793 u32 tmp;
794 u32 reg_ctrl;
795 u32 reg_status;
796 u32 status_mask;
797 u32 reg_mask;
798
799 if (adev->flags & AMD_IS_APU) {
800 reg_ctrl = ixGNB_CLK3_DFS_CNTL;
801 reg_status = ixGNB_CLK3_STATUS;
802 status_mask = 0x00010000;
803 reg_mask = CG_ECLK_CNTL__ECLK_DIVIDER_MASK;
804 } else {
805 reg_ctrl = ixCG_ECLK_CNTL;
806 reg_status = ixCG_ECLK_STATUS;
807 status_mask = CG_ECLK_STATUS__ECLK_STATUS_MASK;
808 reg_mask = CG_ECLK_CNTL__ECLK_DIR_CNTL_EN_MASK | CG_ECLK_CNTL__ECLK_DIVIDER_MASK;
809 }
767 810
768 r = amdgpu_atombios_get_clock_dividers(adev, 811 r = amdgpu_atombios_get_clock_dividers(adev,
769 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, 812 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
@@ -772,24 +815,25 @@ static int vi_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
772 return r; 815 return r;
773 816
774 for (i = 0; i < 100; i++) { 817 for (i = 0; i < 100; i++) {
775 if (RREG32_SMC(ixCG_ECLK_STATUS) & CG_ECLK_STATUS__ECLK_STATUS_MASK) 818 if (RREG32_SMC(reg_status) & status_mask)
776 break; 819 break;
777 mdelay(10); 820 mdelay(10);
778 } 821 }
822
779 if (i == 100) 823 if (i == 100)
780 return -ETIMEDOUT; 824 return -ETIMEDOUT;
781 825
782 tmp = RREG32_SMC(ixCG_ECLK_CNTL); 826 tmp = RREG32_SMC(reg_ctrl);
783 tmp &= ~(CG_ECLK_CNTL__ECLK_DIR_CNTL_EN_MASK | 827 tmp &= ~reg_mask;
784 CG_ECLK_CNTL__ECLK_DIVIDER_MASK);
785 tmp |= dividers.post_divider; 828 tmp |= dividers.post_divider;
786 WREG32_SMC(ixCG_ECLK_CNTL, tmp); 829 WREG32_SMC(reg_ctrl, tmp);
787 830
788 for (i = 0; i < 100; i++) { 831 for (i = 0; i < 100; i++) {
789 if (RREG32_SMC(ixCG_ECLK_STATUS) & CG_ECLK_STATUS__ECLK_STATUS_MASK) 832 if (RREG32_SMC(reg_status) & status_mask)
790 break; 833 break;
791 mdelay(10); 834 mdelay(10);
792 } 835 }
836
793 if (i == 100) 837 if (i == 100)
794 return -ETIMEDOUT; 838 return -ETIMEDOUT;
795 839
@@ -876,6 +920,27 @@ static void vi_invalidate_hdp(struct amdgpu_device *adev,
876 } 920 }
877} 921}
878 922
923static bool vi_need_full_reset(struct amdgpu_device *adev)
924{
925 switch (adev->asic_type) {
926 case CHIP_CARRIZO:
927 case CHIP_STONEY:
928 /* CZ has hang issues with full reset at the moment */
929 return false;
930 case CHIP_FIJI:
931 case CHIP_TONGA:
932 /* XXX: soft reset should work on fiji and tonga */
933 return true;
934 case CHIP_POLARIS10:
935 case CHIP_POLARIS11:
936 case CHIP_POLARIS12:
937 case CHIP_TOPAZ:
938 default:
939 /* change this when we support soft reset */
940 return true;
941 }
942}
943
879static const struct amdgpu_asic_funcs vi_asic_funcs = 944static const struct amdgpu_asic_funcs vi_asic_funcs =
880{ 945{
881 .read_disabled_bios = &vi_read_disabled_bios, 946 .read_disabled_bios = &vi_read_disabled_bios,
@@ -889,6 +954,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs =
889 .get_config_memsize = &vi_get_config_memsize, 954 .get_config_memsize = &vi_get_config_memsize,
890 .flush_hdp = &vi_flush_hdp, 955 .flush_hdp = &vi_flush_hdp,
891 .invalidate_hdp = &vi_invalidate_hdp, 956 .invalidate_hdp = &vi_invalidate_hdp,
957 .need_full_reset = &vi_need_full_reset,
892}; 958};
893 959
894#define CZ_REV_BRISTOL(rev) \ 960#define CZ_REV_BRISTOL(rev) \
@@ -1031,6 +1097,30 @@ static int vi_common_early_init(void *handle)
1031 adev->pg_flags = 0; 1097 adev->pg_flags = 0;
1032 adev->external_rev_id = adev->rev_id + 0x64; 1098 adev->external_rev_id = adev->rev_id + 0x64;
1033 break; 1099 break;
1100 case CHIP_VEGAM:
1101 adev->cg_flags = 0;
1102 /*AMD_CG_SUPPORT_GFX_MGCG |
1103 AMD_CG_SUPPORT_GFX_RLC_LS |
1104 AMD_CG_SUPPORT_GFX_CP_LS |
1105 AMD_CG_SUPPORT_GFX_CGCG |
1106 AMD_CG_SUPPORT_GFX_CGLS |
1107 AMD_CG_SUPPORT_GFX_3D_CGCG |
1108 AMD_CG_SUPPORT_GFX_3D_CGLS |
1109 AMD_CG_SUPPORT_SDMA_MGCG |
1110 AMD_CG_SUPPORT_SDMA_LS |
1111 AMD_CG_SUPPORT_BIF_MGCG |
1112 AMD_CG_SUPPORT_BIF_LS |
1113 AMD_CG_SUPPORT_HDP_MGCG |
1114 AMD_CG_SUPPORT_HDP_LS |
1115 AMD_CG_SUPPORT_ROM_MGCG |
1116 AMD_CG_SUPPORT_MC_MGCG |
1117 AMD_CG_SUPPORT_MC_LS |
1118 AMD_CG_SUPPORT_DRM_LS |
1119 AMD_CG_SUPPORT_UVD_MGCG |
1120 AMD_CG_SUPPORT_VCE_MGCG;*/
1121 adev->pg_flags = 0;
1122 adev->external_rev_id = adev->rev_id + 0x6E;
1123 break;
1034 case CHIP_CARRIZO: 1124 case CHIP_CARRIZO:
1035 adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG | 1125 adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG |
1036 AMD_CG_SUPPORT_GFX_MGCG | 1126 AMD_CG_SUPPORT_GFX_MGCG |
@@ -1422,6 +1512,7 @@ static int vi_common_set_clockgating_state(void *handle,
1422 case CHIP_POLARIS10: 1512 case CHIP_POLARIS10:
1423 case CHIP_POLARIS11: 1513 case CHIP_POLARIS11:
1424 case CHIP_POLARIS12: 1514 case CHIP_POLARIS12:
1515 case CHIP_VEGAM:
1425 vi_common_set_clockgating_state_by_smu(adev, state); 1516 vi_common_set_clockgating_state_by_smu(adev, state);
1426 default: 1517 default:
1427 break; 1518 break;
@@ -1551,9 +1642,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
1551 amdgpu_device_ip_block_add(adev, &vce_v3_0_ip_block); 1642 amdgpu_device_ip_block_add(adev, &vce_v3_0_ip_block);
1552 } 1643 }
1553 break; 1644 break;
1554 case CHIP_POLARIS11:
1555 case CHIP_POLARIS10: 1645 case CHIP_POLARIS10:
1646 case CHIP_POLARIS11:
1556 case CHIP_POLARIS12: 1647 case CHIP_POLARIS12:
1648 case CHIP_VEGAM:
1557 amdgpu_device_ip_block_add(adev, &vi_common_ip_block); 1649 amdgpu_device_ip_block_add(adev, &vi_common_ip_block);
1558 amdgpu_device_ip_block_add(adev, &gmc_v8_1_ip_block); 1650 amdgpu_device_ip_block_add(adev, &gmc_v8_1_ip_block);
1559 amdgpu_device_ip_block_add(adev, &tonga_ih_ip_block); 1651 amdgpu_device_ip_block_add(adev, &tonga_ih_ip_block);
diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile
index 0d0242240c47..ffd096fffc1c 100644
--- a/drivers/gpu/drm/amd/amdkfd/Makefile
+++ b/drivers/gpu/drm/amd/amdkfd/Makefile
@@ -30,12 +30,14 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \
30 kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ 30 kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \
31 kfd_process.o kfd_queue.o kfd_mqd_manager.o \ 31 kfd_process.o kfd_queue.o kfd_mqd_manager.o \
32 kfd_mqd_manager_cik.o kfd_mqd_manager_vi.o \ 32 kfd_mqd_manager_cik.o kfd_mqd_manager_vi.o \
33 kfd_mqd_manager_v9.o \
33 kfd_kernel_queue.o kfd_kernel_queue_cik.o \ 34 kfd_kernel_queue.o kfd_kernel_queue_cik.o \
34 kfd_kernel_queue_vi.o kfd_packet_manager.o \ 35 kfd_kernel_queue_vi.o kfd_kernel_queue_v9.o \
35 kfd_process_queue_manager.o kfd_device_queue_manager.o \ 36 kfd_packet_manager.o kfd_process_queue_manager.o \
36 kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \ 37 kfd_device_queue_manager.o kfd_device_queue_manager_cik.o \
38 kfd_device_queue_manager_vi.o kfd_device_queue_manager_v9.o \
37 kfd_interrupt.o kfd_events.o cik_event_interrupt.o \ 39 kfd_interrupt.o kfd_events.o cik_event_interrupt.o \
38 kfd_dbgdev.o kfd_dbgmgr.o kfd_crat.o 40 kfd_int_process_v9.o kfd_dbgdev.o kfd_dbgmgr.o kfd_crat.o
39 41
40ifneq ($(CONFIG_AMD_IOMMU_V2),) 42ifneq ($(CONFIG_AMD_IOMMU_V2),)
41amdkfd-y += kfd_iommu.o 43amdkfd-y += kfd_iommu.o
diff --git a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
index 3d5ccb3755d4..49df6c791cfc 100644
--- a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
+++ b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
@@ -27,18 +27,28 @@
27static bool cik_event_interrupt_isr(struct kfd_dev *dev, 27static bool cik_event_interrupt_isr(struct kfd_dev *dev,
28 const uint32_t *ih_ring_entry) 28 const uint32_t *ih_ring_entry)
29{ 29{
30 unsigned int pasid;
31 const struct cik_ih_ring_entry *ihre = 30 const struct cik_ih_ring_entry *ihre =
32 (const struct cik_ih_ring_entry *)ih_ring_entry; 31 (const struct cik_ih_ring_entry *)ih_ring_entry;
32 unsigned int vmid, pasid;
33
34 /* Only handle interrupts from KFD VMIDs */
35 vmid = (ihre->ring_id & 0x0000ff00) >> 8;
36 if (vmid < dev->vm_info.first_vmid_kfd ||
37 vmid > dev->vm_info.last_vmid_kfd)
38 return 0;
33 39
40 /* If there is no valid PASID, it's likely a firmware bug */
34 pasid = (ihre->ring_id & 0xffff0000) >> 16; 41 pasid = (ihre->ring_id & 0xffff0000) >> 16;
42 if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt"))
43 return 0;
35 44
36 /* Do not process in ISR, just request it to be forwarded to WQ. */ 45 /* Interrupt types we care about: various signals and faults.
37 return (pasid != 0) && 46 * They will be forwarded to a work queue (see below).
38 (ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE || 47 */
48 return ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE ||
39 ihre->source_id == CIK_INTSRC_SDMA_TRAP || 49 ihre->source_id == CIK_INTSRC_SDMA_TRAP ||
40 ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG || 50 ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG ||
41 ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE); 51 ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE;
42} 52}
43 53
44static void cik_event_interrupt_wq(struct kfd_dev *dev, 54static void cik_event_interrupt_wq(struct kfd_dev *dev,
diff --git a/drivers/gpu/drm/amd/amdkfd/cik_regs.h b/drivers/gpu/drm/amd/amdkfd/cik_regs.h
index 48769d12dd7b..37ce6dd65391 100644
--- a/drivers/gpu/drm/amd/amdkfd/cik_regs.h
+++ b/drivers/gpu/drm/amd/amdkfd/cik_regs.h
@@ -33,7 +33,8 @@
33#define APE1_MTYPE(x) ((x) << 7) 33#define APE1_MTYPE(x) ((x) << 7)
34 34
35/* valid for both DEFAULT_MTYPE and APE1_MTYPE */ 35/* valid for both DEFAULT_MTYPE and APE1_MTYPE */
36#define MTYPE_CACHED 0 36#define MTYPE_CACHED_NV 0
37#define MTYPE_CACHED 1
37#define MTYPE_NONCACHED 3 38#define MTYPE_NONCACHED 3
38 39
39#define DEFAULT_CP_HQD_PERSISTENT_STATE (0x33U << 8) 40#define DEFAULT_CP_HQD_PERSISTENT_STATE (0x33U << 8)
diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
new file mode 100644
index 000000000000..f68aef02fc1f
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
@@ -0,0 +1,560 @@
1/*
2 * Copyright 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23static const uint32_t cwsr_trap_gfx8_hex[] = {
24 0xbf820001, 0xbf820125,
25 0xb8f4f802, 0x89748674,
26 0xb8f5f803, 0x8675ff75,
27 0x00000400, 0xbf850011,
28 0xc00a1e37, 0x00000000,
29 0xbf8c007f, 0x87777978,
30 0xbf840002, 0xb974f802,
31 0xbe801d78, 0xb8f5f803,
32 0x8675ff75, 0x000001ff,
33 0xbf850002, 0x80708470,
34 0x82718071, 0x8671ff71,
35 0x0000ffff, 0xb974f802,
36 0xbe801f70, 0xb8f5f803,
37 0x8675ff75, 0x00000100,
38 0xbf840006, 0xbefa0080,
39 0xb97a0203, 0x8671ff71,
40 0x0000ffff, 0x80f08870,
41 0x82f18071, 0xbefa0080,
42 0xb97a0283, 0xbef60068,
43 0xbef70069, 0xb8fa1c07,
44 0x8e7a9c7a, 0x87717a71,
45 0xb8fa03c7, 0x8e7a9b7a,
46 0x87717a71, 0xb8faf807,
47 0x867aff7a, 0x00007fff,
48 0xb97af807, 0xbef2007e,
49 0xbef3007f, 0xbefe0180,
50 0xbf900004, 0x877a8474,
51 0xb97af802, 0xbf8e0002,
52 0xbf88fffe, 0xbef8007e,
53 0x8679ff7f, 0x0000ffff,
54 0x8779ff79, 0x00040000,
55 0xbefa0080, 0xbefb00ff,
56 0x00807fac, 0x867aff7f,
57 0x08000000, 0x8f7a837a,
58 0x877b7a7b, 0x867aff7f,
59 0x70000000, 0x8f7a817a,
60 0x877b7a7b, 0xbeef007c,
61 0xbeee0080, 0xb8ee2a05,
62 0x806e816e, 0x8e6e8a6e,
63 0xb8fa1605, 0x807a817a,
64 0x8e7a867a, 0x806e7a6e,
65 0xbefa0084, 0xbefa00ff,
66 0x01000000, 0xbefe007c,
67 0xbefc006e, 0xc0611bfc,
68 0x0000007c, 0x806e846e,
69 0xbefc007e, 0xbefe007c,
70 0xbefc006e, 0xc0611c3c,
71 0x0000007c, 0x806e846e,
72 0xbefc007e, 0xbefe007c,
73 0xbefc006e, 0xc0611c7c,
74 0x0000007c, 0x806e846e,
75 0xbefc007e, 0xbefe007c,
76 0xbefc006e, 0xc0611cbc,
77 0x0000007c, 0x806e846e,
78 0xbefc007e, 0xbefe007c,
79 0xbefc006e, 0xc0611cfc,
80 0x0000007c, 0x806e846e,
81 0xbefc007e, 0xbefe007c,
82 0xbefc006e, 0xc0611d3c,
83 0x0000007c, 0x806e846e,
84 0xbefc007e, 0xb8f5f803,
85 0xbefe007c, 0xbefc006e,
86 0xc0611d7c, 0x0000007c,
87 0x806e846e, 0xbefc007e,
88 0xbefe007c, 0xbefc006e,
89 0xc0611dbc, 0x0000007c,
90 0x806e846e, 0xbefc007e,
91 0xbefe007c, 0xbefc006e,
92 0xc0611dfc, 0x0000007c,
93 0x806e846e, 0xbefc007e,
94 0xb8eff801, 0xbefe007c,
95 0xbefc006e, 0xc0611bfc,
96 0x0000007c, 0x806e846e,
97 0xbefc007e, 0xbefe007c,
98 0xbefc006e, 0xc0611b3c,
99 0x0000007c, 0x806e846e,
100 0xbefc007e, 0xbefe007c,
101 0xbefc006e, 0xc0611b7c,
102 0x0000007c, 0x806e846e,
103 0xbefc007e, 0x867aff7f,
104 0x04000000, 0xbef30080,
105 0x8773737a, 0xb8ee2a05,
106 0x806e816e, 0x8e6e8a6e,
107 0xb8f51605, 0x80758175,
108 0x8e758475, 0x8e7a8275,
109 0xbefa00ff, 0x01000000,
110 0xbef60178, 0x80786e78,
111 0x82798079, 0xbefc0080,
112 0xbe802b00, 0xbe822b02,
113 0xbe842b04, 0xbe862b06,
114 0xbe882b08, 0xbe8a2b0a,
115 0xbe8c2b0c, 0xbe8e2b0e,
116 0xc06b003c, 0x00000000,
117 0xc06b013c, 0x00000010,
118 0xc06b023c, 0x00000020,
119 0xc06b033c, 0x00000030,
120 0x8078c078, 0x82798079,
121 0x807c907c, 0xbf0a757c,
122 0xbf85ffeb, 0xbef80176,
123 0xbeee0080, 0xbefe00c1,
124 0xbeff00c1, 0xbefa00ff,
125 0x01000000, 0xe0724000,
126 0x6e1e0000, 0xe0724100,
127 0x6e1e0100, 0xe0724200,
128 0x6e1e0200, 0xe0724300,
129 0x6e1e0300, 0xbefe00c1,
130 0xbeff00c1, 0xb8f54306,
131 0x8675c175, 0xbf84002c,
132 0xbf8a0000, 0x867aff73,
133 0x04000000, 0xbf840028,
134 0x8e758675, 0x8e758275,
135 0xbefa0075, 0xb8ee2a05,
136 0x806e816e, 0x8e6e8a6e,
137 0xb8fa1605, 0x807a817a,
138 0x8e7a867a, 0x806e7a6e,
139 0x806eff6e, 0x00000080,
140 0xbefa00ff, 0x01000000,
141 0xbefc0080, 0xd28c0002,
142 0x000100c1, 0xd28d0003,
143 0x000204c1, 0xd1060002,
144 0x00011103, 0x7e0602ff,
145 0x00000200, 0xbefc00ff,
146 0x00010000, 0xbe80007b,
147 0x867bff7b, 0xff7fffff,
148 0x877bff7b, 0x00058000,
149 0xd8ec0000, 0x00000002,
150 0xbf8c007f, 0xe0765000,
151 0x6e1e0002, 0x32040702,
152 0xd0c9006a, 0x0000eb02,
153 0xbf87fff7, 0xbefb0000,
154 0xbeee00ff, 0x00000400,
155 0xbefe00c1, 0xbeff00c1,
156 0xb8f52a05, 0x80758175,
157 0x8e758275, 0x8e7a8875,
158 0xbefa00ff, 0x01000000,
159 0xbefc0084, 0xbf0a757c,
160 0xbf840015, 0xbf11017c,
161 0x8075ff75, 0x00001000,
162 0x7e000300, 0x7e020301,
163 0x7e040302, 0x7e060303,
164 0xe0724000, 0x6e1e0000,
165 0xe0724100, 0x6e1e0100,
166 0xe0724200, 0x6e1e0200,
167 0xe0724300, 0x6e1e0300,
168 0x807c847c, 0x806eff6e,
169 0x00000400, 0xbf0a757c,
170 0xbf85ffef, 0xbf9c0000,
171 0xbf8200ca, 0xbef8007e,
172 0x8679ff7f, 0x0000ffff,
173 0x8779ff79, 0x00040000,
174 0xbefa0080, 0xbefb00ff,
175 0x00807fac, 0x8676ff7f,
176 0x08000000, 0x8f768376,
177 0x877b767b, 0x8676ff7f,
178 0x70000000, 0x8f768176,
179 0x877b767b, 0x8676ff7f,
180 0x04000000, 0xbf84001e,
181 0xbefe00c1, 0xbeff00c1,
182 0xb8f34306, 0x8673c173,
183 0xbf840019, 0x8e738673,
184 0x8e738273, 0xbefa0073,
185 0xb8f22a05, 0x80728172,
186 0x8e728a72, 0xb8f61605,
187 0x80768176, 0x8e768676,
188 0x80727672, 0x8072ff72,
189 0x00000080, 0xbefa00ff,
190 0x01000000, 0xbefc0080,
191 0xe0510000, 0x721e0000,
192 0xe0510100, 0x721e0000,
193 0x807cff7c, 0x00000200,
194 0x8072ff72, 0x00000200,
195 0xbf0a737c, 0xbf85fff6,
196 0xbef20080, 0xbefe00c1,
197 0xbeff00c1, 0xb8f32a05,
198 0x80738173, 0x8e738273,
199 0x8e7a8873, 0xbefa00ff,
200 0x01000000, 0xbef60072,
201 0x8072ff72, 0x00000400,
202 0xbefc0084, 0xbf11087c,
203 0x8073ff73, 0x00008000,
204 0xe0524000, 0x721e0000,
205 0xe0524100, 0x721e0100,
206 0xe0524200, 0x721e0200,
207 0xe0524300, 0x721e0300,
208 0xbf8c0f70, 0x7e000300,
209 0x7e020301, 0x7e040302,
210 0x7e060303, 0x807c847c,
211 0x8072ff72, 0x00000400,
212 0xbf0a737c, 0xbf85ffee,
213 0xbf9c0000, 0xe0524000,
214 0x761e0000, 0xe0524100,
215 0x761e0100, 0xe0524200,
216 0x761e0200, 0xe0524300,
217 0x761e0300, 0xb8f22a05,
218 0x80728172, 0x8e728a72,
219 0xb8f61605, 0x80768176,
220 0x8e768676, 0x80727672,
221 0x80f2c072, 0xb8f31605,
222 0x80738173, 0x8e738473,
223 0x8e7a8273, 0xbefa00ff,
224 0x01000000, 0xbefc0073,
225 0xc031003c, 0x00000072,
226 0x80f2c072, 0xbf8c007f,
227 0x80fc907c, 0xbe802d00,
228 0xbe822d02, 0xbe842d04,
229 0xbe862d06, 0xbe882d08,
230 0xbe8a2d0a, 0xbe8c2d0c,
231 0xbe8e2d0e, 0xbf06807c,
232 0xbf84fff1, 0xb8f22a05,
233 0x80728172, 0x8e728a72,
234 0xb8f61605, 0x80768176,
235 0x8e768676, 0x80727672,
236 0xbefa0084, 0xbefa00ff,
237 0x01000000, 0xc0211cfc,
238 0x00000072, 0x80728472,
239 0xc0211c3c, 0x00000072,
240 0x80728472, 0xc0211c7c,
241 0x00000072, 0x80728472,
242 0xc0211bbc, 0x00000072,
243 0x80728472, 0xc0211bfc,
244 0x00000072, 0x80728472,
245 0xc0211d3c, 0x00000072,
246 0x80728472, 0xc0211d7c,
247 0x00000072, 0x80728472,
248 0xc0211a3c, 0x00000072,
249 0x80728472, 0xc0211a7c,
250 0x00000072, 0x80728472,
251 0xc0211dfc, 0x00000072,
252 0x80728472, 0xc0211b3c,
253 0x00000072, 0x80728472,
254 0xc0211b7c, 0x00000072,
255 0x80728472, 0xbf8c007f,
256 0xbefc0073, 0xbefe006e,
257 0xbeff006f, 0x867375ff,
258 0x000003ff, 0xb9734803,
259 0x867375ff, 0xfffff800,
260 0x8f738b73, 0xb973a2c3,
261 0xb977f801, 0x8673ff71,
262 0xf0000000, 0x8f739c73,
263 0x8e739073, 0xbef60080,
264 0x87767376, 0x8673ff71,
265 0x08000000, 0x8f739b73,
266 0x8e738f73, 0x87767376,
267 0x8673ff74, 0x00800000,
268 0x8f739773, 0xb976f807,
269 0x8671ff71, 0x0000ffff,
270 0x86fe7e7e, 0x86ea6a6a,
271 0xb974f802, 0xbf8a0000,
272 0x95807370, 0xbf810000,
273};
274
275
276static const uint32_t cwsr_trap_gfx9_hex[] = {
277 0xbf820001, 0xbf82015a,
278 0xb8f8f802, 0x89788678,
279 0xb8f1f803, 0x866eff71,
280 0x00000400, 0xbf850034,
281 0x866eff71, 0x00000800,
282 0xbf850003, 0x866eff71,
283 0x00000100, 0xbf840008,
284 0x866eff78, 0x00002000,
285 0xbf840001, 0xbf810000,
286 0x8778ff78, 0x00002000,
287 0x80ec886c, 0x82ed806d,
288 0xb8eef807, 0x866fff6e,
289 0x001f8000, 0x8e6f8b6f,
290 0x8977ff77, 0xfc000000,
291 0x87776f77, 0x896eff6e,
292 0x001f8000, 0xb96ef807,
293 0xb8f0f812, 0xb8f1f813,
294 0x8ef08870, 0xc0071bb8,
295 0x00000000, 0xbf8cc07f,
296 0xc0071c38, 0x00000008,
297 0xbf8cc07f, 0x86ee6e6e,
298 0xbf840001, 0xbe801d6e,
299 0xb8f1f803, 0x8671ff71,
300 0x000001ff, 0xbf850002,
301 0x806c846c, 0x826d806d,
302 0x866dff6d, 0x0000ffff,
303 0x8f6e8b77, 0x866eff6e,
304 0x001f8000, 0xb96ef807,
305 0x86fe7e7e, 0x86ea6a6a,
306 0xb978f802, 0xbe801f6c,
307 0x866dff6d, 0x0000ffff,
308 0xbef00080, 0xb9700283,
309 0xb8f02407, 0x8e709c70,
310 0x876d706d, 0xb8f003c7,
311 0x8e709b70, 0x876d706d,
312 0xb8f0f807, 0x8670ff70,
313 0x00007fff, 0xb970f807,
314 0xbeee007e, 0xbeef007f,
315 0xbefe0180, 0xbf900004,
316 0x87708478, 0xb970f802,
317 0xbf8e0002, 0xbf88fffe,
318 0xb8f02a05, 0x80708170,
319 0x8e708a70, 0xb8f11605,
320 0x80718171, 0x8e718671,
321 0x80707170, 0x80707e70,
322 0x8271807f, 0x8671ff71,
323 0x0000ffff, 0xc0471cb8,
324 0x00000040, 0xbf8cc07f,
325 0xc04b1d38, 0x00000048,
326 0xbf8cc07f, 0xc0431e78,
327 0x00000058, 0xbf8cc07f,
328 0xc0471eb8, 0x0000005c,
329 0xbf8cc07f, 0xbef4007e,
330 0x8675ff7f, 0x0000ffff,
331 0x8775ff75, 0x00040000,
332 0xbef60080, 0xbef700ff,
333 0x00807fac, 0x8670ff7f,
334 0x08000000, 0x8f708370,
335 0x87777077, 0x8670ff7f,
336 0x70000000, 0x8f708170,
337 0x87777077, 0xbefb007c,
338 0xbefa0080, 0xb8fa2a05,
339 0x807a817a, 0x8e7a8a7a,
340 0xb8f01605, 0x80708170,
341 0x8e708670, 0x807a707a,
342 0xbef60084, 0xbef600ff,
343 0x01000000, 0xbefe007c,
344 0xbefc007a, 0xc0611efa,
345 0x0000007c, 0xbf8cc07f,
346 0x807a847a, 0xbefc007e,
347 0xbefe007c, 0xbefc007a,
348 0xc0611b3a, 0x0000007c,
349 0xbf8cc07f, 0x807a847a,
350 0xbefc007e, 0xbefe007c,
351 0xbefc007a, 0xc0611b7a,
352 0x0000007c, 0xbf8cc07f,
353 0x807a847a, 0xbefc007e,
354 0xbefe007c, 0xbefc007a,
355 0xc0611bba, 0x0000007c,
356 0xbf8cc07f, 0x807a847a,
357 0xbefc007e, 0xbefe007c,
358 0xbefc007a, 0xc0611bfa,
359 0x0000007c, 0xbf8cc07f,
360 0x807a847a, 0xbefc007e,
361 0xbefe007c, 0xbefc007a,
362 0xc0611e3a, 0x0000007c,
363 0xbf8cc07f, 0x807a847a,
364 0xbefc007e, 0xb8f1f803,
365 0xbefe007c, 0xbefc007a,
366 0xc0611c7a, 0x0000007c,
367 0xbf8cc07f, 0x807a847a,
368 0xbefc007e, 0xbefe007c,
369 0xbefc007a, 0xc0611a3a,
370 0x0000007c, 0xbf8cc07f,
371 0x807a847a, 0xbefc007e,
372 0xbefe007c, 0xbefc007a,
373 0xc0611a7a, 0x0000007c,
374 0xbf8cc07f, 0x807a847a,
375 0xbefc007e, 0xb8fbf801,
376 0xbefe007c, 0xbefc007a,
377 0xc0611efa, 0x0000007c,
378 0xbf8cc07f, 0x807a847a,
379 0xbefc007e, 0x8670ff7f,
380 0x04000000, 0xbeef0080,
381 0x876f6f70, 0xb8fa2a05,
382 0x807a817a, 0x8e7a8a7a,
383 0xb8f11605, 0x80718171,
384 0x8e718471, 0x8e768271,
385 0xbef600ff, 0x01000000,
386 0xbef20174, 0x80747a74,
387 0x82758075, 0xbefc0080,
388 0xbf800000, 0xbe802b00,
389 0xbe822b02, 0xbe842b04,
390 0xbe862b06, 0xbe882b08,
391 0xbe8a2b0a, 0xbe8c2b0c,
392 0xbe8e2b0e, 0xc06b003a,
393 0x00000000, 0xbf8cc07f,
394 0xc06b013a, 0x00000010,
395 0xbf8cc07f, 0xc06b023a,
396 0x00000020, 0xbf8cc07f,
397 0xc06b033a, 0x00000030,
398 0xbf8cc07f, 0x8074c074,
399 0x82758075, 0x807c907c,
400 0xbf0a717c, 0xbf85ffe7,
401 0xbef40172, 0xbefa0080,
402 0xbefe00c1, 0xbeff00c1,
403 0xbee80080, 0xbee90080,
404 0xbef600ff, 0x01000000,
405 0xe0724000, 0x7a1d0000,
406 0xe0724100, 0x7a1d0100,
407 0xe0724200, 0x7a1d0200,
408 0xe0724300, 0x7a1d0300,
409 0xbefe00c1, 0xbeff00c1,
410 0xb8f14306, 0x8671c171,
411 0xbf84002c, 0xbf8a0000,
412 0x8670ff6f, 0x04000000,
413 0xbf840028, 0x8e718671,
414 0x8e718271, 0xbef60071,
415 0xb8fa2a05, 0x807a817a,
416 0x8e7a8a7a, 0xb8f01605,
417 0x80708170, 0x8e708670,
418 0x807a707a, 0x807aff7a,
419 0x00000080, 0xbef600ff,
420 0x01000000, 0xbefc0080,
421 0xd28c0002, 0x000100c1,
422 0xd28d0003, 0x000204c1,
423 0xd1060002, 0x00011103,
424 0x7e0602ff, 0x00000200,
425 0xbefc00ff, 0x00010000,
426 0xbe800077, 0x8677ff77,
427 0xff7fffff, 0x8777ff77,
428 0x00058000, 0xd8ec0000,
429 0x00000002, 0xbf8cc07f,
430 0xe0765000, 0x7a1d0002,
431 0x68040702, 0xd0c9006a,
432 0x0000e302, 0xbf87fff7,
433 0xbef70000, 0xbefa00ff,
434 0x00000400, 0xbefe00c1,
435 0xbeff00c1, 0xb8f12a05,
436 0x80718171, 0x8e718271,
437 0x8e768871, 0xbef600ff,
438 0x01000000, 0xbefc0084,
439 0xbf0a717c, 0xbf840015,
440 0xbf11017c, 0x8071ff71,
441 0x00001000, 0x7e000300,
442 0x7e020301, 0x7e040302,
443 0x7e060303, 0xe0724000,
444 0x7a1d0000, 0xe0724100,
445 0x7a1d0100, 0xe0724200,
446 0x7a1d0200, 0xe0724300,
447 0x7a1d0300, 0x807c847c,
448 0x807aff7a, 0x00000400,
449 0xbf0a717c, 0xbf85ffef,
450 0xbf9c0000, 0xbf8200d9,
451 0xbef4007e, 0x8675ff7f,
452 0x0000ffff, 0x8775ff75,
453 0x00040000, 0xbef60080,
454 0xbef700ff, 0x00807fac,
455 0x866eff7f, 0x08000000,
456 0x8f6e836e, 0x87776e77,
457 0x866eff7f, 0x70000000,
458 0x8f6e816e, 0x87776e77,
459 0x866eff7f, 0x04000000,
460 0xbf84001e, 0xbefe00c1,
461 0xbeff00c1, 0xb8ef4306,
462 0x866fc16f, 0xbf840019,
463 0x8e6f866f, 0x8e6f826f,
464 0xbef6006f, 0xb8f82a05,
465 0x80788178, 0x8e788a78,
466 0xb8ee1605, 0x806e816e,
467 0x8e6e866e, 0x80786e78,
468 0x8078ff78, 0x00000080,
469 0xbef600ff, 0x01000000,
470 0xbefc0080, 0xe0510000,
471 0x781d0000, 0xe0510100,
472 0x781d0000, 0x807cff7c,
473 0x00000200, 0x8078ff78,
474 0x00000200, 0xbf0a6f7c,
475 0xbf85fff6, 0xbef80080,
476 0xbefe00c1, 0xbeff00c1,
477 0xb8ef2a05, 0x806f816f,
478 0x8e6f826f, 0x8e76886f,
479 0xbef600ff, 0x01000000,
480 0xbeee0078, 0x8078ff78,
481 0x00000400, 0xbefc0084,
482 0xbf11087c, 0x806fff6f,
483 0x00008000, 0xe0524000,
484 0x781d0000, 0xe0524100,
485 0x781d0100, 0xe0524200,
486 0x781d0200, 0xe0524300,
487 0x781d0300, 0xbf8c0f70,
488 0x7e000300, 0x7e020301,
489 0x7e040302, 0x7e060303,
490 0x807c847c, 0x8078ff78,
491 0x00000400, 0xbf0a6f7c,
492 0xbf85ffee, 0xbf9c0000,
493 0xe0524000, 0x6e1d0000,
494 0xe0524100, 0x6e1d0100,
495 0xe0524200, 0x6e1d0200,
496 0xe0524300, 0x6e1d0300,
497 0xb8f82a05, 0x80788178,
498 0x8e788a78, 0xb8ee1605,
499 0x806e816e, 0x8e6e866e,
500 0x80786e78, 0x80f8c078,
501 0xb8ef1605, 0x806f816f,
502 0x8e6f846f, 0x8e76826f,
503 0xbef600ff, 0x01000000,
504 0xbefc006f, 0xc031003a,
505 0x00000078, 0x80f8c078,
506 0xbf8cc07f, 0x80fc907c,
507 0xbf800000, 0xbe802d00,
508 0xbe822d02, 0xbe842d04,
509 0xbe862d06, 0xbe882d08,
510 0xbe8a2d0a, 0xbe8c2d0c,
511 0xbe8e2d0e, 0xbf06807c,
512 0xbf84fff0, 0xb8f82a05,
513 0x80788178, 0x8e788a78,
514 0xb8ee1605, 0x806e816e,
515 0x8e6e866e, 0x80786e78,
516 0xbef60084, 0xbef600ff,
517 0x01000000, 0xc0211bfa,
518 0x00000078, 0x80788478,
519 0xc0211b3a, 0x00000078,
520 0x80788478, 0xc0211b7a,
521 0x00000078, 0x80788478,
522 0xc0211eba, 0x00000078,
523 0x80788478, 0xc0211efa,
524 0x00000078, 0x80788478,
525 0xc0211c3a, 0x00000078,
526 0x80788478, 0xc0211c7a,
527 0x00000078, 0x80788478,
528 0xc0211a3a, 0x00000078,
529 0x80788478, 0xc0211a7a,
530 0x00000078, 0x80788478,
531 0xc0211cfa, 0x00000078,
532 0x80788478, 0xbf8cc07f,
533 0xbefc006f, 0xbefe007a,
534 0xbeff007b, 0x866f71ff,
535 0x000003ff, 0xb96f4803,
536 0x866f71ff, 0xfffff800,
537 0x8f6f8b6f, 0xb96fa2c3,
538 0xb973f801, 0xb8ee2a05,
539 0x806e816e, 0x8e6e8a6e,
540 0xb8ef1605, 0x806f816f,
541 0x8e6f866f, 0x806e6f6e,
542 0x806e746e, 0x826f8075,
543 0x866fff6f, 0x0000ffff,
544 0xc0071cb7, 0x00000040,
545 0xc00b1d37, 0x00000048,
546 0xc0031e77, 0x00000058,
547 0xc0071eb7, 0x0000005c,
548 0xbf8cc07f, 0x866fff6d,
549 0xf0000000, 0x8f6f9c6f,
550 0x8e6f906f, 0xbeee0080,
551 0x876e6f6e, 0x866fff6d,
552 0x08000000, 0x8f6f9b6f,
553 0x8e6f8f6f, 0x876e6f6e,
554 0x866fff70, 0x00800000,
555 0x8f6f976f, 0xb96ef807,
556 0x866dff6d, 0x0000ffff,
557 0x86fe7e7e, 0x86ea6a6a,
558 0xb970f802, 0xbf8a0000,
559 0x95806f6c, 0xbf810000,
560};
diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx8.asm b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx8.asm
index 997a383dcb8b..a2a04bb64096 100644
--- a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx8.asm
+++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx8.asm
@@ -20,9 +20,12 @@
20 * OTHER DEALINGS IN THE SOFTWARE. 20 * OTHER DEALINGS IN THE SOFTWARE.
21 */ 21 */
22 22
23#if 0 23/* To compile this assembly code:
24HW (VI) source code for CWSR trap handler 24 * PROJECT=vi ./sp3 cwsr_trap_handler_gfx8.asm -hex tmp.hex
25#Version 18 + multiple trap handler 25 */
26
27/* HW (VI) source code for CWSR trap handler */
28/* Version 18 + multiple trap handler */
26 29
27// this performance-optimal version was originally from Seven Xu at SRDC 30// this performance-optimal version was originally from Seven Xu at SRDC
28 31
@@ -98,6 +101,7 @@ var SWIZZLE_EN = 0 //whether we use swi
98/**************************************************************************/ 101/**************************************************************************/
99var SQ_WAVE_STATUS_INST_ATC_SHIFT = 23 102var SQ_WAVE_STATUS_INST_ATC_SHIFT = 23
100var SQ_WAVE_STATUS_INST_ATC_MASK = 0x00800000 103var SQ_WAVE_STATUS_INST_ATC_MASK = 0x00800000
104var SQ_WAVE_STATUS_SPI_PRIO_SHIFT = 1
101var SQ_WAVE_STATUS_SPI_PRIO_MASK = 0x00000006 105var SQ_WAVE_STATUS_SPI_PRIO_MASK = 0x00000006
102 106
103var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT = 12 107var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT = 12
@@ -149,7 +153,7 @@ var s_save_spi_init_lo = exec_lo
149var s_save_spi_init_hi = exec_hi 153var s_save_spi_init_hi = exec_hi
150 154
151 //tba_lo and tba_hi need to be saved/restored 155 //tba_lo and tba_hi need to be saved/restored
152var s_save_pc_lo = ttmp0 //{TTMP1, TTMP0} = {3??h0,pc_rewind[3:0], HT[0],trapID[7:0], PC[47:0]} 156var s_save_pc_lo = ttmp0 //{TTMP1, TTMP0} = {3'h0,pc_rewind[3:0], HT[0],trapID[7:0], PC[47:0]}
153var s_save_pc_hi = ttmp1 157var s_save_pc_hi = ttmp1
154var s_save_exec_lo = ttmp2 158var s_save_exec_lo = ttmp2
155var s_save_exec_hi = ttmp3 159var s_save_exec_hi = ttmp3
@@ -319,6 +323,10 @@ end
319 s_sendmsg sendmsg(MSG_SAVEWAVE) //send SPI a message and wait for SPI's write to EXEC 323 s_sendmsg sendmsg(MSG_SAVEWAVE) //send SPI a message and wait for SPI's write to EXEC
320 end 324 end
321 325
326 // Set SPI_PRIO=2 to avoid starving instruction fetch in the waves we're waiting for.
327 s_or_b32 s_save_tmp, s_save_status, (2 << SQ_WAVE_STATUS_SPI_PRIO_SHIFT)
328 s_setreg_b32 hwreg(HW_REG_STATUS), s_save_tmp
329
322 L_SLEEP: 330 L_SLEEP:
323 s_sleep 0x2 // sleep 1 (64clk) is not enough for 8 waves per SIMD, which will cause SQ hang, since the 7,8th wave could not get arbit to exec inst, while other waves are stuck into the sleep-loop and waiting for wrexec!=0 331 s_sleep 0x2 // sleep 1 (64clk) is not enough for 8 waves per SIMD, which will cause SQ hang, since the 7,8th wave could not get arbit to exec inst, while other waves are stuck into the sleep-loop and waiting for wrexec!=0
324 332
@@ -1007,8 +1015,6 @@ end
1007 1015
1008 s_waitcnt lgkmcnt(0) //from now on, it is safe to restore STATUS and IB_STS 1016 s_waitcnt lgkmcnt(0) //from now on, it is safe to restore STATUS and IB_STS
1009 1017
1010 s_and_b32 s_restore_pc_hi, s_restore_pc_hi, 0x0000ffff //pc[47:32] //Do it here in order not to affect STATUS
1011
1012 //for normal save & restore, the saved PC points to the next inst to execute, no adjustment needs to be made, otherwise: 1018 //for normal save & restore, the saved PC points to the next inst to execute, no adjustment needs to be made, otherwise:
1013 if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_RESTORE_NORMAL)) 1019 if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_RESTORE_NORMAL))
1014 s_add_u32 s_restore_pc_lo, s_restore_pc_lo, 8 //pc[31:0]+8 //two back-to-back s_trap are used (first for save and second for restore) 1020 s_add_u32 s_restore_pc_lo, s_restore_pc_lo, 8 //pc[31:0]+8 //two back-to-back s_trap are used (first for save and second for restore)
@@ -1044,6 +1050,7 @@ end
1044 s_lshr_b32 s_restore_m0, s_restore_m0, SQ_WAVE_STATUS_INST_ATC_SHIFT 1050 s_lshr_b32 s_restore_m0, s_restore_m0, SQ_WAVE_STATUS_INST_ATC_SHIFT
1045 s_setreg_b32 hwreg(HW_REG_IB_STS), s_restore_tmp 1051 s_setreg_b32 hwreg(HW_REG_IB_STS), s_restore_tmp
1046 1052
1053 s_and_b32 s_restore_pc_hi, s_restore_pc_hi, 0x0000ffff //pc[47:32] //Do it here in order not to affect STATUS
1047 s_and_b64 exec, exec, exec // Restore STATUS.EXECZ, not writable by s_setreg_b32 1054 s_and_b64 exec, exec, exec // Restore STATUS.EXECZ, not writable by s_setreg_b32
1048 s_and_b64 vcc, vcc, vcc // Restore STATUS.VCCZ, not writable by s_setreg_b32 1055 s_and_b64 vcc, vcc, vcc // Restore STATUS.VCCZ, not writable by s_setreg_b32
1049 s_setreg_b32 hwreg(HW_REG_STATUS), s_restore_status // SCC is included, which is changed by previous salu 1056 s_setreg_b32 hwreg(HW_REG_STATUS), s_restore_status // SCC is included, which is changed by previous salu
@@ -1127,258 +1134,3 @@ end
1127function get_hwreg_size_bytes 1134function get_hwreg_size_bytes
1128 return 128 //HWREG size 128 bytes 1135 return 128 //HWREG size 128 bytes
1129end 1136end
1130
1131
1132#endif
1133
1134static const uint32_t cwsr_trap_gfx8_hex[] = {
1135 0xbf820001, 0xbf820123,
1136 0xb8f4f802, 0x89748674,
1137 0xb8f5f803, 0x8675ff75,
1138 0x00000400, 0xbf850011,
1139 0xc00a1e37, 0x00000000,
1140 0xbf8c007f, 0x87777978,
1141 0xbf840002, 0xb974f802,
1142 0xbe801d78, 0xb8f5f803,
1143 0x8675ff75, 0x000001ff,
1144 0xbf850002, 0x80708470,
1145 0x82718071, 0x8671ff71,
1146 0x0000ffff, 0xb974f802,
1147 0xbe801f70, 0xb8f5f803,
1148 0x8675ff75, 0x00000100,
1149 0xbf840006, 0xbefa0080,
1150 0xb97a0203, 0x8671ff71,
1151 0x0000ffff, 0x80f08870,
1152 0x82f18071, 0xbefa0080,
1153 0xb97a0283, 0xbef60068,
1154 0xbef70069, 0xb8fa1c07,
1155 0x8e7a9c7a, 0x87717a71,
1156 0xb8fa03c7, 0x8e7a9b7a,
1157 0x87717a71, 0xb8faf807,
1158 0x867aff7a, 0x00007fff,
1159 0xb97af807, 0xbef2007e,
1160 0xbef3007f, 0xbefe0180,
1161 0xbf900004, 0xbf8e0002,
1162 0xbf88fffe, 0xbef8007e,
1163 0x8679ff7f, 0x0000ffff,
1164 0x8779ff79, 0x00040000,
1165 0xbefa0080, 0xbefb00ff,
1166 0x00807fac, 0x867aff7f,
1167 0x08000000, 0x8f7a837a,
1168 0x877b7a7b, 0x867aff7f,
1169 0x70000000, 0x8f7a817a,
1170 0x877b7a7b, 0xbeef007c,
1171 0xbeee0080, 0xb8ee2a05,
1172 0x806e816e, 0x8e6e8a6e,
1173 0xb8fa1605, 0x807a817a,
1174 0x8e7a867a, 0x806e7a6e,
1175 0xbefa0084, 0xbefa00ff,
1176 0x01000000, 0xbefe007c,
1177 0xbefc006e, 0xc0611bfc,
1178 0x0000007c, 0x806e846e,
1179 0xbefc007e, 0xbefe007c,
1180 0xbefc006e, 0xc0611c3c,
1181 0x0000007c, 0x806e846e,
1182 0xbefc007e, 0xbefe007c,
1183 0xbefc006e, 0xc0611c7c,
1184 0x0000007c, 0x806e846e,
1185 0xbefc007e, 0xbefe007c,
1186 0xbefc006e, 0xc0611cbc,
1187 0x0000007c, 0x806e846e,
1188 0xbefc007e, 0xbefe007c,
1189 0xbefc006e, 0xc0611cfc,
1190 0x0000007c, 0x806e846e,
1191 0xbefc007e, 0xbefe007c,
1192 0xbefc006e, 0xc0611d3c,
1193 0x0000007c, 0x806e846e,
1194 0xbefc007e, 0xb8f5f803,
1195 0xbefe007c, 0xbefc006e,
1196 0xc0611d7c, 0x0000007c,
1197 0x806e846e, 0xbefc007e,
1198 0xbefe007c, 0xbefc006e,
1199 0xc0611dbc, 0x0000007c,
1200 0x806e846e, 0xbefc007e,
1201 0xbefe007c, 0xbefc006e,
1202 0xc0611dfc, 0x0000007c,
1203 0x806e846e, 0xbefc007e,
1204 0xb8eff801, 0xbefe007c,
1205 0xbefc006e, 0xc0611bfc,
1206 0x0000007c, 0x806e846e,
1207 0xbefc007e, 0xbefe007c,
1208 0xbefc006e, 0xc0611b3c,
1209 0x0000007c, 0x806e846e,
1210 0xbefc007e, 0xbefe007c,
1211 0xbefc006e, 0xc0611b7c,
1212 0x0000007c, 0x806e846e,
1213 0xbefc007e, 0x867aff7f,
1214 0x04000000, 0xbef30080,
1215 0x8773737a, 0xb8ee2a05,
1216 0x806e816e, 0x8e6e8a6e,
1217 0xb8f51605, 0x80758175,
1218 0x8e758475, 0x8e7a8275,
1219 0xbefa00ff, 0x01000000,
1220 0xbef60178, 0x80786e78,
1221 0x82798079, 0xbefc0080,
1222 0xbe802b00, 0xbe822b02,
1223 0xbe842b04, 0xbe862b06,
1224 0xbe882b08, 0xbe8a2b0a,
1225 0xbe8c2b0c, 0xbe8e2b0e,
1226 0xc06b003c, 0x00000000,
1227 0xc06b013c, 0x00000010,
1228 0xc06b023c, 0x00000020,
1229 0xc06b033c, 0x00000030,
1230 0x8078c078, 0x82798079,
1231 0x807c907c, 0xbf0a757c,
1232 0xbf85ffeb, 0xbef80176,
1233 0xbeee0080, 0xbefe00c1,
1234 0xbeff00c1, 0xbefa00ff,
1235 0x01000000, 0xe0724000,
1236 0x6e1e0000, 0xe0724100,
1237 0x6e1e0100, 0xe0724200,
1238 0x6e1e0200, 0xe0724300,
1239 0x6e1e0300, 0xbefe00c1,
1240 0xbeff00c1, 0xb8f54306,
1241 0x8675c175, 0xbf84002c,
1242 0xbf8a0000, 0x867aff73,
1243 0x04000000, 0xbf840028,
1244 0x8e758675, 0x8e758275,
1245 0xbefa0075, 0xb8ee2a05,
1246 0x806e816e, 0x8e6e8a6e,
1247 0xb8fa1605, 0x807a817a,
1248 0x8e7a867a, 0x806e7a6e,
1249 0x806eff6e, 0x00000080,
1250 0xbefa00ff, 0x01000000,
1251 0xbefc0080, 0xd28c0002,
1252 0x000100c1, 0xd28d0003,
1253 0x000204c1, 0xd1060002,
1254 0x00011103, 0x7e0602ff,
1255 0x00000200, 0xbefc00ff,
1256 0x00010000, 0xbe80007b,
1257 0x867bff7b, 0xff7fffff,
1258 0x877bff7b, 0x00058000,
1259 0xd8ec0000, 0x00000002,
1260 0xbf8c007f, 0xe0765000,
1261 0x6e1e0002, 0x32040702,
1262 0xd0c9006a, 0x0000eb02,
1263 0xbf87fff7, 0xbefb0000,
1264 0xbeee00ff, 0x00000400,
1265 0xbefe00c1, 0xbeff00c1,
1266 0xb8f52a05, 0x80758175,
1267 0x8e758275, 0x8e7a8875,
1268 0xbefa00ff, 0x01000000,
1269 0xbefc0084, 0xbf0a757c,
1270 0xbf840015, 0xbf11017c,
1271 0x8075ff75, 0x00001000,
1272 0x7e000300, 0x7e020301,
1273 0x7e040302, 0x7e060303,
1274 0xe0724000, 0x6e1e0000,
1275 0xe0724100, 0x6e1e0100,
1276 0xe0724200, 0x6e1e0200,
1277 0xe0724300, 0x6e1e0300,
1278 0x807c847c, 0x806eff6e,
1279 0x00000400, 0xbf0a757c,
1280 0xbf85ffef, 0xbf9c0000,
1281 0xbf8200ca, 0xbef8007e,
1282 0x8679ff7f, 0x0000ffff,
1283 0x8779ff79, 0x00040000,
1284 0xbefa0080, 0xbefb00ff,
1285 0x00807fac, 0x8676ff7f,
1286 0x08000000, 0x8f768376,
1287 0x877b767b, 0x8676ff7f,
1288 0x70000000, 0x8f768176,
1289 0x877b767b, 0x8676ff7f,
1290 0x04000000, 0xbf84001e,
1291 0xbefe00c1, 0xbeff00c1,
1292 0xb8f34306, 0x8673c173,
1293 0xbf840019, 0x8e738673,
1294 0x8e738273, 0xbefa0073,
1295 0xb8f22a05, 0x80728172,
1296 0x8e728a72, 0xb8f61605,
1297 0x80768176, 0x8e768676,
1298 0x80727672, 0x8072ff72,
1299 0x00000080, 0xbefa00ff,
1300 0x01000000, 0xbefc0080,
1301 0xe0510000, 0x721e0000,
1302 0xe0510100, 0x721e0000,
1303 0x807cff7c, 0x00000200,
1304 0x8072ff72, 0x00000200,
1305 0xbf0a737c, 0xbf85fff6,
1306 0xbef20080, 0xbefe00c1,
1307 0xbeff00c1, 0xb8f32a05,
1308 0x80738173, 0x8e738273,
1309 0x8e7a8873, 0xbefa00ff,
1310 0x01000000, 0xbef60072,
1311 0x8072ff72, 0x00000400,
1312 0xbefc0084, 0xbf11087c,
1313 0x8073ff73, 0x00008000,
1314 0xe0524000, 0x721e0000,
1315 0xe0524100, 0x721e0100,
1316 0xe0524200, 0x721e0200,
1317 0xe0524300, 0x721e0300,
1318 0xbf8c0f70, 0x7e000300,
1319 0x7e020301, 0x7e040302,
1320 0x7e060303, 0x807c847c,
1321 0x8072ff72, 0x00000400,
1322 0xbf0a737c, 0xbf85ffee,
1323 0xbf9c0000, 0xe0524000,
1324 0x761e0000, 0xe0524100,
1325 0x761e0100, 0xe0524200,
1326 0x761e0200, 0xe0524300,
1327 0x761e0300, 0xb8f22a05,
1328 0x80728172, 0x8e728a72,
1329 0xb8f61605, 0x80768176,
1330 0x8e768676, 0x80727672,
1331 0x80f2c072, 0xb8f31605,
1332 0x80738173, 0x8e738473,
1333 0x8e7a8273, 0xbefa00ff,
1334 0x01000000, 0xbefc0073,
1335 0xc031003c, 0x00000072,
1336 0x80f2c072, 0xbf8c007f,
1337 0x80fc907c, 0xbe802d00,
1338 0xbe822d02, 0xbe842d04,
1339 0xbe862d06, 0xbe882d08,
1340 0xbe8a2d0a, 0xbe8c2d0c,
1341 0xbe8e2d0e, 0xbf06807c,
1342 0xbf84fff1, 0xb8f22a05,
1343 0x80728172, 0x8e728a72,
1344 0xb8f61605, 0x80768176,
1345 0x8e768676, 0x80727672,
1346 0xbefa0084, 0xbefa00ff,
1347 0x01000000, 0xc0211cfc,
1348 0x00000072, 0x80728472,
1349 0xc0211c3c, 0x00000072,
1350 0x80728472, 0xc0211c7c,
1351 0x00000072, 0x80728472,
1352 0xc0211bbc, 0x00000072,
1353 0x80728472, 0xc0211bfc,
1354 0x00000072, 0x80728472,
1355 0xc0211d3c, 0x00000072,
1356 0x80728472, 0xc0211d7c,
1357 0x00000072, 0x80728472,
1358 0xc0211a3c, 0x00000072,
1359 0x80728472, 0xc0211a7c,
1360 0x00000072, 0x80728472,
1361 0xc0211dfc, 0x00000072,
1362 0x80728472, 0xc0211b3c,
1363 0x00000072, 0x80728472,
1364 0xc0211b7c, 0x00000072,
1365 0x80728472, 0xbf8c007f,
1366 0x8671ff71, 0x0000ffff,
1367 0xbefc0073, 0xbefe006e,
1368 0xbeff006f, 0x867375ff,
1369 0x000003ff, 0xb9734803,
1370 0x867375ff, 0xfffff800,
1371 0x8f738b73, 0xb973a2c3,
1372 0xb977f801, 0x8673ff71,
1373 0xf0000000, 0x8f739c73,
1374 0x8e739073, 0xbef60080,
1375 0x87767376, 0x8673ff71,
1376 0x08000000, 0x8f739b73,
1377 0x8e738f73, 0x87767376,
1378 0x8673ff74, 0x00800000,
1379 0x8f739773, 0xb976f807,
1380 0x86fe7e7e, 0x86ea6a6a,
1381 0xb974f802, 0xbf8a0000,
1382 0x95807370, 0xbf810000,
1383};
1384
diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx9.asm b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx9.asm
new file mode 100644
index 000000000000..998be96be736
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx9.asm
@@ -0,0 +1,1214 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23/* To compile this assembly code:
24 * PROJECT=greenland ./sp3 cwsr_trap_handler_gfx9.asm -hex tmp.hex
25 */
26
27/* HW (GFX9) source code for CWSR trap handler */
28/* Version 18 + multiple trap handler */
29
30// this performance-optimal version was originally from Seven Xu at SRDC
31
32// Revison #18 --...
33/* Rev History
34** #1. Branch from gc dv. //gfxip/gfx9/main/src/test/suites/block/cs/sr/cs_trap_handler.sp3#1,#50, #51, #52-53(Skip, Already Fixed by PV), #54-56(merged),#57-58(mergerd, skiped-already fixed by PV)
35** #4. SR Memory Layout:
36** 1. VGPR-SGPR-HWREG-{LDS}
37** 2. tba_hi.bits.26 - reconfigured as the first wave in tg bits, for defer Save LDS for a threadgroup.. performance concern..
38** #5. Update: 1. Accurate g8sr_ts_save_d timestamp
39** #6. Update: 1. Fix s_barrier usage; 2. VGPR s/r using swizzle buffer?(NoNeed, already matched the swizzle pattern, more investigation)
40** #7. Update: 1. don't barrier if noLDS
41** #8. Branch: 1. Branch to ver#0, which is very similar to gc dv version
42** 2. Fix SQ issue by s_sleep 2
43** #9. Update: 1. Fix scc restore failed issue, restore wave_status at last
44** 2. optimize s_buffer save by burst 16sgprs...
45** #10. Update 1. Optimize restore sgpr by busrt 16 sgprs.
46** #11. Update 1. Add 2 more timestamp for debug version
47** #12. Update 1. Add VGPR SR using DWx4, some case improve and some case drop performance
48** #13. Integ 1. Always use MUBUF for PV trap shader...
49** #14. Update 1. s_buffer_store soft clause...
50** #15. Update 1. PERF - sclar write with glc:0/mtype0 to allow L2 combine. perf improvement a lot.
51** #16. Update 1. PRRF - UNROLL LDS_DMA got 2500cycle save in IP tree
52** #17. Update 1. FUNC - LDS_DMA has issues while ATC, replace with ds_read/buffer_store for save part[TODO restore part]
53** 2. PERF - Save LDS before save VGPR to cover LDS save long latency...
54** #18. Update 1. FUNC - Implicitly estore STATUS.VCCZ, which is not writable by s_setreg_b32
55** 2. FUNC - Handle non-CWSR traps
56*/
57
58var G8SR_WDMEM_HWREG_OFFSET = 0
59var G8SR_WDMEM_SGPR_OFFSET = 128 // in bytes
60
61// Keep definition same as the app shader, These 2 time stamps are part of the app shader... Should before any Save and after restore.
62
63var G8SR_DEBUG_TIMESTAMP = 0
64var G8SR_DEBUG_TS_SAVE_D_OFFSET = 40*4 // ts_save_d timestamp offset relative to SGPR_SR_memory_offset
65var s_g8sr_ts_save_s = s[34:35] // save start
66var s_g8sr_ts_sq_save_msg = s[36:37] // The save shader send SAVEWAVE msg to spi
67var s_g8sr_ts_spi_wrexec = s[38:39] // the SPI write the sr address to SQ
68var s_g8sr_ts_save_d = s[40:41] // save end
69var s_g8sr_ts_restore_s = s[42:43] // restore start
70var s_g8sr_ts_restore_d = s[44:45] // restore end
71
72var G8SR_VGPR_SR_IN_DWX4 = 0
73var G8SR_SAVE_BUF_RSRC_WORD1_STRIDE_DWx4 = 0x00100000 // DWx4 stride is 4*4Bytes
74var G8SR_RESTORE_BUF_RSRC_WORD1_STRIDE_DWx4 = G8SR_SAVE_BUF_RSRC_WORD1_STRIDE_DWx4
75
76
77/*************************************************************************/
78/* control on how to run the shader */
79/*************************************************************************/
80//any hack that needs to be made to run this code in EMU (either because various EMU code are not ready or no compute save & restore in EMU run)
81var EMU_RUN_HACK = 0
82var EMU_RUN_HACK_RESTORE_NORMAL = 0
83var EMU_RUN_HACK_SAVE_NORMAL_EXIT = 0
84var EMU_RUN_HACK_SAVE_SINGLE_WAVE = 0
85var EMU_RUN_HACK_SAVE_FIRST_TIME = 0 //for interrupted restore in which the first save is through EMU_RUN_HACK
86var SAVE_LDS = 1
87var WG_BASE_ADDR_LO = 0x9000a000
88var WG_BASE_ADDR_HI = 0x0
89var WAVE_SPACE = 0x5000 //memory size that each wave occupies in workgroup state mem
90var CTX_SAVE_CONTROL = 0x0
91var CTX_RESTORE_CONTROL = CTX_SAVE_CONTROL
92var SIM_RUN_HACK = 0 //any hack that needs to be made to run this code in SIM (either because various RTL code are not ready or no compute save & restore in RTL run)
93var SGPR_SAVE_USE_SQC = 1 //use SQC D$ to do the write
94var USE_MTBUF_INSTEAD_OF_MUBUF = 0 //because TC EMU currently asserts on 0 of // overload DFMT field to carry 4 more bits of stride for MUBUF opcodes
95var SWIZZLE_EN = 0 //whether we use swizzled buffer addressing
96var ACK_SQC_STORE = 1 //workaround for suspected SQC store bug causing incorrect stores under concurrency
97
98/**************************************************************************/
99/* variables */
100/**************************************************************************/
101var SQ_WAVE_STATUS_INST_ATC_SHIFT = 23
102var SQ_WAVE_STATUS_INST_ATC_MASK = 0x00800000
103var SQ_WAVE_STATUS_SPI_PRIO_SHIFT = 1
104var SQ_WAVE_STATUS_SPI_PRIO_MASK = 0x00000006
105var SQ_WAVE_STATUS_HALT_MASK = 0x2000
106
107var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT = 12
108var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE = 9
109var SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT = 8
110var SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SIZE = 6
111var SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SHIFT = 24
112var SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SIZE = 3 //FIXME sq.blk still has 4 bits at this time while SQ programming guide has 3 bits
113
114var SQ_WAVE_TRAPSTS_SAVECTX_MASK = 0x400
115var SQ_WAVE_TRAPSTS_EXCE_MASK = 0x1FF // Exception mask
116var SQ_WAVE_TRAPSTS_SAVECTX_SHIFT = 10
117var SQ_WAVE_TRAPSTS_MEM_VIOL_MASK = 0x100
118var SQ_WAVE_TRAPSTS_MEM_VIOL_SHIFT = 8
119var SQ_WAVE_TRAPSTS_PRE_SAVECTX_MASK = 0x3FF
120var SQ_WAVE_TRAPSTS_PRE_SAVECTX_SHIFT = 0x0
121var SQ_WAVE_TRAPSTS_PRE_SAVECTX_SIZE = 10
122var SQ_WAVE_TRAPSTS_POST_SAVECTX_MASK = 0xFFFFF800
123var SQ_WAVE_TRAPSTS_POST_SAVECTX_SHIFT = 11
124var SQ_WAVE_TRAPSTS_POST_SAVECTX_SIZE = 21
125var SQ_WAVE_TRAPSTS_ILLEGAL_INST_MASK = 0x800
126
127var SQ_WAVE_IB_STS_RCNT_SHIFT = 16 //FIXME
128var SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT = 15 //FIXME
129var SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK = 0x1F8000
130var SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK_NEG = 0x00007FFF //FIXME
131
132var SQ_BUF_RSRC_WORD1_ATC_SHIFT = 24
133var SQ_BUF_RSRC_WORD3_MTYPE_SHIFT = 27
134
135var TTMP11_SAVE_RCNT_FIRST_REPLAY_SHIFT = 26 // bits [31:26] unused by SPI debug data
136var TTMP11_SAVE_RCNT_FIRST_REPLAY_MASK = 0xFC000000
137
138/* Save */
139var S_SAVE_BUF_RSRC_WORD1_STRIDE = 0x00040000 //stride is 4 bytes
140var S_SAVE_BUF_RSRC_WORD3_MISC = 0x00807FAC //SQ_SEL_X/Y/Z/W, BUF_NUM_FORMAT_FLOAT, (0 for MUBUF stride[17:14] when ADD_TID_ENABLE and BUF_DATA_FORMAT_32 for MTBUF), ADD_TID_ENABLE
141
142var S_SAVE_SPI_INIT_ATC_MASK = 0x08000000 //bit[27]: ATC bit
143var S_SAVE_SPI_INIT_ATC_SHIFT = 27
144var S_SAVE_SPI_INIT_MTYPE_MASK = 0x70000000 //bit[30:28]: Mtype
145var S_SAVE_SPI_INIT_MTYPE_SHIFT = 28
146var S_SAVE_SPI_INIT_FIRST_WAVE_MASK = 0x04000000 //bit[26]: FirstWaveInTG
147var S_SAVE_SPI_INIT_FIRST_WAVE_SHIFT = 26
148
149var S_SAVE_PC_HI_RCNT_SHIFT = 28 //FIXME check with Brian to ensure all fields other than PC[47:0] can be used
150var S_SAVE_PC_HI_RCNT_MASK = 0xF0000000 //FIXME
151var S_SAVE_PC_HI_FIRST_REPLAY_SHIFT = 27 //FIXME
152var S_SAVE_PC_HI_FIRST_REPLAY_MASK = 0x08000000 //FIXME
153
154var s_save_spi_init_lo = exec_lo
155var s_save_spi_init_hi = exec_hi
156
157var s_save_pc_lo = ttmp0 //{TTMP1, TTMP0} = {3'h0,pc_rewind[3:0], HT[0],trapID[7:0], PC[47:0]}
158var s_save_pc_hi = ttmp1
159var s_save_exec_lo = ttmp2
160var s_save_exec_hi = ttmp3
161var s_save_tmp = ttmp4
162var s_save_trapsts = ttmp5 //not really used until the end of the SAVE routine
163var s_save_xnack_mask_lo = ttmp6
164var s_save_xnack_mask_hi = ttmp7
165var s_save_buf_rsrc0 = ttmp8
166var s_save_buf_rsrc1 = ttmp9
167var s_save_buf_rsrc2 = ttmp10
168var s_save_buf_rsrc3 = ttmp11
169var s_save_status = ttmp12
170var s_save_mem_offset = ttmp14
171var s_save_alloc_size = s_save_trapsts //conflict
172var s_save_m0 = ttmp15
173var s_save_ttmps_lo = s_save_tmp //no conflict
174var s_save_ttmps_hi = s_save_trapsts //no conflict
175
176/* Restore */
177var S_RESTORE_BUF_RSRC_WORD1_STRIDE = S_SAVE_BUF_RSRC_WORD1_STRIDE
178var S_RESTORE_BUF_RSRC_WORD3_MISC = S_SAVE_BUF_RSRC_WORD3_MISC
179
180var S_RESTORE_SPI_INIT_ATC_MASK = 0x08000000 //bit[27]: ATC bit
181var S_RESTORE_SPI_INIT_ATC_SHIFT = 27
182var S_RESTORE_SPI_INIT_MTYPE_MASK = 0x70000000 //bit[30:28]: Mtype
183var S_RESTORE_SPI_INIT_MTYPE_SHIFT = 28
184var S_RESTORE_SPI_INIT_FIRST_WAVE_MASK = 0x04000000 //bit[26]: FirstWaveInTG
185var S_RESTORE_SPI_INIT_FIRST_WAVE_SHIFT = 26
186
187var S_RESTORE_PC_HI_RCNT_SHIFT = S_SAVE_PC_HI_RCNT_SHIFT
188var S_RESTORE_PC_HI_RCNT_MASK = S_SAVE_PC_HI_RCNT_MASK
189var S_RESTORE_PC_HI_FIRST_REPLAY_SHIFT = S_SAVE_PC_HI_FIRST_REPLAY_SHIFT
190var S_RESTORE_PC_HI_FIRST_REPLAY_MASK = S_SAVE_PC_HI_FIRST_REPLAY_MASK
191
192var s_restore_spi_init_lo = exec_lo
193var s_restore_spi_init_hi = exec_hi
194
195var s_restore_mem_offset = ttmp12
196var s_restore_alloc_size = ttmp3
197var s_restore_tmp = ttmp2
198var s_restore_mem_offset_save = s_restore_tmp //no conflict
199
200var s_restore_m0 = s_restore_alloc_size //no conflict
201
202var s_restore_mode = ttmp7
203
204var s_restore_pc_lo = ttmp0
205var s_restore_pc_hi = ttmp1
206var s_restore_exec_lo = ttmp14
207var s_restore_exec_hi = ttmp15
208var s_restore_status = ttmp4
209var s_restore_trapsts = ttmp5
210var s_restore_xnack_mask_lo = xnack_mask_lo
211var s_restore_xnack_mask_hi = xnack_mask_hi
212var s_restore_buf_rsrc0 = ttmp8
213var s_restore_buf_rsrc1 = ttmp9
214var s_restore_buf_rsrc2 = ttmp10
215var s_restore_buf_rsrc3 = ttmp11
216var s_restore_ttmps_lo = s_restore_tmp //no conflict
217var s_restore_ttmps_hi = s_restore_alloc_size //no conflict
218
219/**************************************************************************/
220/* trap handler entry points */
221/**************************************************************************/
222/* Shader Main*/
223
224shader main
225 asic(GFX9)
226 type(CS)
227
228
229 if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_RESTORE_NORMAL)) //hack to use trap_id for determining save/restore
230 //FIXME VCCZ un-init assertion s_getreg_b32 s_save_status, hwreg(HW_REG_STATUS) //save STATUS since we will change SCC
231 s_and_b32 s_save_tmp, s_save_pc_hi, 0xffff0000 //change SCC
232 s_cmp_eq_u32 s_save_tmp, 0x007e0000 //Save: trap_id = 0x7e. Restore: trap_id = 0x7f.
233 s_cbranch_scc0 L_JUMP_TO_RESTORE //do not need to recover STATUS here since we are going to RESTORE
234 //FIXME s_setreg_b32 hwreg(HW_REG_STATUS), s_save_status //need to recover STATUS since we are going to SAVE
235 s_branch L_SKIP_RESTORE //NOT restore, SAVE actually
236 else
237 s_branch L_SKIP_RESTORE //NOT restore. might be a regular trap or save
238 end
239
240L_JUMP_TO_RESTORE:
241 s_branch L_RESTORE //restore
242
243L_SKIP_RESTORE:
244
245 s_getreg_b32 s_save_status, hwreg(HW_REG_STATUS) //save STATUS since we will change SCC
246 s_andn2_b32 s_save_status, s_save_status, SQ_WAVE_STATUS_SPI_PRIO_MASK //check whether this is for save
247 s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS)
248 s_and_b32 ttmp2, s_save_trapsts, SQ_WAVE_TRAPSTS_SAVECTX_MASK //check whether this is for save
249 s_cbranch_scc1 L_SAVE //this is the operation for save
250
251 // ********* Handle non-CWSR traps *******************
252if (!EMU_RUN_HACK)
253 // Illegal instruction is a non-maskable exception which blocks context save.
254 // Halt the wavefront and return from the trap.
255 s_and_b32 ttmp2, s_save_trapsts, SQ_WAVE_TRAPSTS_ILLEGAL_INST_MASK
256 s_cbranch_scc1 L_HALT_WAVE
257
258 // If STATUS.MEM_VIOL is asserted then we cannot fetch from the TMA.
259 // Instead, halt the wavefront and return from the trap.
260 s_and_b32 ttmp2, s_save_trapsts, SQ_WAVE_TRAPSTS_MEM_VIOL_MASK
261 s_cbranch_scc0 L_FETCH_2ND_TRAP
262
263L_HALT_WAVE:
264 // If STATUS.HALT is set then this fault must come from SQC instruction fetch.
265 // We cannot prevent further faults so just terminate the wavefront.
266 s_and_b32 ttmp2, s_save_status, SQ_WAVE_STATUS_HALT_MASK
267 s_cbranch_scc0 L_NOT_ALREADY_HALTED
268 s_endpgm
269L_NOT_ALREADY_HALTED:
270 s_or_b32 s_save_status, s_save_status, SQ_WAVE_STATUS_HALT_MASK
271
272 // If the PC points to S_ENDPGM then context save will fail if STATUS.HALT is set.
273 // Rewind the PC to prevent this from occurring. The debugger compensates for this.
274 s_sub_u32 ttmp0, ttmp0, 0x8
275 s_subb_u32 ttmp1, ttmp1, 0x0
276
277L_FETCH_2ND_TRAP:
278 // Preserve and clear scalar XNACK state before issuing scalar reads.
279 // Save IB_STS.FIRST_REPLAY[15] and IB_STS.RCNT[20:16] into unused space ttmp11[31:26].
280 s_getreg_b32 ttmp2, hwreg(HW_REG_IB_STS)
281 s_and_b32 ttmp3, ttmp2, SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK
282 s_lshl_b32 ttmp3, ttmp3, (TTMP11_SAVE_RCNT_FIRST_REPLAY_SHIFT - SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT)
283 s_andn2_b32 ttmp11, ttmp11, TTMP11_SAVE_RCNT_FIRST_REPLAY_MASK
284 s_or_b32 ttmp11, ttmp11, ttmp3
285
286 s_andn2_b32 ttmp2, ttmp2, SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK
287 s_setreg_b32 hwreg(HW_REG_IB_STS), ttmp2
288
289 // Read second-level TBA/TMA from first-level TMA and jump if available.
290 // ttmp[2:5] and ttmp12 can be used (others hold SPI-initialized debug data)
291 // ttmp12 holds SQ_WAVE_STATUS
292 s_getreg_b32 ttmp4, hwreg(HW_REG_SQ_SHADER_TMA_LO)
293 s_getreg_b32 ttmp5, hwreg(HW_REG_SQ_SHADER_TMA_HI)
294 s_lshl_b64 [ttmp4, ttmp5], [ttmp4, ttmp5], 0x8
295 s_load_dwordx2 [ttmp2, ttmp3], [ttmp4, ttmp5], 0x0 glc:1 // second-level TBA
296 s_waitcnt lgkmcnt(0)
297 s_load_dwordx2 [ttmp4, ttmp5], [ttmp4, ttmp5], 0x8 glc:1 // second-level TMA
298 s_waitcnt lgkmcnt(0)
299 s_and_b64 [ttmp2, ttmp3], [ttmp2, ttmp3], [ttmp2, ttmp3]
300 s_cbranch_scc0 L_NO_NEXT_TRAP // second-level trap handler not been set
301 s_setpc_b64 [ttmp2, ttmp3] // jump to second-level trap handler
302
303L_NO_NEXT_TRAP:
304 s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS)
305 s_and_b32 s_save_trapsts, s_save_trapsts, SQ_WAVE_TRAPSTS_EXCE_MASK // Check whether it is an exception
306 s_cbranch_scc1 L_EXCP_CASE // Exception, jump back to the shader program directly.
307 s_add_u32 ttmp0, ttmp0, 4 // S_TRAP case, add 4 to ttmp0
308 s_addc_u32 ttmp1, ttmp1, 0
309L_EXCP_CASE:
310 s_and_b32 ttmp1, ttmp1, 0xFFFF
311
312 // Restore SQ_WAVE_IB_STS.
313 s_lshr_b32 ttmp2, ttmp11, (TTMP11_SAVE_RCNT_FIRST_REPLAY_SHIFT - SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT)
314 s_and_b32 ttmp2, ttmp2, SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK
315 s_setreg_b32 hwreg(HW_REG_IB_STS), ttmp2
316
317 // Restore SQ_WAVE_STATUS.
318 s_and_b64 exec, exec, exec // Restore STATUS.EXECZ, not writable by s_setreg_b32
319 s_and_b64 vcc, vcc, vcc // Restore STATUS.VCCZ, not writable by s_setreg_b32
320 s_setreg_b32 hwreg(HW_REG_STATUS), s_save_status
321
322 s_rfe_b64 [ttmp0, ttmp1]
323end
324 // ********* End handling of non-CWSR traps *******************
325
326/**************************************************************************/
327/* save routine */
328/**************************************************************************/
329
330L_SAVE:
331
332if G8SR_DEBUG_TIMESTAMP
333 s_memrealtime s_g8sr_ts_save_s
334 s_waitcnt lgkmcnt(0) //FIXME, will cause xnack??
335end
336
337 s_and_b32 s_save_pc_hi, s_save_pc_hi, 0x0000ffff //pc[47:32]
338
339 s_mov_b32 s_save_tmp, 0 //clear saveCtx bit
340 s_setreg_b32 hwreg(HW_REG_TRAPSTS, SQ_WAVE_TRAPSTS_SAVECTX_SHIFT, 1), s_save_tmp //clear saveCtx bit
341
342 s_getreg_b32 s_save_tmp, hwreg(HW_REG_IB_STS, SQ_WAVE_IB_STS_RCNT_SHIFT, SQ_WAVE_IB_STS_RCNT_SIZE) //save RCNT
343 s_lshl_b32 s_save_tmp, s_save_tmp, S_SAVE_PC_HI_RCNT_SHIFT
344 s_or_b32 s_save_pc_hi, s_save_pc_hi, s_save_tmp
345 s_getreg_b32 s_save_tmp, hwreg(HW_REG_IB_STS, SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT, SQ_WAVE_IB_STS_FIRST_REPLAY_SIZE) //save FIRST_REPLAY
346 s_lshl_b32 s_save_tmp, s_save_tmp, S_SAVE_PC_HI_FIRST_REPLAY_SHIFT
347 s_or_b32 s_save_pc_hi, s_save_pc_hi, s_save_tmp
348 s_getreg_b32 s_save_tmp, hwreg(HW_REG_IB_STS) //clear RCNT and FIRST_REPLAY in IB_STS
349 s_and_b32 s_save_tmp, s_save_tmp, SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK_NEG
350
351 s_setreg_b32 hwreg(HW_REG_IB_STS), s_save_tmp
352
353 /* inform SPI the readiness and wait for SPI's go signal */
354 s_mov_b32 s_save_exec_lo, exec_lo //save EXEC and use EXEC for the go signal from SPI
355 s_mov_b32 s_save_exec_hi, exec_hi
356 s_mov_b64 exec, 0x0 //clear EXEC to get ready to receive
357
358if G8SR_DEBUG_TIMESTAMP
359 s_memrealtime s_g8sr_ts_sq_save_msg
360 s_waitcnt lgkmcnt(0)
361end
362
363 if (EMU_RUN_HACK)
364
365 else
366 s_sendmsg sendmsg(MSG_SAVEWAVE) //send SPI a message and wait for SPI's write to EXEC
367 end
368
369 // Set SPI_PRIO=2 to avoid starving instruction fetch in the waves we're waiting for.
370 s_or_b32 s_save_tmp, s_save_status, (2 << SQ_WAVE_STATUS_SPI_PRIO_SHIFT)
371 s_setreg_b32 hwreg(HW_REG_STATUS), s_save_tmp
372
373 L_SLEEP:
374 s_sleep 0x2 // sleep 1 (64clk) is not enough for 8 waves per SIMD, which will cause SQ hang, since the 7,8th wave could not get arbit to exec inst, while other waves are stuck into the sleep-loop and waiting for wrexec!=0
375
376 if (EMU_RUN_HACK)
377
378 else
379 s_cbranch_execz L_SLEEP
380 end
381
382if G8SR_DEBUG_TIMESTAMP
383 s_memrealtime s_g8sr_ts_spi_wrexec
384 s_waitcnt lgkmcnt(0)
385end
386
387 if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_SAVE_SINGLE_WAVE))
388 //calculate wd_addr using absolute thread id
389 v_readlane_b32 s_save_tmp, v9, 0
390 s_lshr_b32 s_save_tmp, s_save_tmp, 6
391 s_mul_i32 s_save_tmp, s_save_tmp, WAVE_SPACE
392 s_add_i32 s_save_spi_init_lo, s_save_tmp, WG_BASE_ADDR_LO
393 s_mov_b32 s_save_spi_init_hi, WG_BASE_ADDR_HI
394 s_and_b32 s_save_spi_init_hi, s_save_spi_init_hi, CTX_SAVE_CONTROL
395 else
396 end
397 if ((EMU_RUN_HACK) && (EMU_RUN_HACK_SAVE_SINGLE_WAVE))
398 s_add_i32 s_save_spi_init_lo, s_save_tmp, WG_BASE_ADDR_LO
399 s_mov_b32 s_save_spi_init_hi, WG_BASE_ADDR_HI
400 s_and_b32 s_save_spi_init_hi, s_save_spi_init_hi, CTX_SAVE_CONTROL
401 else
402 end
403
404 // Save trap temporaries 6-11, 13-15 initialized by SPI debug dispatch logic
405 // ttmp SR memory offset : size(VGPR)+size(SGPR)+0x40
406 get_vgpr_size_bytes(s_save_ttmps_lo)
407 get_sgpr_size_bytes(s_save_ttmps_hi)
408 s_add_u32 s_save_ttmps_lo, s_save_ttmps_lo, s_save_ttmps_hi
409 s_add_u32 s_save_ttmps_lo, s_save_ttmps_lo, s_save_spi_init_lo
410 s_addc_u32 s_save_ttmps_hi, s_save_spi_init_hi, 0x0
411 s_and_b32 s_save_ttmps_hi, s_save_ttmps_hi, 0xFFFF
412 s_store_dwordx2 [ttmp6, ttmp7], [s_save_ttmps_lo, s_save_ttmps_hi], 0x40 glc:1
413 ack_sqc_store_workaround()
414 s_store_dwordx4 [ttmp8, ttmp9, ttmp10, ttmp11], [s_save_ttmps_lo, s_save_ttmps_hi], 0x48 glc:1
415 ack_sqc_store_workaround()
416 s_store_dword ttmp13, [s_save_ttmps_lo, s_save_ttmps_hi], 0x58 glc:1
417 ack_sqc_store_workaround()
418 s_store_dwordx2 [ttmp14, ttmp15], [s_save_ttmps_lo, s_save_ttmps_hi], 0x5C glc:1
419 ack_sqc_store_workaround()
420
421 /* setup Resource Contants */
422 s_mov_b32 s_save_buf_rsrc0, s_save_spi_init_lo //base_addr_lo
423 s_and_b32 s_save_buf_rsrc1, s_save_spi_init_hi, 0x0000FFFF //base_addr_hi
424 s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, S_SAVE_BUF_RSRC_WORD1_STRIDE
425 s_mov_b32 s_save_buf_rsrc2, 0 //NUM_RECORDS initial value = 0 (in bytes) although not neccessarily inited
426 s_mov_b32 s_save_buf_rsrc3, S_SAVE_BUF_RSRC_WORD3_MISC
427 s_and_b32 s_save_tmp, s_save_spi_init_hi, S_SAVE_SPI_INIT_ATC_MASK
428 s_lshr_b32 s_save_tmp, s_save_tmp, (S_SAVE_SPI_INIT_ATC_SHIFT-SQ_BUF_RSRC_WORD1_ATC_SHIFT) //get ATC bit into position
429 s_or_b32 s_save_buf_rsrc3, s_save_buf_rsrc3, s_save_tmp //or ATC
430 s_and_b32 s_save_tmp, s_save_spi_init_hi, S_SAVE_SPI_INIT_MTYPE_MASK
431 s_lshr_b32 s_save_tmp, s_save_tmp, (S_SAVE_SPI_INIT_MTYPE_SHIFT-SQ_BUF_RSRC_WORD3_MTYPE_SHIFT) //get MTYPE bits into position
432 s_or_b32 s_save_buf_rsrc3, s_save_buf_rsrc3, s_save_tmp //or MTYPE
433
434 //FIXME right now s_save_m0/s_save_mem_offset use tma_lo/tma_hi (might need to save them before using them?)
435 s_mov_b32 s_save_m0, m0 //save M0
436
437 /* global mem offset */
438 s_mov_b32 s_save_mem_offset, 0x0 //mem offset initial value = 0
439
440
441
442
443 /* save HW registers */
444 //////////////////////////////
445
446 L_SAVE_HWREG:
447 // HWREG SR memory offset : size(VGPR)+size(SGPR)
448 get_vgpr_size_bytes(s_save_mem_offset)
449 get_sgpr_size_bytes(s_save_tmp)
450 s_add_u32 s_save_mem_offset, s_save_mem_offset, s_save_tmp
451
452
453 s_mov_b32 s_save_buf_rsrc2, 0x4 //NUM_RECORDS in bytes
454 if (SWIZZLE_EN)
455 s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
456 else
457 s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
458 end
459
460
461 write_hwreg_to_mem(s_save_m0, s_save_buf_rsrc0, s_save_mem_offset) //M0
462
463 if ((EMU_RUN_HACK) && (EMU_RUN_HACK_SAVE_FIRST_TIME))
464 s_add_u32 s_save_pc_lo, s_save_pc_lo, 4 //pc[31:0]+4
465 s_addc_u32 s_save_pc_hi, s_save_pc_hi, 0x0 //carry bit over
466 end
467
468 write_hwreg_to_mem(s_save_pc_lo, s_save_buf_rsrc0, s_save_mem_offset) //PC
469 write_hwreg_to_mem(s_save_pc_hi, s_save_buf_rsrc0, s_save_mem_offset)
470 write_hwreg_to_mem(s_save_exec_lo, s_save_buf_rsrc0, s_save_mem_offset) //EXEC
471 write_hwreg_to_mem(s_save_exec_hi, s_save_buf_rsrc0, s_save_mem_offset)
472 write_hwreg_to_mem(s_save_status, s_save_buf_rsrc0, s_save_mem_offset) //STATUS
473
474 //s_save_trapsts conflicts with s_save_alloc_size
475 s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS)
476 write_hwreg_to_mem(s_save_trapsts, s_save_buf_rsrc0, s_save_mem_offset) //TRAPSTS
477
478 write_hwreg_to_mem(xnack_mask_lo, s_save_buf_rsrc0, s_save_mem_offset) //XNACK_MASK_LO
479 write_hwreg_to_mem(xnack_mask_hi, s_save_buf_rsrc0, s_save_mem_offset) //XNACK_MASK_HI
480
481 //use s_save_tmp would introduce conflict here between s_save_tmp and s_save_buf_rsrc2
482 s_getreg_b32 s_save_m0, hwreg(HW_REG_MODE) //MODE
483 write_hwreg_to_mem(s_save_m0, s_save_buf_rsrc0, s_save_mem_offset)
484
485
486
487 /* the first wave in the threadgroup */
488 s_and_b32 s_save_tmp, s_save_spi_init_hi, S_SAVE_SPI_INIT_FIRST_WAVE_MASK // extract fisrt wave bit
489 s_mov_b32 s_save_exec_hi, 0x0
490 s_or_b32 s_save_exec_hi, s_save_tmp, s_save_exec_hi // save first wave bit to s_save_exec_hi.bits[26]
491
492
493 /* save SGPRs */
494 // Save SGPR before LDS save, then the s0 to s4 can be used during LDS save...
495 //////////////////////////////
496
497 // SGPR SR memory offset : size(VGPR)
498 get_vgpr_size_bytes(s_save_mem_offset)
499 // TODO, change RSRC word to rearrange memory layout for SGPRS
500
501 s_getreg_b32 s_save_alloc_size, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SIZE) //spgr_size
502 s_add_u32 s_save_alloc_size, s_save_alloc_size, 1
503 s_lshl_b32 s_save_alloc_size, s_save_alloc_size, 4 //Number of SGPRs = (sgpr_size + 1) * 16 (non-zero value)
504
505 if (SGPR_SAVE_USE_SQC)
506 s_lshl_b32 s_save_buf_rsrc2, s_save_alloc_size, 2 //NUM_RECORDS in bytes
507 else
508 s_lshl_b32 s_save_buf_rsrc2, s_save_alloc_size, 8 //NUM_RECORDS in bytes (64 threads)
509 end
510
511 if (SWIZZLE_EN)
512 s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
513 else
514 s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
515 end
516
517
518 // backup s_save_buf_rsrc0,1 to s_save_pc_lo/hi, since write_16sgpr_to_mem function will change the rsrc0
519 //s_mov_b64 s_save_pc_lo, s_save_buf_rsrc0
520 s_mov_b64 s_save_xnack_mask_lo, s_save_buf_rsrc0
521 s_add_u32 s_save_buf_rsrc0, s_save_buf_rsrc0, s_save_mem_offset
522 s_addc_u32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0
523
524 s_mov_b32 m0, 0x0 //SGPR initial index value =0
525 s_nop 0x0 //Manually inserted wait states
526 L_SAVE_SGPR_LOOP:
527 // SGPR is allocated in 16 SGPR granularity
528 s_movrels_b64 s0, s0 //s0 = s[0+m0], s1 = s[1+m0]
529 s_movrels_b64 s2, s2 //s2 = s[2+m0], s3 = s[3+m0]
530 s_movrels_b64 s4, s4 //s4 = s[4+m0], s5 = s[5+m0]
531 s_movrels_b64 s6, s6 //s6 = s[6+m0], s7 = s[7+m0]
532 s_movrels_b64 s8, s8 //s8 = s[8+m0], s9 = s[9+m0]
533 s_movrels_b64 s10, s10 //s10 = s[10+m0], s11 = s[11+m0]
534 s_movrels_b64 s12, s12 //s12 = s[12+m0], s13 = s[13+m0]
535 s_movrels_b64 s14, s14 //s14 = s[14+m0], s15 = s[15+m0]
536
537 write_16sgpr_to_mem(s0, s_save_buf_rsrc0, s_save_mem_offset) //PV: the best performance should be using s_buffer_store_dwordx4
538 s_add_u32 m0, m0, 16 //next sgpr index
539 s_cmp_lt_u32 m0, s_save_alloc_size //scc = (m0 < s_save_alloc_size) ? 1 : 0
540 s_cbranch_scc1 L_SAVE_SGPR_LOOP //SGPR save is complete?
541 // restore s_save_buf_rsrc0,1
542 //s_mov_b64 s_save_buf_rsrc0, s_save_pc_lo
543 s_mov_b64 s_save_buf_rsrc0, s_save_xnack_mask_lo
544
545
546
547
548 /* save first 4 VGPR, then LDS save could use */
549 // each wave will alloc 4 vgprs at least...
550 /////////////////////////////////////////////////////////////////////////////////////
551
552 s_mov_b32 s_save_mem_offset, 0
553 s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on
554 s_mov_b32 exec_hi, 0xFFFFFFFF
555 s_mov_b32 xnack_mask_lo, 0x0
556 s_mov_b32 xnack_mask_hi, 0x0
557
558 if (SWIZZLE_EN)
559 s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
560 else
561 s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
562 end
563
564
565 // VGPR Allocated in 4-GPR granularity
566
567if G8SR_VGPR_SR_IN_DWX4
568 // the const stride for DWx4 is 4*4 bytes
569 s_and_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0x0000FFFF // reset const stride to 0
570 s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, G8SR_SAVE_BUF_RSRC_WORD1_STRIDE_DWx4 // const stride to 4*4 bytes
571
572 buffer_store_dwordx4 v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
573
574 s_and_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0x0000FFFF // reset const stride to 0
575 s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, S_SAVE_BUF_RSRC_WORD1_STRIDE // reset const stride to 4 bytes
576else
577 buffer_store_dword v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
578 buffer_store_dword v1, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256
579 buffer_store_dword v2, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256*2
580 buffer_store_dword v3, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256*3
581end
582
583
584
585 /* save LDS */
586 //////////////////////////////
587
588 L_SAVE_LDS:
589
590 // Change EXEC to all threads...
591 s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on
592 s_mov_b32 exec_hi, 0xFFFFFFFF
593
594 s_getreg_b32 s_save_alloc_size, hwreg(HW_REG_LDS_ALLOC,SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT,SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE) //lds_size
595 s_and_b32 s_save_alloc_size, s_save_alloc_size, 0xFFFFFFFF //lds_size is zero?
596 s_cbranch_scc0 L_SAVE_LDS_DONE //no lds used? jump to L_SAVE_DONE
597
598 s_barrier //LDS is used? wait for other waves in the same TG
599 s_and_b32 s_save_tmp, s_save_exec_hi, S_SAVE_SPI_INIT_FIRST_WAVE_MASK //exec is still used here
600 s_cbranch_scc0 L_SAVE_LDS_DONE
601
602 // first wave do LDS save;
603
604 s_lshl_b32 s_save_alloc_size, s_save_alloc_size, 6 //LDS size in dwords = lds_size * 64dw
605 s_lshl_b32 s_save_alloc_size, s_save_alloc_size, 2 //LDS size in bytes
606 s_mov_b32 s_save_buf_rsrc2, s_save_alloc_size //NUM_RECORDS in bytes
607
608 // LDS at offset: size(VGPR)+SIZE(SGPR)+SIZE(HWREG)
609 //
610 get_vgpr_size_bytes(s_save_mem_offset)
611 get_sgpr_size_bytes(s_save_tmp)
612 s_add_u32 s_save_mem_offset, s_save_mem_offset, s_save_tmp
613 s_add_u32 s_save_mem_offset, s_save_mem_offset, get_hwreg_size_bytes()
614
615
616 if (SWIZZLE_EN)
617 s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
618 else
619 s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
620 end
621
622 s_mov_b32 m0, 0x0 //lds_offset initial value = 0
623
624
625var LDS_DMA_ENABLE = 0
626var UNROLL = 0
627if UNROLL==0 && LDS_DMA_ENABLE==1
628 s_mov_b32 s3, 256*2
629 s_nop 0
630 s_nop 0
631 s_nop 0
632 L_SAVE_LDS_LOOP:
633 //TODO: looks the 2 buffer_store/load clause for s/r will hurt performance.???
634 if (SAVE_LDS) //SPI always alloc LDS space in 128DW granularity
635 buffer_store_lds_dword s_save_buf_rsrc0, s_save_mem_offset lds:1 // first 64DW
636 buffer_store_lds_dword s_save_buf_rsrc0, s_save_mem_offset lds:1 offset:256 // second 64DW
637 end
638
639 s_add_u32 m0, m0, s3 //every buffer_store_lds does 256 bytes
640 s_add_u32 s_save_mem_offset, s_save_mem_offset, s3 //mem offset increased by 256 bytes
641 s_cmp_lt_u32 m0, s_save_alloc_size //scc=(m0 < s_save_alloc_size) ? 1 : 0
642 s_cbranch_scc1 L_SAVE_LDS_LOOP //LDS save is complete?
643
644elsif LDS_DMA_ENABLE==1 && UNROLL==1 // UNROOL , has ichace miss
645 // store from higest LDS address to lowest
646 s_mov_b32 s3, 256*2
647 s_sub_u32 m0, s_save_alloc_size, s3
648 s_add_u32 s_save_mem_offset, s_save_mem_offset, m0
649 s_lshr_b32 s_save_alloc_size, s_save_alloc_size, 9 // how many 128 trunks...
650 s_sub_u32 s_save_alloc_size, 128, s_save_alloc_size // store from higheset addr to lowest
651 s_mul_i32 s_save_alloc_size, s_save_alloc_size, 6*4 // PC offset increment, each LDS save block cost 6*4 Bytes instruction
652 s_add_u32 s_save_alloc_size, s_save_alloc_size, 3*4 //2is the below 2 inst...//s_addc and s_setpc
653 s_nop 0
654 s_nop 0
655 s_nop 0 //pad 3 dw to let LDS_DMA align with 64Bytes
656 s_getpc_b64 s[0:1] // reuse s[0:1], since s[0:1] already saved
657 s_add_u32 s0, s0,s_save_alloc_size
658 s_addc_u32 s1, s1, 0
659 s_setpc_b64 s[0:1]
660
661
662 for var i =0; i< 128; i++
663 // be careful to make here a 64Byte aligned address, which could improve performance...
664 buffer_store_lds_dword s_save_buf_rsrc0, s_save_mem_offset lds:1 offset:0 // first 64DW
665 buffer_store_lds_dword s_save_buf_rsrc0, s_save_mem_offset lds:1 offset:256 // second 64DW
666
667 if i!=127
668 s_sub_u32 m0, m0, s3 // use a sgpr to shrink 2DW-inst to 1DW inst to improve performance , i.e. pack more LDS_DMA inst to one Cacheline
669 s_sub_u32 s_save_mem_offset, s_save_mem_offset, s3
670 end
671 end
672
673else // BUFFER_STORE
674 v_mbcnt_lo_u32_b32 v2, 0xffffffff, 0x0
675 v_mbcnt_hi_u32_b32 v3, 0xffffffff, v2 // tid
676 v_mul_i32_i24 v2, v3, 8 // tid*8
677 v_mov_b32 v3, 256*2
678 s_mov_b32 m0, 0x10000
679 s_mov_b32 s0, s_save_buf_rsrc3
680 s_and_b32 s_save_buf_rsrc3, s_save_buf_rsrc3, 0xFF7FFFFF // disable add_tid
681 s_or_b32 s_save_buf_rsrc3, s_save_buf_rsrc3, 0x58000 //DFMT
682
683L_SAVE_LDS_LOOP_VECTOR:
684 ds_read_b64 v[0:1], v2 //x =LDS[a], byte address
685 s_waitcnt lgkmcnt(0)
686 buffer_store_dwordx2 v[0:1], v2, s_save_buf_rsrc0, s_save_mem_offset offen:1 glc:1 slc:1
687// s_waitcnt vmcnt(0)
688// v_add_u32 v2, vcc[0:1], v2, v3
689 v_add_u32 v2, v2, v3
690 v_cmp_lt_u32 vcc[0:1], v2, s_save_alloc_size
691 s_cbranch_vccnz L_SAVE_LDS_LOOP_VECTOR
692
693 // restore rsrc3
694 s_mov_b32 s_save_buf_rsrc3, s0
695
696end
697
698L_SAVE_LDS_DONE:
699
700
701 /* save VGPRs - set the Rest VGPRs */
702 //////////////////////////////////////////////////////////////////////////////////////
703 L_SAVE_VGPR:
704 // VGPR SR memory offset: 0
705 // TODO rearrange the RSRC words to use swizzle for VGPR save...
706
707 s_mov_b32 s_save_mem_offset, (0+256*4) // for the rest VGPRs
708 s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on
709 s_mov_b32 exec_hi, 0xFFFFFFFF
710
711 s_getreg_b32 s_save_alloc_size, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SIZE) //vpgr_size
712 s_add_u32 s_save_alloc_size, s_save_alloc_size, 1
713 s_lshl_b32 s_save_alloc_size, s_save_alloc_size, 2 //Number of VGPRs = (vgpr_size + 1) * 4 (non-zero value) //FIXME for GFX, zero is possible
714 s_lshl_b32 s_save_buf_rsrc2, s_save_alloc_size, 8 //NUM_RECORDS in bytes (64 threads*4)
715 if (SWIZZLE_EN)
716 s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
717 else
718 s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
719 end
720
721
722 // VGPR Allocated in 4-GPR granularity
723
724if G8SR_VGPR_SR_IN_DWX4
725 // the const stride for DWx4 is 4*4 bytes
726 s_and_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0x0000FFFF // reset const stride to 0
727 s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, G8SR_SAVE_BUF_RSRC_WORD1_STRIDE_DWx4 // const stride to 4*4 bytes
728
729 s_mov_b32 m0, 4 // skip first 4 VGPRs
730 s_cmp_lt_u32 m0, s_save_alloc_size
731 s_cbranch_scc0 L_SAVE_VGPR_LOOP_END // no more vgprs
732
733 s_set_gpr_idx_on m0, 0x1 // This will change M0
734 s_add_u32 s_save_alloc_size, s_save_alloc_size, 0x1000 // because above inst change m0
735L_SAVE_VGPR_LOOP:
736 v_mov_b32 v0, v0 // v0 = v[0+m0]
737 v_mov_b32 v1, v1
738 v_mov_b32 v2, v2
739 v_mov_b32 v3, v3
740
741
742 buffer_store_dwordx4 v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
743 s_add_u32 m0, m0, 4
744 s_add_u32 s_save_mem_offset, s_save_mem_offset, 256*4
745 s_cmp_lt_u32 m0, s_save_alloc_size
746 s_cbranch_scc1 L_SAVE_VGPR_LOOP //VGPR save is complete?
747 s_set_gpr_idx_off
748L_SAVE_VGPR_LOOP_END:
749
750 s_and_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0x0000FFFF // reset const stride to 0
751 s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, S_SAVE_BUF_RSRC_WORD1_STRIDE // reset const stride to 4 bytes
752else
753 // VGPR store using dw burst
754 s_mov_b32 m0, 0x4 //VGPR initial index value =0
755 s_cmp_lt_u32 m0, s_save_alloc_size
756 s_cbranch_scc0 L_SAVE_VGPR_END
757
758
759 s_set_gpr_idx_on m0, 0x1 //M0[7:0] = M0[7:0] and M0[15:12] = 0x1
760 s_add_u32 s_save_alloc_size, s_save_alloc_size, 0x1000 //add 0x1000 since we compare m0 against it later
761
762 L_SAVE_VGPR_LOOP:
763 v_mov_b32 v0, v0 //v0 = v[0+m0]
764 v_mov_b32 v1, v1 //v0 = v[0+m0]
765 v_mov_b32 v2, v2 //v0 = v[0+m0]
766 v_mov_b32 v3, v3 //v0 = v[0+m0]
767
768 if(USE_MTBUF_INSTEAD_OF_MUBUF)
769 tbuffer_store_format_x v0, v0, s_save_buf_rsrc0, s_save_mem_offset format:BUF_NUM_FORMAT_FLOAT format: BUF_DATA_FORMAT_32 slc:1 glc:1
770 else
771 buffer_store_dword v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
772 buffer_store_dword v1, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256
773 buffer_store_dword v2, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256*2
774 buffer_store_dword v3, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256*3
775 end
776
777 s_add_u32 m0, m0, 4 //next vgpr index
778 s_add_u32 s_save_mem_offset, s_save_mem_offset, 256*4 //every buffer_store_dword does 256 bytes
779 s_cmp_lt_u32 m0, s_save_alloc_size //scc = (m0 < s_save_alloc_size) ? 1 : 0
780 s_cbranch_scc1 L_SAVE_VGPR_LOOP //VGPR save is complete?
781 s_set_gpr_idx_off
782end
783
784L_SAVE_VGPR_END:
785
786
787
788
789
790
791 /* S_PGM_END_SAVED */ //FIXME graphics ONLY
792 if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_SAVE_NORMAL_EXIT))
793 s_and_b32 s_save_pc_hi, s_save_pc_hi, 0x0000ffff //pc[47:32]
794 s_add_u32 s_save_pc_lo, s_save_pc_lo, 4 //pc[31:0]+4
795 s_addc_u32 s_save_pc_hi, s_save_pc_hi, 0x0 //carry bit over
796 s_rfe_b64 s_save_pc_lo //Return to the main shader program
797 else
798 end
799
800// Save Done timestamp
801if G8SR_DEBUG_TIMESTAMP
802 s_memrealtime s_g8sr_ts_save_d
803 // SGPR SR memory offset : size(VGPR)
804 get_vgpr_size_bytes(s_save_mem_offset)
805 s_add_u32 s_save_mem_offset, s_save_mem_offset, G8SR_DEBUG_TS_SAVE_D_OFFSET
806 s_waitcnt lgkmcnt(0) //FIXME, will cause xnack??
807 // Need reset rsrc2??
808 s_mov_b32 m0, s_save_mem_offset
809 s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
810 s_buffer_store_dwordx2 s_g8sr_ts_save_d, s_save_buf_rsrc0, m0 glc:1
811end
812
813
814 s_branch L_END_PGM
815
816
817
818/**************************************************************************/
819/* restore routine */
820/**************************************************************************/
821
822L_RESTORE:
823 /* Setup Resource Contants */
824 if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_RESTORE_NORMAL))
825 //calculate wd_addr using absolute thread id
826 v_readlane_b32 s_restore_tmp, v9, 0
827 s_lshr_b32 s_restore_tmp, s_restore_tmp, 6
828 s_mul_i32 s_restore_tmp, s_restore_tmp, WAVE_SPACE
829 s_add_i32 s_restore_spi_init_lo, s_restore_tmp, WG_BASE_ADDR_LO
830 s_mov_b32 s_restore_spi_init_hi, WG_BASE_ADDR_HI
831 s_and_b32 s_restore_spi_init_hi, s_restore_spi_init_hi, CTX_RESTORE_CONTROL
832 else
833 end
834
835if G8SR_DEBUG_TIMESTAMP
836 s_memrealtime s_g8sr_ts_restore_s
837 s_waitcnt lgkmcnt(0) //FIXME, will cause xnack??
838 // tma_lo/hi are sgpr 110, 111, which will not used for 112 SGPR allocated case...
839 s_mov_b32 s_restore_pc_lo, s_g8sr_ts_restore_s[0]
840 s_mov_b32 s_restore_pc_hi, s_g8sr_ts_restore_s[1] //backup ts to ttmp0/1, sicne exec will be finally restored..
841end
842
843
844
845 s_mov_b32 s_restore_buf_rsrc0, s_restore_spi_init_lo //base_addr_lo
846 s_and_b32 s_restore_buf_rsrc1, s_restore_spi_init_hi, 0x0000FFFF //base_addr_hi
847 s_or_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, S_RESTORE_BUF_RSRC_WORD1_STRIDE
848 s_mov_b32 s_restore_buf_rsrc2, 0 //NUM_RECORDS initial value = 0 (in bytes)
849 s_mov_b32 s_restore_buf_rsrc3, S_RESTORE_BUF_RSRC_WORD3_MISC
850 s_and_b32 s_restore_tmp, s_restore_spi_init_hi, S_RESTORE_SPI_INIT_ATC_MASK
851 s_lshr_b32 s_restore_tmp, s_restore_tmp, (S_RESTORE_SPI_INIT_ATC_SHIFT-SQ_BUF_RSRC_WORD1_ATC_SHIFT) //get ATC bit into position
852 s_or_b32 s_restore_buf_rsrc3, s_restore_buf_rsrc3, s_restore_tmp //or ATC
853 s_and_b32 s_restore_tmp, s_restore_spi_init_hi, S_RESTORE_SPI_INIT_MTYPE_MASK
854 s_lshr_b32 s_restore_tmp, s_restore_tmp, (S_RESTORE_SPI_INIT_MTYPE_SHIFT-SQ_BUF_RSRC_WORD3_MTYPE_SHIFT) //get MTYPE bits into position
855 s_or_b32 s_restore_buf_rsrc3, s_restore_buf_rsrc3, s_restore_tmp //or MTYPE
856
857 /* global mem offset */
858// s_mov_b32 s_restore_mem_offset, 0x0 //mem offset initial value = 0
859
860 /* the first wave in the threadgroup */
861 s_and_b32 s_restore_tmp, s_restore_spi_init_hi, S_RESTORE_SPI_INIT_FIRST_WAVE_MASK
862 s_cbranch_scc0 L_RESTORE_VGPR
863
864 /* restore LDS */
865 //////////////////////////////
866 L_RESTORE_LDS:
867
868 s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on //be consistent with SAVE although can be moved ahead
869 s_mov_b32 exec_hi, 0xFFFFFFFF
870
871 s_getreg_b32 s_restore_alloc_size, hwreg(HW_REG_LDS_ALLOC,SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT,SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE) //lds_size
872 s_and_b32 s_restore_alloc_size, s_restore_alloc_size, 0xFFFFFFFF //lds_size is zero?
873 s_cbranch_scc0 L_RESTORE_VGPR //no lds used? jump to L_RESTORE_VGPR
874 s_lshl_b32 s_restore_alloc_size, s_restore_alloc_size, 6 //LDS size in dwords = lds_size * 64dw
875 s_lshl_b32 s_restore_alloc_size, s_restore_alloc_size, 2 //LDS size in bytes
876 s_mov_b32 s_restore_buf_rsrc2, s_restore_alloc_size //NUM_RECORDS in bytes
877
878 // LDS at offset: size(VGPR)+SIZE(SGPR)+SIZE(HWREG)
879 //
880 get_vgpr_size_bytes(s_restore_mem_offset)
881 get_sgpr_size_bytes(s_restore_tmp)
882 s_add_u32 s_restore_mem_offset, s_restore_mem_offset, s_restore_tmp
883 s_add_u32 s_restore_mem_offset, s_restore_mem_offset, get_hwreg_size_bytes() //FIXME, Check if offset overflow???
884
885
886 if (SWIZZLE_EN)
887 s_add_u32 s_restore_buf_rsrc2, s_restore_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
888 else
889 s_mov_b32 s_restore_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
890 end
891 s_mov_b32 m0, 0x0 //lds_offset initial value = 0
892
893 L_RESTORE_LDS_LOOP:
894 if (SAVE_LDS)
895 buffer_load_dword v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset lds:1 // first 64DW
896 buffer_load_dword v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset lds:1 offset:256 // second 64DW
897 end
898 s_add_u32 m0, m0, 256*2 // 128 DW
899 s_add_u32 s_restore_mem_offset, s_restore_mem_offset, 256*2 //mem offset increased by 128DW
900 s_cmp_lt_u32 m0, s_restore_alloc_size //scc=(m0 < s_restore_alloc_size) ? 1 : 0
901 s_cbranch_scc1 L_RESTORE_LDS_LOOP //LDS restore is complete?
902
903
904 /* restore VGPRs */
905 //////////////////////////////
906 L_RESTORE_VGPR:
907 // VGPR SR memory offset : 0
908 s_mov_b32 s_restore_mem_offset, 0x0
909 s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on //be consistent with SAVE although can be moved ahead
910 s_mov_b32 exec_hi, 0xFFFFFFFF
911
912 s_getreg_b32 s_restore_alloc_size, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SIZE) //vpgr_size
913 s_add_u32 s_restore_alloc_size, s_restore_alloc_size, 1
914 s_lshl_b32 s_restore_alloc_size, s_restore_alloc_size, 2 //Number of VGPRs = (vgpr_size + 1) * 4 (non-zero value)
915 s_lshl_b32 s_restore_buf_rsrc2, s_restore_alloc_size, 8 //NUM_RECORDS in bytes (64 threads*4)
916 if (SWIZZLE_EN)
917 s_add_u32 s_restore_buf_rsrc2, s_restore_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
918 else
919 s_mov_b32 s_restore_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
920 end
921
922if G8SR_VGPR_SR_IN_DWX4
923 get_vgpr_size_bytes(s_restore_mem_offset)
924 s_sub_u32 s_restore_mem_offset, s_restore_mem_offset, 256*4
925
926 // the const stride for DWx4 is 4*4 bytes
927 s_and_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, 0x0000FFFF // reset const stride to 0
928 s_or_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, G8SR_RESTORE_BUF_RSRC_WORD1_STRIDE_DWx4 // const stride to 4*4 bytes
929
930 s_mov_b32 m0, s_restore_alloc_size
931 s_set_gpr_idx_on m0, 0x8 // Note.. This will change m0
932
933L_RESTORE_VGPR_LOOP:
934 buffer_load_dwordx4 v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1
935 s_waitcnt vmcnt(0)
936 s_sub_u32 m0, m0, 4
937 v_mov_b32 v0, v0 // v[0+m0] = v0
938 v_mov_b32 v1, v1
939 v_mov_b32 v2, v2
940 v_mov_b32 v3, v3
941 s_sub_u32 s_restore_mem_offset, s_restore_mem_offset, 256*4
942 s_cmp_eq_u32 m0, 0x8000
943 s_cbranch_scc0 L_RESTORE_VGPR_LOOP
944 s_set_gpr_idx_off
945
946 s_and_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, 0x0000FFFF // reset const stride to 0
947 s_or_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, S_RESTORE_BUF_RSRC_WORD1_STRIDE // const stride to 4*4 bytes
948
949else
950 // VGPR load using dw burst
951 s_mov_b32 s_restore_mem_offset_save, s_restore_mem_offset // restore start with v1, v0 will be the last
952 s_add_u32 s_restore_mem_offset, s_restore_mem_offset, 256*4
953 s_mov_b32 m0, 4 //VGPR initial index value = 1
954 s_set_gpr_idx_on m0, 0x8 //M0[7:0] = M0[7:0] and M0[15:12] = 0x8
955 s_add_u32 s_restore_alloc_size, s_restore_alloc_size, 0x8000 //add 0x8000 since we compare m0 against it later
956
957 L_RESTORE_VGPR_LOOP:
958 if(USE_MTBUF_INSTEAD_OF_MUBUF)
959 tbuffer_load_format_x v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset format:BUF_NUM_FORMAT_FLOAT format: BUF_DATA_FORMAT_32 slc:1 glc:1
960 else
961 buffer_load_dword v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1
962 buffer_load_dword v1, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1 offset:256
963 buffer_load_dword v2, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1 offset:256*2
964 buffer_load_dword v3, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1 offset:256*3
965 end
966 s_waitcnt vmcnt(0) //ensure data ready
967 v_mov_b32 v0, v0 //v[0+m0] = v0
968 v_mov_b32 v1, v1
969 v_mov_b32 v2, v2
970 v_mov_b32 v3, v3
971 s_add_u32 m0, m0, 4 //next vgpr index
972 s_add_u32 s_restore_mem_offset, s_restore_mem_offset, 256*4 //every buffer_load_dword does 256 bytes
973 s_cmp_lt_u32 m0, s_restore_alloc_size //scc = (m0 < s_restore_alloc_size) ? 1 : 0
974 s_cbranch_scc1 L_RESTORE_VGPR_LOOP //VGPR restore (except v0) is complete?
975 s_set_gpr_idx_off
976 /* VGPR restore on v0 */
977 if(USE_MTBUF_INSTEAD_OF_MUBUF)
978 tbuffer_load_format_x v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save format:BUF_NUM_FORMAT_FLOAT format: BUF_DATA_FORMAT_32 slc:1 glc:1
979 else
980 buffer_load_dword v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1
981 buffer_load_dword v1, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1 offset:256
982 buffer_load_dword v2, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1 offset:256*2
983 buffer_load_dword v3, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1 offset:256*3
984 end
985
986end
987
988 /* restore SGPRs */
989 //////////////////////////////
990
991 // SGPR SR memory offset : size(VGPR)
992 get_vgpr_size_bytes(s_restore_mem_offset)
993 get_sgpr_size_bytes(s_restore_tmp)
994 s_add_u32 s_restore_mem_offset, s_restore_mem_offset, s_restore_tmp
995 s_sub_u32 s_restore_mem_offset, s_restore_mem_offset, 16*4 // restore SGPR from S[n] to S[0], by 16 sgprs group
996 // TODO, change RSRC word to rearrange memory layout for SGPRS
997
998 s_getreg_b32 s_restore_alloc_size, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SIZE) //spgr_size
999 s_add_u32 s_restore_alloc_size, s_restore_alloc_size, 1
1000 s_lshl_b32 s_restore_alloc_size, s_restore_alloc_size, 4 //Number of SGPRs = (sgpr_size + 1) * 16 (non-zero value)
1001
1002 if (SGPR_SAVE_USE_SQC)
1003 s_lshl_b32 s_restore_buf_rsrc2, s_restore_alloc_size, 2 //NUM_RECORDS in bytes
1004 else
1005 s_lshl_b32 s_restore_buf_rsrc2, s_restore_alloc_size, 8 //NUM_RECORDS in bytes (64 threads)
1006 end
1007 if (SWIZZLE_EN)
1008 s_add_u32 s_restore_buf_rsrc2, s_restore_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
1009 else
1010 s_mov_b32 s_restore_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
1011 end
1012
1013 s_mov_b32 m0, s_restore_alloc_size
1014
1015 L_RESTORE_SGPR_LOOP:
1016 read_16sgpr_from_mem(s0, s_restore_buf_rsrc0, s_restore_mem_offset) //PV: further performance improvement can be made
1017 s_waitcnt lgkmcnt(0) //ensure data ready
1018
1019 s_sub_u32 m0, m0, 16 // Restore from S[n] to S[0]
1020 s_nop 0 // hazard SALU M0=> S_MOVREL
1021
1022 s_movreld_b64 s0, s0 //s[0+m0] = s0
1023 s_movreld_b64 s2, s2
1024 s_movreld_b64 s4, s4
1025 s_movreld_b64 s6, s6
1026 s_movreld_b64 s8, s8
1027 s_movreld_b64 s10, s10
1028 s_movreld_b64 s12, s12
1029 s_movreld_b64 s14, s14
1030
1031 s_cmp_eq_u32 m0, 0 //scc = (m0 < s_restore_alloc_size) ? 1 : 0
1032 s_cbranch_scc0 L_RESTORE_SGPR_LOOP //SGPR restore (except s0) is complete?
1033
1034 /* restore HW registers */
1035 //////////////////////////////
1036 L_RESTORE_HWREG:
1037
1038
1039if G8SR_DEBUG_TIMESTAMP
1040 s_mov_b32 s_g8sr_ts_restore_s[0], s_restore_pc_lo
1041 s_mov_b32 s_g8sr_ts_restore_s[1], s_restore_pc_hi
1042end
1043
1044 // HWREG SR memory offset : size(VGPR)+size(SGPR)
1045 get_vgpr_size_bytes(s_restore_mem_offset)
1046 get_sgpr_size_bytes(s_restore_tmp)
1047 s_add_u32 s_restore_mem_offset, s_restore_mem_offset, s_restore_tmp
1048
1049
1050 s_mov_b32 s_restore_buf_rsrc2, 0x4 //NUM_RECORDS in bytes
1051 if (SWIZZLE_EN)
1052 s_add_u32 s_restore_buf_rsrc2, s_restore_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
1053 else
1054 s_mov_b32 s_restore_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
1055 end
1056
1057 read_hwreg_from_mem(s_restore_m0, s_restore_buf_rsrc0, s_restore_mem_offset) //M0
1058 read_hwreg_from_mem(s_restore_pc_lo, s_restore_buf_rsrc0, s_restore_mem_offset) //PC
1059 read_hwreg_from_mem(s_restore_pc_hi, s_restore_buf_rsrc0, s_restore_mem_offset)
1060 read_hwreg_from_mem(s_restore_exec_lo, s_restore_buf_rsrc0, s_restore_mem_offset) //EXEC
1061 read_hwreg_from_mem(s_restore_exec_hi, s_restore_buf_rsrc0, s_restore_mem_offset)
1062 read_hwreg_from_mem(s_restore_status, s_restore_buf_rsrc0, s_restore_mem_offset) //STATUS
1063 read_hwreg_from_mem(s_restore_trapsts, s_restore_buf_rsrc0, s_restore_mem_offset) //TRAPSTS
1064 read_hwreg_from_mem(xnack_mask_lo, s_restore_buf_rsrc0, s_restore_mem_offset) //XNACK_MASK_LO
1065 read_hwreg_from_mem(xnack_mask_hi, s_restore_buf_rsrc0, s_restore_mem_offset) //XNACK_MASK_HI
1066 read_hwreg_from_mem(s_restore_mode, s_restore_buf_rsrc0, s_restore_mem_offset) //MODE
1067
1068 s_waitcnt lgkmcnt(0) //from now on, it is safe to restore STATUS and IB_STS
1069
1070 //for normal save & restore, the saved PC points to the next inst to execute, no adjustment needs to be made, otherwise:
1071 if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_RESTORE_NORMAL))
1072 s_add_u32 s_restore_pc_lo, s_restore_pc_lo, 8 //pc[31:0]+8 //two back-to-back s_trap are used (first for save and second for restore)
1073 s_addc_u32 s_restore_pc_hi, s_restore_pc_hi, 0x0 //carry bit over
1074 end
1075 if ((EMU_RUN_HACK) && (EMU_RUN_HACK_RESTORE_NORMAL))
1076 s_add_u32 s_restore_pc_lo, s_restore_pc_lo, 4 //pc[31:0]+4 // save is hack through s_trap but restore is normal
1077 s_addc_u32 s_restore_pc_hi, s_restore_pc_hi, 0x0 //carry bit over
1078 end
1079
1080 s_mov_b32 m0, s_restore_m0
1081 s_mov_b32 exec_lo, s_restore_exec_lo
1082 s_mov_b32 exec_hi, s_restore_exec_hi
1083
1084 s_and_b32 s_restore_m0, SQ_WAVE_TRAPSTS_PRE_SAVECTX_MASK, s_restore_trapsts
1085 s_setreg_b32 hwreg(HW_REG_TRAPSTS, SQ_WAVE_TRAPSTS_PRE_SAVECTX_SHIFT, SQ_WAVE_TRAPSTS_PRE_SAVECTX_SIZE), s_restore_m0
1086 s_and_b32 s_restore_m0, SQ_WAVE_TRAPSTS_POST_SAVECTX_MASK, s_restore_trapsts
1087 s_lshr_b32 s_restore_m0, s_restore_m0, SQ_WAVE_TRAPSTS_POST_SAVECTX_SHIFT
1088 s_setreg_b32 hwreg(HW_REG_TRAPSTS, SQ_WAVE_TRAPSTS_POST_SAVECTX_SHIFT, SQ_WAVE_TRAPSTS_POST_SAVECTX_SIZE), s_restore_m0
1089 //s_setreg_b32 hwreg(HW_REG_TRAPSTS), s_restore_trapsts //don't overwrite SAVECTX bit as it may be set through external SAVECTX during restore
1090 s_setreg_b32 hwreg(HW_REG_MODE), s_restore_mode
1091
1092 // Restore trap temporaries 6-11, 13-15 initialized by SPI debug dispatch logic
1093 // ttmp SR memory offset : size(VGPR)+size(SGPR)+0x40
1094 get_vgpr_size_bytes(s_restore_ttmps_lo)
1095 get_sgpr_size_bytes(s_restore_ttmps_hi)
1096 s_add_u32 s_restore_ttmps_lo, s_restore_ttmps_lo, s_restore_ttmps_hi
1097 s_add_u32 s_restore_ttmps_lo, s_restore_ttmps_lo, s_restore_buf_rsrc0
1098 s_addc_u32 s_restore_ttmps_hi, s_restore_buf_rsrc1, 0x0
1099 s_and_b32 s_restore_ttmps_hi, s_restore_ttmps_hi, 0xFFFF
1100 s_load_dwordx2 [ttmp6, ttmp7], [s_restore_ttmps_lo, s_restore_ttmps_hi], 0x40 glc:1
1101 s_load_dwordx4 [ttmp8, ttmp9, ttmp10, ttmp11], [s_restore_ttmps_lo, s_restore_ttmps_hi], 0x48 glc:1
1102 s_load_dword ttmp13, [s_restore_ttmps_lo, s_restore_ttmps_hi], 0x58 glc:1
1103 s_load_dwordx2 [ttmp14, ttmp15], [s_restore_ttmps_lo, s_restore_ttmps_hi], 0x5C glc:1
1104 s_waitcnt lgkmcnt(0)
1105
1106 //reuse s_restore_m0 as a temp register
1107 s_and_b32 s_restore_m0, s_restore_pc_hi, S_SAVE_PC_HI_RCNT_MASK
1108 s_lshr_b32 s_restore_m0, s_restore_m0, S_SAVE_PC_HI_RCNT_SHIFT
1109 s_lshl_b32 s_restore_m0, s_restore_m0, SQ_WAVE_IB_STS_RCNT_SHIFT
1110 s_mov_b32 s_restore_tmp, 0x0 //IB_STS is zero
1111 s_or_b32 s_restore_tmp, s_restore_tmp, s_restore_m0
1112 s_and_b32 s_restore_m0, s_restore_pc_hi, S_SAVE_PC_HI_FIRST_REPLAY_MASK
1113 s_lshr_b32 s_restore_m0, s_restore_m0, S_SAVE_PC_HI_FIRST_REPLAY_SHIFT
1114 s_lshl_b32 s_restore_m0, s_restore_m0, SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT
1115 s_or_b32 s_restore_tmp, s_restore_tmp, s_restore_m0
1116 s_and_b32 s_restore_m0, s_restore_status, SQ_WAVE_STATUS_INST_ATC_MASK
1117 s_lshr_b32 s_restore_m0, s_restore_m0, SQ_WAVE_STATUS_INST_ATC_SHIFT
1118 s_setreg_b32 hwreg(HW_REG_IB_STS), s_restore_tmp
1119
1120 s_and_b32 s_restore_pc_hi, s_restore_pc_hi, 0x0000ffff //pc[47:32] //Do it here in order not to affect STATUS
1121 s_and_b64 exec, exec, exec // Restore STATUS.EXECZ, not writable by s_setreg_b32
1122 s_and_b64 vcc, vcc, vcc // Restore STATUS.VCCZ, not writable by s_setreg_b32
1123 s_setreg_b32 hwreg(HW_REG_STATUS), s_restore_status // SCC is included, which is changed by previous salu
1124
1125 s_barrier //barrier to ensure the readiness of LDS before access attempts from any other wave in the same TG //FIXME not performance-optimal at this time
1126
1127if G8SR_DEBUG_TIMESTAMP
1128 s_memrealtime s_g8sr_ts_restore_d
1129 s_waitcnt lgkmcnt(0)
1130end
1131
1132// s_rfe_b64 s_restore_pc_lo //Return to the main shader program and resume execution
1133 s_rfe_restore_b64 s_restore_pc_lo, s_restore_m0 // s_restore_m0[0] is used to set STATUS.inst_atc
1134
1135
1136/**************************************************************************/
1137/* the END */
1138/**************************************************************************/
1139L_END_PGM:
1140 s_endpgm
1141
1142end
1143
1144
1145/**************************************************************************/
1146/* the helper functions */
1147/**************************************************************************/
1148
1149//Only for save hwreg to mem
1150function write_hwreg_to_mem(s, s_rsrc, s_mem_offset)
1151 s_mov_b32 exec_lo, m0 //assuming exec_lo is not needed anymore from this point on
1152 s_mov_b32 m0, s_mem_offset
1153 s_buffer_store_dword s, s_rsrc, m0 glc:1
1154 ack_sqc_store_workaround()
1155 s_add_u32 s_mem_offset, s_mem_offset, 4
1156 s_mov_b32 m0, exec_lo
1157end
1158
1159
1160// HWREG are saved before SGPRs, so all HWREG could be use.
1161function write_16sgpr_to_mem(s, s_rsrc, s_mem_offset)
1162
1163 s_buffer_store_dwordx4 s[0], s_rsrc, 0 glc:1
1164 ack_sqc_store_workaround()
1165 s_buffer_store_dwordx4 s[4], s_rsrc, 16 glc:1
1166 ack_sqc_store_workaround()
1167 s_buffer_store_dwordx4 s[8], s_rsrc, 32 glc:1
1168 ack_sqc_store_workaround()
1169 s_buffer_store_dwordx4 s[12], s_rsrc, 48 glc:1
1170 ack_sqc_store_workaround()
1171 s_add_u32 s_rsrc[0], s_rsrc[0], 4*16
1172 s_addc_u32 s_rsrc[1], s_rsrc[1], 0x0 // +scc
1173end
1174
1175
1176function read_hwreg_from_mem(s, s_rsrc, s_mem_offset)
1177 s_buffer_load_dword s, s_rsrc, s_mem_offset glc:1
1178 s_add_u32 s_mem_offset, s_mem_offset, 4
1179end
1180
1181function read_16sgpr_from_mem(s, s_rsrc, s_mem_offset)
1182 s_buffer_load_dwordx16 s, s_rsrc, s_mem_offset glc:1
1183 s_sub_u32 s_mem_offset, s_mem_offset, 4*16
1184end
1185
1186
1187
1188function get_lds_size_bytes(s_lds_size_byte)
1189 // SQ LDS granularity is 64DW, while PGM_RSRC2.lds_size is in granularity 128DW
1190 s_getreg_b32 s_lds_size_byte, hwreg(HW_REG_LDS_ALLOC, SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT, SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE) // lds_size
1191 s_lshl_b32 s_lds_size_byte, s_lds_size_byte, 8 //LDS size in dwords = lds_size * 64 *4Bytes // granularity 64DW
1192end
1193
1194function get_vgpr_size_bytes(s_vgpr_size_byte)
1195 s_getreg_b32 s_vgpr_size_byte, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SIZE) //vpgr_size
1196 s_add_u32 s_vgpr_size_byte, s_vgpr_size_byte, 1
1197 s_lshl_b32 s_vgpr_size_byte, s_vgpr_size_byte, (2+8) //Number of VGPRs = (vgpr_size + 1) * 4 * 64 * 4 (non-zero value) //FIXME for GFX, zero is possible
1198end
1199
1200function get_sgpr_size_bytes(s_sgpr_size_byte)
1201 s_getreg_b32 s_sgpr_size_byte, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SIZE) //spgr_size
1202 s_add_u32 s_sgpr_size_byte, s_sgpr_size_byte, 1
1203 s_lshl_b32 s_sgpr_size_byte, s_sgpr_size_byte, 6 //Number of SGPRs = (sgpr_size + 1) * 16 *4 (non-zero value)
1204end
1205
1206function get_hwreg_size_bytes
1207 return 128 //HWREG size 128 bytes
1208end
1209
1210function ack_sqc_store_workaround
1211 if ACK_SQC_STORE
1212 s_waitcnt lgkmcnt(0)
1213 end
1214end
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 59808a39ecf4..f64c5551cdba 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -233,7 +233,7 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
233 pr_debug("Queue Size: 0x%llX, %u\n", 233 pr_debug("Queue Size: 0x%llX, %u\n",
234 q_properties->queue_size, args->ring_size); 234 q_properties->queue_size, args->ring_size);
235 235
236 pr_debug("Queue r/w Pointers: %p, %p\n", 236 pr_debug("Queue r/w Pointers: %px, %px\n",
237 q_properties->read_ptr, 237 q_properties->read_ptr,
238 q_properties->write_ptr); 238 q_properties->write_ptr);
239 239
@@ -292,8 +292,16 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
292 292
293 293
294 /* Return gpu_id as doorbell offset for mmap usage */ 294 /* Return gpu_id as doorbell offset for mmap usage */
295 args->doorbell_offset = (KFD_MMAP_DOORBELL_MASK | args->gpu_id); 295 args->doorbell_offset = KFD_MMAP_TYPE_DOORBELL;
296 args->doorbell_offset |= KFD_MMAP_GPU_ID(args->gpu_id);
296 args->doorbell_offset <<= PAGE_SHIFT; 297 args->doorbell_offset <<= PAGE_SHIFT;
298 if (KFD_IS_SOC15(dev->device_info->asic_family))
299 /* On SOC15 ASICs, doorbell allocation must be
300 * per-device, and independent from the per-process
301 * queue_id. Return the doorbell offset within the
302 * doorbell aperture to user mode.
303 */
304 args->doorbell_offset |= q_properties.doorbell_off;
297 305
298 mutex_unlock(&p->mutex); 306 mutex_unlock(&p->mutex);
299 307
@@ -1296,8 +1304,8 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
1296 return -EINVAL; 1304 return -EINVAL;
1297 } 1305 }
1298 1306
1299 devices_arr = kmalloc(args->n_devices * sizeof(*devices_arr), 1307 devices_arr = kmalloc_array(args->n_devices, sizeof(*devices_arr),
1300 GFP_KERNEL); 1308 GFP_KERNEL);
1301 if (!devices_arr) 1309 if (!devices_arr)
1302 return -ENOMEM; 1310 return -ENOMEM;
1303 1311
@@ -1405,8 +1413,8 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
1405 return -EINVAL; 1413 return -EINVAL;
1406 } 1414 }
1407 1415
1408 devices_arr = kmalloc(args->n_devices * sizeof(*devices_arr), 1416 devices_arr = kmalloc_array(args->n_devices, sizeof(*devices_arr),
1409 GFP_KERNEL); 1417 GFP_KERNEL);
1410 if (!devices_arr) 1418 if (!devices_arr)
1411 return -ENOMEM; 1419 return -ENOMEM;
1412 1420
@@ -1645,23 +1653,33 @@ err_i1:
1645static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) 1653static int kfd_mmap(struct file *filp, struct vm_area_struct *vma)
1646{ 1654{
1647 struct kfd_process *process; 1655 struct kfd_process *process;
1656 struct kfd_dev *dev = NULL;
1657 unsigned long vm_pgoff;
1658 unsigned int gpu_id;
1648 1659
1649 process = kfd_get_process(current); 1660 process = kfd_get_process(current);
1650 if (IS_ERR(process)) 1661 if (IS_ERR(process))
1651 return PTR_ERR(process); 1662 return PTR_ERR(process);
1652 1663
1653 if ((vma->vm_pgoff & KFD_MMAP_DOORBELL_MASK) == 1664 vm_pgoff = vma->vm_pgoff;
1654 KFD_MMAP_DOORBELL_MASK) { 1665 vma->vm_pgoff = KFD_MMAP_OFFSET_VALUE_GET(vm_pgoff);
1655 vma->vm_pgoff = vma->vm_pgoff ^ KFD_MMAP_DOORBELL_MASK; 1666 gpu_id = KFD_MMAP_GPU_ID_GET(vm_pgoff);
1656 return kfd_doorbell_mmap(process, vma); 1667 if (gpu_id)
1657 } else if ((vma->vm_pgoff & KFD_MMAP_EVENTS_MASK) == 1668 dev = kfd_device_by_id(gpu_id);
1658 KFD_MMAP_EVENTS_MASK) { 1669
1659 vma->vm_pgoff = vma->vm_pgoff ^ KFD_MMAP_EVENTS_MASK; 1670 switch (vm_pgoff & KFD_MMAP_TYPE_MASK) {
1671 case KFD_MMAP_TYPE_DOORBELL:
1672 if (!dev)
1673 return -ENODEV;
1674 return kfd_doorbell_mmap(dev, process, vma);
1675
1676 case KFD_MMAP_TYPE_EVENTS:
1660 return kfd_event_mmap(process, vma); 1677 return kfd_event_mmap(process, vma);
1661 } else if ((vma->vm_pgoff & KFD_MMAP_RESERVED_MEM_MASK) == 1678
1662 KFD_MMAP_RESERVED_MEM_MASK) { 1679 case KFD_MMAP_TYPE_RESERVED_MEM:
1663 vma->vm_pgoff = vma->vm_pgoff ^ KFD_MMAP_RESERVED_MEM_MASK; 1680 if (!dev)
1664 return kfd_reserved_mem_mmap(process, vma); 1681 return -ENODEV;
1682 return kfd_reserved_mem_mmap(dev, process, vma);
1665 } 1683 }
1666 1684
1667 return -EFAULT; 1685 return -EFAULT;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
index 4f126ef6139b..296b3f230280 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
@@ -132,6 +132,9 @@ static struct kfd_gpu_cache_info carrizo_cache_info[] = {
132#define fiji_cache_info carrizo_cache_info 132#define fiji_cache_info carrizo_cache_info
133#define polaris10_cache_info carrizo_cache_info 133#define polaris10_cache_info carrizo_cache_info
134#define polaris11_cache_info carrizo_cache_info 134#define polaris11_cache_info carrizo_cache_info
135/* TODO - check & update Vega10 cache details */
136#define vega10_cache_info carrizo_cache_info
137#define raven_cache_info carrizo_cache_info
135 138
136static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev, 139static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
137 struct crat_subtype_computeunit *cu) 140 struct crat_subtype_computeunit *cu)
@@ -603,6 +606,14 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
603 pcache_info = polaris11_cache_info; 606 pcache_info = polaris11_cache_info;
604 num_of_cache_types = ARRAY_SIZE(polaris11_cache_info); 607 num_of_cache_types = ARRAY_SIZE(polaris11_cache_info);
605 break; 608 break;
609 case CHIP_VEGA10:
610 pcache_info = vega10_cache_info;
611 num_of_cache_types = ARRAY_SIZE(vega10_cache_info);
612 break;
613 case CHIP_RAVEN:
614 pcache_info = raven_cache_info;
615 num_of_cache_types = ARRAY_SIZE(raven_cache_info);
616 break;
606 default: 617 default:
607 return -EINVAL; 618 return -EINVAL;
608 } 619 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 3346699960dd..7ee6cec2c060 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -20,16 +20,13 @@
20 * OTHER DEALINGS IN THE SOFTWARE. 20 * OTHER DEALINGS IN THE SOFTWARE.
21 */ 21 */
22 22
23#if defined(CONFIG_AMD_IOMMU_V2_MODULE) || defined(CONFIG_AMD_IOMMU_V2)
24#include <linux/amd-iommu.h>
25#endif
26#include <linux/bsearch.h> 23#include <linux/bsearch.h>
27#include <linux/pci.h> 24#include <linux/pci.h>
28#include <linux/slab.h> 25#include <linux/slab.h>
29#include "kfd_priv.h" 26#include "kfd_priv.h"
30#include "kfd_device_queue_manager.h" 27#include "kfd_device_queue_manager.h"
31#include "kfd_pm4_headers_vi.h" 28#include "kfd_pm4_headers_vi.h"
32#include "cwsr_trap_handler_gfx8.asm" 29#include "cwsr_trap_handler.h"
33#include "kfd_iommu.h" 30#include "kfd_iommu.h"
34 31
35#define MQD_SIZE_ALIGNED 768 32#define MQD_SIZE_ALIGNED 768
@@ -41,6 +38,7 @@ static const struct kfd_device_info kaveri_device_info = {
41 .max_pasid_bits = 16, 38 .max_pasid_bits = 16,
42 /* max num of queues for KV.TODO should be a dynamic value */ 39 /* max num of queues for KV.TODO should be a dynamic value */
43 .max_no_of_hqd = 24, 40 .max_no_of_hqd = 24,
41 .doorbell_size = 4,
44 .ih_ring_entry_size = 4 * sizeof(uint32_t), 42 .ih_ring_entry_size = 4 * sizeof(uint32_t),
45 .event_interrupt_class = &event_interrupt_class_cik, 43 .event_interrupt_class = &event_interrupt_class_cik,
46 .num_of_watch_points = 4, 44 .num_of_watch_points = 4,
@@ -55,6 +53,7 @@ static const struct kfd_device_info carrizo_device_info = {
55 .max_pasid_bits = 16, 53 .max_pasid_bits = 16,
56 /* max num of queues for CZ.TODO should be a dynamic value */ 54 /* max num of queues for CZ.TODO should be a dynamic value */
57 .max_no_of_hqd = 24, 55 .max_no_of_hqd = 24,
56 .doorbell_size = 4,
58 .ih_ring_entry_size = 4 * sizeof(uint32_t), 57 .ih_ring_entry_size = 4 * sizeof(uint32_t),
59 .event_interrupt_class = &event_interrupt_class_cik, 58 .event_interrupt_class = &event_interrupt_class_cik,
60 .num_of_watch_points = 4, 59 .num_of_watch_points = 4,
@@ -70,6 +69,7 @@ static const struct kfd_device_info hawaii_device_info = {
70 .max_pasid_bits = 16, 69 .max_pasid_bits = 16,
71 /* max num of queues for KV.TODO should be a dynamic value */ 70 /* max num of queues for KV.TODO should be a dynamic value */
72 .max_no_of_hqd = 24, 71 .max_no_of_hqd = 24,
72 .doorbell_size = 4,
73 .ih_ring_entry_size = 4 * sizeof(uint32_t), 73 .ih_ring_entry_size = 4 * sizeof(uint32_t),
74 .event_interrupt_class = &event_interrupt_class_cik, 74 .event_interrupt_class = &event_interrupt_class_cik,
75 .num_of_watch_points = 4, 75 .num_of_watch_points = 4,
@@ -83,6 +83,7 @@ static const struct kfd_device_info tonga_device_info = {
83 .asic_family = CHIP_TONGA, 83 .asic_family = CHIP_TONGA,
84 .max_pasid_bits = 16, 84 .max_pasid_bits = 16,
85 .max_no_of_hqd = 24, 85 .max_no_of_hqd = 24,
86 .doorbell_size = 4,
86 .ih_ring_entry_size = 4 * sizeof(uint32_t), 87 .ih_ring_entry_size = 4 * sizeof(uint32_t),
87 .event_interrupt_class = &event_interrupt_class_cik, 88 .event_interrupt_class = &event_interrupt_class_cik,
88 .num_of_watch_points = 4, 89 .num_of_watch_points = 4,
@@ -96,6 +97,7 @@ static const struct kfd_device_info tonga_vf_device_info = {
96 .asic_family = CHIP_TONGA, 97 .asic_family = CHIP_TONGA,
97 .max_pasid_bits = 16, 98 .max_pasid_bits = 16,
98 .max_no_of_hqd = 24, 99 .max_no_of_hqd = 24,
100 .doorbell_size = 4,
99 .ih_ring_entry_size = 4 * sizeof(uint32_t), 101 .ih_ring_entry_size = 4 * sizeof(uint32_t),
100 .event_interrupt_class = &event_interrupt_class_cik, 102 .event_interrupt_class = &event_interrupt_class_cik,
101 .num_of_watch_points = 4, 103 .num_of_watch_points = 4,
@@ -109,6 +111,7 @@ static const struct kfd_device_info fiji_device_info = {
109 .asic_family = CHIP_FIJI, 111 .asic_family = CHIP_FIJI,
110 .max_pasid_bits = 16, 112 .max_pasid_bits = 16,
111 .max_no_of_hqd = 24, 113 .max_no_of_hqd = 24,
114 .doorbell_size = 4,
112 .ih_ring_entry_size = 4 * sizeof(uint32_t), 115 .ih_ring_entry_size = 4 * sizeof(uint32_t),
113 .event_interrupt_class = &event_interrupt_class_cik, 116 .event_interrupt_class = &event_interrupt_class_cik,
114 .num_of_watch_points = 4, 117 .num_of_watch_points = 4,
@@ -122,6 +125,7 @@ static const struct kfd_device_info fiji_vf_device_info = {
122 .asic_family = CHIP_FIJI, 125 .asic_family = CHIP_FIJI,
123 .max_pasid_bits = 16, 126 .max_pasid_bits = 16,
124 .max_no_of_hqd = 24, 127 .max_no_of_hqd = 24,
128 .doorbell_size = 4,
125 .ih_ring_entry_size = 4 * sizeof(uint32_t), 129 .ih_ring_entry_size = 4 * sizeof(uint32_t),
126 .event_interrupt_class = &event_interrupt_class_cik, 130 .event_interrupt_class = &event_interrupt_class_cik,
127 .num_of_watch_points = 4, 131 .num_of_watch_points = 4,
@@ -136,6 +140,7 @@ static const struct kfd_device_info polaris10_device_info = {
136 .asic_family = CHIP_POLARIS10, 140 .asic_family = CHIP_POLARIS10,
137 .max_pasid_bits = 16, 141 .max_pasid_bits = 16,
138 .max_no_of_hqd = 24, 142 .max_no_of_hqd = 24,
143 .doorbell_size = 4,
139 .ih_ring_entry_size = 4 * sizeof(uint32_t), 144 .ih_ring_entry_size = 4 * sizeof(uint32_t),
140 .event_interrupt_class = &event_interrupt_class_cik, 145 .event_interrupt_class = &event_interrupt_class_cik,
141 .num_of_watch_points = 4, 146 .num_of_watch_points = 4,
@@ -149,6 +154,7 @@ static const struct kfd_device_info polaris10_vf_device_info = {
149 .asic_family = CHIP_POLARIS10, 154 .asic_family = CHIP_POLARIS10,
150 .max_pasid_bits = 16, 155 .max_pasid_bits = 16,
151 .max_no_of_hqd = 24, 156 .max_no_of_hqd = 24,
157 .doorbell_size = 4,
152 .ih_ring_entry_size = 4 * sizeof(uint32_t), 158 .ih_ring_entry_size = 4 * sizeof(uint32_t),
153 .event_interrupt_class = &event_interrupt_class_cik, 159 .event_interrupt_class = &event_interrupt_class_cik,
154 .num_of_watch_points = 4, 160 .num_of_watch_points = 4,
@@ -162,6 +168,7 @@ static const struct kfd_device_info polaris11_device_info = {
162 .asic_family = CHIP_POLARIS11, 168 .asic_family = CHIP_POLARIS11,
163 .max_pasid_bits = 16, 169 .max_pasid_bits = 16,
164 .max_no_of_hqd = 24, 170 .max_no_of_hqd = 24,
171 .doorbell_size = 4,
165 .ih_ring_entry_size = 4 * sizeof(uint32_t), 172 .ih_ring_entry_size = 4 * sizeof(uint32_t),
166 .event_interrupt_class = &event_interrupt_class_cik, 173 .event_interrupt_class = &event_interrupt_class_cik,
167 .num_of_watch_points = 4, 174 .num_of_watch_points = 4,
@@ -171,6 +178,34 @@ static const struct kfd_device_info polaris11_device_info = {
171 .needs_pci_atomics = true, 178 .needs_pci_atomics = true,
172}; 179};
173 180
181static const struct kfd_device_info vega10_device_info = {
182 .asic_family = CHIP_VEGA10,
183 .max_pasid_bits = 16,
184 .max_no_of_hqd = 24,
185 .doorbell_size = 8,
186 .ih_ring_entry_size = 8 * sizeof(uint32_t),
187 .event_interrupt_class = &event_interrupt_class_v9,
188 .num_of_watch_points = 4,
189 .mqd_size_aligned = MQD_SIZE_ALIGNED,
190 .supports_cwsr = true,
191 .needs_iommu_device = false,
192 .needs_pci_atomics = false,
193};
194
195static const struct kfd_device_info vega10_vf_device_info = {
196 .asic_family = CHIP_VEGA10,
197 .max_pasid_bits = 16,
198 .max_no_of_hqd = 24,
199 .doorbell_size = 8,
200 .ih_ring_entry_size = 8 * sizeof(uint32_t),
201 .event_interrupt_class = &event_interrupt_class_v9,
202 .num_of_watch_points = 4,
203 .mqd_size_aligned = MQD_SIZE_ALIGNED,
204 .supports_cwsr = true,
205 .needs_iommu_device = false,
206 .needs_pci_atomics = false,
207};
208
174 209
175struct kfd_deviceid { 210struct kfd_deviceid {
176 unsigned short did; 211 unsigned short did;
@@ -250,6 +285,15 @@ static const struct kfd_deviceid supported_devices[] = {
250 { 0x67EB, &polaris11_device_info }, /* Polaris11 */ 285 { 0x67EB, &polaris11_device_info }, /* Polaris11 */
251 { 0x67EF, &polaris11_device_info }, /* Polaris11 */ 286 { 0x67EF, &polaris11_device_info }, /* Polaris11 */
252 { 0x67FF, &polaris11_device_info }, /* Polaris11 */ 287 { 0x67FF, &polaris11_device_info }, /* Polaris11 */
288 { 0x6860, &vega10_device_info }, /* Vega10 */
289 { 0x6861, &vega10_device_info }, /* Vega10 */
290 { 0x6862, &vega10_device_info }, /* Vega10 */
291 { 0x6863, &vega10_device_info }, /* Vega10 */
292 { 0x6864, &vega10_device_info }, /* Vega10 */
293 { 0x6867, &vega10_device_info }, /* Vega10 */
294 { 0x6868, &vega10_device_info }, /* Vega10 */
295 { 0x686C, &vega10_vf_device_info }, /* Vega10 vf*/
296 { 0x687F, &vega10_device_info }, /* Vega10 */
253}; 297};
254 298
255static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size, 299static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size,
@@ -279,7 +323,7 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
279 struct pci_dev *pdev, const struct kfd2kgd_calls *f2g) 323 struct pci_dev *pdev, const struct kfd2kgd_calls *f2g)
280{ 324{
281 struct kfd_dev *kfd; 325 struct kfd_dev *kfd;
282 326 int ret;
283 const struct kfd_device_info *device_info = 327 const struct kfd_device_info *device_info =
284 lookup_device_info(pdev->device); 328 lookup_device_info(pdev->device);
285 329
@@ -288,19 +332,18 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
288 return NULL; 332 return NULL;
289 } 333 }
290 334
291 if (device_info->needs_pci_atomics) { 335 /* Allow BIF to recode atomics to PCIe 3.0 AtomicOps.
292 /* Allow BIF to recode atomics to PCIe 3.0 336 * 32 and 64-bit requests are possible and must be
293 * AtomicOps. 32 and 64-bit requests are possible and 337 * supported.
294 * must be supported. 338 */
295 */ 339 ret = pci_enable_atomic_ops_to_root(pdev,
296 if (pci_enable_atomic_ops_to_root(pdev, 340 PCI_EXP_DEVCAP2_ATOMIC_COMP32 |
297 PCI_EXP_DEVCAP2_ATOMIC_COMP32 | 341 PCI_EXP_DEVCAP2_ATOMIC_COMP64);
298 PCI_EXP_DEVCAP2_ATOMIC_COMP64) < 0) { 342 if (device_info->needs_pci_atomics && ret < 0) {
299 dev_info(kfd_device, 343 dev_info(kfd_device,
300 "skipped device %x:%x, PCI rejects atomics", 344 "skipped device %x:%x, PCI rejects atomics\n",
301 pdev->vendor, pdev->device); 345 pdev->vendor, pdev->device);
302 return NULL; 346 return NULL;
303 }
304 } 347 }
305 348
306 kfd = kzalloc(sizeof(*kfd), GFP_KERNEL); 349 kfd = kzalloc(sizeof(*kfd), GFP_KERNEL);
@@ -323,10 +366,16 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
323static void kfd_cwsr_init(struct kfd_dev *kfd) 366static void kfd_cwsr_init(struct kfd_dev *kfd)
324{ 367{
325 if (cwsr_enable && kfd->device_info->supports_cwsr) { 368 if (cwsr_enable && kfd->device_info->supports_cwsr) {
326 BUILD_BUG_ON(sizeof(cwsr_trap_gfx8_hex) > PAGE_SIZE); 369 if (kfd->device_info->asic_family < CHIP_VEGA10) {
370 BUILD_BUG_ON(sizeof(cwsr_trap_gfx8_hex) > PAGE_SIZE);
371 kfd->cwsr_isa = cwsr_trap_gfx8_hex;
372 kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx8_hex);
373 } else {
374 BUILD_BUG_ON(sizeof(cwsr_trap_gfx9_hex) > PAGE_SIZE);
375 kfd->cwsr_isa = cwsr_trap_gfx9_hex;
376 kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx9_hex);
377 }
327 378
328 kfd->cwsr_isa = cwsr_trap_gfx8_hex;
329 kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx8_hex);
330 kfd->cwsr_enabled = true; 379 kfd->cwsr_enabled = true;
331 } 380 }
332} 381}
@@ -541,6 +590,44 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry)
541 spin_unlock(&kfd->interrupt_lock); 590 spin_unlock(&kfd->interrupt_lock);
542} 591}
543 592
593int kgd2kfd_quiesce_mm(struct mm_struct *mm)
594{
595 struct kfd_process *p;
596 int r;
597
598 /* Because we are called from arbitrary context (workqueue) as opposed
599 * to process context, kfd_process could attempt to exit while we are
600 * running so the lookup function increments the process ref count.
601 */
602 p = kfd_lookup_process_by_mm(mm);
603 if (!p)
604 return -ESRCH;
605
606 r = kfd_process_evict_queues(p);
607
608 kfd_unref_process(p);
609 return r;
610}
611
612int kgd2kfd_resume_mm(struct mm_struct *mm)
613{
614 struct kfd_process *p;
615 int r;
616
617 /* Because we are called from arbitrary context (workqueue) as opposed
618 * to process context, kfd_process could attempt to exit while we are
619 * running so the lookup function increments the process ref count.
620 */
621 p = kfd_lookup_process_by_mm(mm);
622 if (!p)
623 return -ESRCH;
624
625 r = kfd_process_restore_queues(p);
626
627 kfd_unref_process(p);
628 return r;
629}
630
544/** kgd2kfd_schedule_evict_and_restore_process - Schedules work queue that will 631/** kgd2kfd_schedule_evict_and_restore_process - Schedules work queue that will
545 * prepare for safe eviction of KFD BOs that belong to the specified 632 * prepare for safe eviction of KFD BOs that belong to the specified
546 * process. 633 * process.
@@ -652,7 +739,7 @@ int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
652 if (size > kfd->gtt_sa_num_of_chunks * kfd->gtt_sa_chunk_size) 739 if (size > kfd->gtt_sa_num_of_chunks * kfd->gtt_sa_chunk_size)
653 return -ENOMEM; 740 return -ENOMEM;
654 741
655 *mem_obj = kmalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); 742 *mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_NOIO);
656 if ((*mem_obj) == NULL) 743 if ((*mem_obj) == NULL)
657 return -ENOMEM; 744 return -ENOMEM;
658 745
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index d55d29d31da4..668ad07ebe1f 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -110,6 +110,57 @@ void program_sh_mem_settings(struct device_queue_manager *dqm,
110 qpd->sh_mem_bases); 110 qpd->sh_mem_bases);
111} 111}
112 112
113static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q)
114{
115 struct kfd_dev *dev = qpd->dqm->dev;
116
117 if (!KFD_IS_SOC15(dev->device_info->asic_family)) {
118 /* On pre-SOC15 chips we need to use the queue ID to
119 * preserve the user mode ABI.
120 */
121 q->doorbell_id = q->properties.queue_id;
122 } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
123 /* For SDMA queues on SOC15, use static doorbell
124 * assignments based on the engine and queue.
125 */
126 q->doorbell_id = dev->shared_resources.sdma_doorbell
127 [q->properties.sdma_engine_id]
128 [q->properties.sdma_queue_id];
129 } else {
130 /* For CP queues on SOC15 reserve a free doorbell ID */
131 unsigned int found;
132
133 found = find_first_zero_bit(qpd->doorbell_bitmap,
134 KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
135 if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
136 pr_debug("No doorbells available");
137 return -EBUSY;
138 }
139 set_bit(found, qpd->doorbell_bitmap);
140 q->doorbell_id = found;
141 }
142
143 q->properties.doorbell_off =
144 kfd_doorbell_id_to_offset(dev, q->process,
145 q->doorbell_id);
146
147 return 0;
148}
149
150static void deallocate_doorbell(struct qcm_process_device *qpd,
151 struct queue *q)
152{
153 unsigned int old;
154 struct kfd_dev *dev = qpd->dqm->dev;
155
156 if (!KFD_IS_SOC15(dev->device_info->asic_family) ||
157 q->properties.type == KFD_QUEUE_TYPE_SDMA)
158 return;
159
160 old = test_and_clear_bit(q->doorbell_id, qpd->doorbell_bitmap);
161 WARN_ON(!old);
162}
163
113static int allocate_vmid(struct device_queue_manager *dqm, 164static int allocate_vmid(struct device_queue_manager *dqm,
114 struct qcm_process_device *qpd, 165 struct qcm_process_device *qpd,
115 struct queue *q) 166 struct queue *q)
@@ -145,15 +196,19 @@ static int allocate_vmid(struct device_queue_manager *dqm,
145static int flush_texture_cache_nocpsch(struct kfd_dev *kdev, 196static int flush_texture_cache_nocpsch(struct kfd_dev *kdev,
146 struct qcm_process_device *qpd) 197 struct qcm_process_device *qpd)
147{ 198{
148 uint32_t len; 199 const struct packet_manager_funcs *pmf = qpd->dqm->packets.pmf;
200 int ret;
149 201
150 if (!qpd->ib_kaddr) 202 if (!qpd->ib_kaddr)
151 return -ENOMEM; 203 return -ENOMEM;
152 204
153 len = pm_create_release_mem(qpd->ib_base, (uint32_t *)qpd->ib_kaddr); 205 ret = pmf->release_mem(qpd->ib_base, (uint32_t *)qpd->ib_kaddr);
206 if (ret)
207 return ret;
154 208
155 return kdev->kfd2kgd->submit_ib(kdev->kgd, KGD_ENGINE_MEC1, qpd->vmid, 209 return kdev->kfd2kgd->submit_ib(kdev->kgd, KGD_ENGINE_MEC1, qpd->vmid,
156 qpd->ib_base, (uint32_t *)qpd->ib_kaddr, len); 210 qpd->ib_base, (uint32_t *)qpd->ib_kaddr,
211 pmf->release_mem_size / sizeof(uint32_t));
157} 212}
158 213
159static void deallocate_vmid(struct device_queue_manager *dqm, 214static void deallocate_vmid(struct device_queue_manager *dqm,
@@ -301,10 +356,14 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
301 if (retval) 356 if (retval)
302 return retval; 357 return retval;
303 358
359 retval = allocate_doorbell(qpd, q);
360 if (retval)
361 goto out_deallocate_hqd;
362
304 retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, 363 retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
305 &q->gart_mqd_addr, &q->properties); 364 &q->gart_mqd_addr, &q->properties);
306 if (retval) 365 if (retval)
307 goto out_deallocate_hqd; 366 goto out_deallocate_doorbell;
308 367
309 pr_debug("Loading mqd to hqd on pipe %d, queue %d\n", 368 pr_debug("Loading mqd to hqd on pipe %d, queue %d\n",
310 q->pipe, q->queue); 369 q->pipe, q->queue);
@@ -324,6 +383,8 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
324 383
325out_uninit_mqd: 384out_uninit_mqd:
326 mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); 385 mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
386out_deallocate_doorbell:
387 deallocate_doorbell(qpd, q);
327out_deallocate_hqd: 388out_deallocate_hqd:
328 deallocate_hqd(dqm, q); 389 deallocate_hqd(dqm, q);
329 390
@@ -357,6 +418,8 @@ static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm,
357 } 418 }
358 dqm->total_queue_count--; 419 dqm->total_queue_count--;
359 420
421 deallocate_doorbell(qpd, q);
422
360 retval = mqd->destroy_mqd(mqd, q->mqd, 423 retval = mqd->destroy_mqd(mqd, q->mqd,
361 KFD_PREEMPT_TYPE_WAVEFRONT_RESET, 424 KFD_PREEMPT_TYPE_WAVEFRONT_RESET,
362 KFD_UNMAP_LATENCY_MS, 425 KFD_UNMAP_LATENCY_MS,
@@ -861,6 +924,10 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
861 q->properties.sdma_queue_id = q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE; 924 q->properties.sdma_queue_id = q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE;
862 q->properties.sdma_engine_id = q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE; 925 q->properties.sdma_engine_id = q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE;
863 926
927 retval = allocate_doorbell(qpd, q);
928 if (retval)
929 goto out_deallocate_sdma_queue;
930
864 pr_debug("SDMA id is: %d\n", q->sdma_id); 931 pr_debug("SDMA id is: %d\n", q->sdma_id);
865 pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id); 932 pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id);
866 pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id); 933 pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id);
@@ -869,7 +936,7 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
869 retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, 936 retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
870 &q->gart_mqd_addr, &q->properties); 937 &q->gart_mqd_addr, &q->properties);
871 if (retval) 938 if (retval)
872 goto out_deallocate_sdma_queue; 939 goto out_deallocate_doorbell;
873 940
874 retval = mqd->load_mqd(mqd, q->mqd, 0, 0, &q->properties, NULL); 941 retval = mqd->load_mqd(mqd, q->mqd, 0, 0, &q->properties, NULL);
875 if (retval) 942 if (retval)
@@ -879,6 +946,8 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
879 946
880out_uninit_mqd: 947out_uninit_mqd:
881 mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); 948 mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
949out_deallocate_doorbell:
950 deallocate_doorbell(qpd, q);
882out_deallocate_sdma_queue: 951out_deallocate_sdma_queue:
883 deallocate_sdma_queue(dqm, q->sdma_id); 952 deallocate_sdma_queue(dqm, q->sdma_id);
884 953
@@ -1070,12 +1139,17 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
1070 q->properties.sdma_engine_id = 1139 q->properties.sdma_engine_id =
1071 q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE; 1140 q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE;
1072 } 1141 }
1142
1143 retval = allocate_doorbell(qpd, q);
1144 if (retval)
1145 goto out_deallocate_sdma_queue;
1146
1073 mqd = dqm->ops.get_mqd_manager(dqm, 1147 mqd = dqm->ops.get_mqd_manager(dqm,
1074 get_mqd_type_from_queue_type(q->properties.type)); 1148 get_mqd_type_from_queue_type(q->properties.type));
1075 1149
1076 if (!mqd) { 1150 if (!mqd) {
1077 retval = -ENOMEM; 1151 retval = -ENOMEM;
1078 goto out_deallocate_sdma_queue; 1152 goto out_deallocate_doorbell;
1079 } 1153 }
1080 /* 1154 /*
1081 * Eviction state logic: we only mark active queues as evicted 1155 * Eviction state logic: we only mark active queues as evicted
@@ -1093,7 +1167,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
1093 retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, 1167 retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
1094 &q->gart_mqd_addr, &q->properties); 1168 &q->gart_mqd_addr, &q->properties);
1095 if (retval) 1169 if (retval)
1096 goto out_deallocate_sdma_queue; 1170 goto out_deallocate_doorbell;
1097 1171
1098 list_add(&q->list, &qpd->queues_list); 1172 list_add(&q->list, &qpd->queues_list);
1099 qpd->queue_count++; 1173 qpd->queue_count++;
@@ -1117,6 +1191,8 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
1117 mutex_unlock(&dqm->lock); 1191 mutex_unlock(&dqm->lock);
1118 return retval; 1192 return retval;
1119 1193
1194out_deallocate_doorbell:
1195 deallocate_doorbell(qpd, q);
1120out_deallocate_sdma_queue: 1196out_deallocate_sdma_queue:
1121 if (q->properties.type == KFD_QUEUE_TYPE_SDMA) 1197 if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
1122 deallocate_sdma_queue(dqm, q->sdma_id); 1198 deallocate_sdma_queue(dqm, q->sdma_id);
@@ -1257,6 +1333,8 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
1257 goto failed; 1333 goto failed;
1258 } 1334 }
1259 1335
1336 deallocate_doorbell(qpd, q);
1337
1260 if (q->properties.type == KFD_QUEUE_TYPE_SDMA) { 1338 if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
1261 dqm->sdma_queue_count--; 1339 dqm->sdma_queue_count--;
1262 deallocate_sdma_queue(dqm, q->sdma_id); 1340 deallocate_sdma_queue(dqm, q->sdma_id);
@@ -1308,7 +1386,10 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
1308 void __user *alternate_aperture_base, 1386 void __user *alternate_aperture_base,
1309 uint64_t alternate_aperture_size) 1387 uint64_t alternate_aperture_size)
1310{ 1388{
1311 bool retval; 1389 bool retval = true;
1390
1391 if (!dqm->asic_ops.set_cache_memory_policy)
1392 return retval;
1312 1393
1313 mutex_lock(&dqm->lock); 1394 mutex_lock(&dqm->lock);
1314 1395
@@ -1577,6 +1658,11 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
1577 case CHIP_POLARIS11: 1658 case CHIP_POLARIS11:
1578 device_queue_manager_init_vi_tonga(&dqm->asic_ops); 1659 device_queue_manager_init_vi_tonga(&dqm->asic_ops);
1579 break; 1660 break;
1661
1662 case CHIP_VEGA10:
1663 case CHIP_RAVEN:
1664 device_queue_manager_init_v9(&dqm->asic_ops);
1665 break;
1580 default: 1666 default:
1581 WARN(1, "Unexpected ASIC family %u", 1667 WARN(1, "Unexpected ASIC family %u",
1582 dev->device_info->asic_family); 1668 dev->device_info->asic_family);
@@ -1627,6 +1713,18 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)
1627 int pipe, queue; 1713 int pipe, queue;
1628 int r = 0; 1714 int r = 0;
1629 1715
1716 r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->kgd,
1717 KFD_CIK_HIQ_PIPE, KFD_CIK_HIQ_QUEUE, &dump, &n_regs);
1718 if (!r) {
1719 seq_printf(m, " HIQ on MEC %d Pipe %d Queue %d\n",
1720 KFD_CIK_HIQ_PIPE/get_pipes_per_mec(dqm)+1,
1721 KFD_CIK_HIQ_PIPE%get_pipes_per_mec(dqm),
1722 KFD_CIK_HIQ_QUEUE);
1723 seq_reg_dump(m, dump, n_regs);
1724
1725 kfree(dump);
1726 }
1727
1630 for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) { 1728 for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) {
1631 int pipe_offset = pipe * get_queues_per_pipe(dqm); 1729 int pipe_offset = pipe * get_queues_per_pipe(dqm);
1632 1730
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index 412beff3281d..59a6b1956932 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -200,6 +200,8 @@ void device_queue_manager_init_vi(
200 struct device_queue_manager_asic_ops *asic_ops); 200 struct device_queue_manager_asic_ops *asic_ops);
201void device_queue_manager_init_vi_tonga( 201void device_queue_manager_init_vi_tonga(
202 struct device_queue_manager_asic_ops *asic_ops); 202 struct device_queue_manager_asic_ops *asic_ops);
203void device_queue_manager_init_v9(
204 struct device_queue_manager_asic_ops *asic_ops);
203void program_sh_mem_settings(struct device_queue_manager *dqm, 205void program_sh_mem_settings(struct device_queue_manager *dqm,
204 struct qcm_process_device *qpd); 206 struct qcm_process_device *qpd);
205unsigned int get_queues_num(struct device_queue_manager *dqm); 207unsigned int get_queues_num(struct device_queue_manager *dqm);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c
new file mode 100644
index 000000000000..79e5bcf6367c
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c
@@ -0,0 +1,84 @@
1/*
2 * Copyright 2016-2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "kfd_device_queue_manager.h"
25#include "vega10_enum.h"
26#include "gc/gc_9_0_offset.h"
27#include "gc/gc_9_0_sh_mask.h"
28#include "sdma0/sdma0_4_0_sh_mask.h"
29
30static int update_qpd_v9(struct device_queue_manager *dqm,
31 struct qcm_process_device *qpd);
32static void init_sdma_vm_v9(struct device_queue_manager *dqm, struct queue *q,
33 struct qcm_process_device *qpd);
34
35void device_queue_manager_init_v9(
36 struct device_queue_manager_asic_ops *asic_ops)
37{
38 asic_ops->update_qpd = update_qpd_v9;
39 asic_ops->init_sdma_vm = init_sdma_vm_v9;
40}
41
42static uint32_t compute_sh_mem_bases_64bit(struct kfd_process_device *pdd)
43{
44 uint32_t shared_base = pdd->lds_base >> 48;
45 uint32_t private_base = pdd->scratch_base >> 48;
46
47 return (shared_base << SH_MEM_BASES__SHARED_BASE__SHIFT) |
48 private_base;
49}
50
51static int update_qpd_v9(struct device_queue_manager *dqm,
52 struct qcm_process_device *qpd)
53{
54 struct kfd_process_device *pdd;
55
56 pdd = qpd_to_pdd(qpd);
57
58 /* check if sh_mem_config register already configured */
59 if (qpd->sh_mem_config == 0) {
60 qpd->sh_mem_config =
61 SH_MEM_ALIGNMENT_MODE_UNALIGNED <<
62 SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT;
63 if (vega10_noretry &&
64 !dqm->dev->device_info->needs_iommu_device)
65 qpd->sh_mem_config |=
66 1 << SH_MEM_CONFIG__RETRY_DISABLE__SHIFT;
67
68 qpd->sh_mem_ape1_limit = 0;
69 qpd->sh_mem_ape1_base = 0;
70 }
71
72 qpd->sh_mem_bases = compute_sh_mem_bases_64bit(pdd);
73
74 pr_debug("sh_mem_bases 0x%X\n", qpd->sh_mem_bases);
75
76 return 0;
77}
78
79static void init_sdma_vm_v9(struct device_queue_manager *dqm, struct queue *q,
80 struct qcm_process_device *qpd)
81{
82 /* Not needed on SDMAv4 any more */
83 q->properties.sdma_vm_addr = 0;
84}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index ebb4da14e3df..c3744d89352c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -33,7 +33,6 @@
33 33
34static DEFINE_IDA(doorbell_ida); 34static DEFINE_IDA(doorbell_ida);
35static unsigned int max_doorbell_slices; 35static unsigned int max_doorbell_slices;
36#define KFD_SIZE_OF_DOORBELL_IN_BYTES 4
37 36
38/* 37/*
39 * Each device exposes a doorbell aperture, a PCI MMIO aperture that 38 * Each device exposes a doorbell aperture, a PCI MMIO aperture that
@@ -50,9 +49,9 @@ static unsigned int max_doorbell_slices;
50 */ 49 */
51 50
52/* # of doorbell bytes allocated for each process. */ 51/* # of doorbell bytes allocated for each process. */
53static inline size_t doorbell_process_allocation(void) 52size_t kfd_doorbell_process_slice(struct kfd_dev *kfd)
54{ 53{
55 return roundup(KFD_SIZE_OF_DOORBELL_IN_BYTES * 54 return roundup(kfd->device_info->doorbell_size *
56 KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, 55 KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
57 PAGE_SIZE); 56 PAGE_SIZE);
58} 57}
@@ -72,16 +71,16 @@ int kfd_doorbell_init(struct kfd_dev *kfd)
72 71
73 doorbell_start_offset = 72 doorbell_start_offset =
74 roundup(kfd->shared_resources.doorbell_start_offset, 73 roundup(kfd->shared_resources.doorbell_start_offset,
75 doorbell_process_allocation()); 74 kfd_doorbell_process_slice(kfd));
76 75
77 doorbell_aperture_size = 76 doorbell_aperture_size =
78 rounddown(kfd->shared_resources.doorbell_aperture_size, 77 rounddown(kfd->shared_resources.doorbell_aperture_size,
79 doorbell_process_allocation()); 78 kfd_doorbell_process_slice(kfd));
80 79
81 if (doorbell_aperture_size > doorbell_start_offset) 80 if (doorbell_aperture_size > doorbell_start_offset)
82 doorbell_process_limit = 81 doorbell_process_limit =
83 (doorbell_aperture_size - doorbell_start_offset) / 82 (doorbell_aperture_size - doorbell_start_offset) /
84 doorbell_process_allocation(); 83 kfd_doorbell_process_slice(kfd);
85 else 84 else
86 return -ENOSPC; 85 return -ENOSPC;
87 86
@@ -95,7 +94,7 @@ int kfd_doorbell_init(struct kfd_dev *kfd)
95 kfd->doorbell_id_offset = doorbell_start_offset / sizeof(u32); 94 kfd->doorbell_id_offset = doorbell_start_offset / sizeof(u32);
96 95
97 kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base, 96 kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
98 doorbell_process_allocation()); 97 kfd_doorbell_process_slice(kfd));
99 98
100 if (!kfd->doorbell_kernel_ptr) 99 if (!kfd->doorbell_kernel_ptr)
101 return -ENOMEM; 100 return -ENOMEM;
@@ -127,21 +126,16 @@ void kfd_doorbell_fini(struct kfd_dev *kfd)
127 iounmap(kfd->doorbell_kernel_ptr); 126 iounmap(kfd->doorbell_kernel_ptr);
128} 127}
129 128
130int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma) 129int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process,
130 struct vm_area_struct *vma)
131{ 131{
132 phys_addr_t address; 132 phys_addr_t address;
133 struct kfd_dev *dev;
134 133
135 /* 134 /*
136 * For simplicitly we only allow mapping of the entire doorbell 135 * For simplicitly we only allow mapping of the entire doorbell
137 * allocation of a single device & process. 136 * allocation of a single device & process.
138 */ 137 */
139 if (vma->vm_end - vma->vm_start != doorbell_process_allocation()) 138 if (vma->vm_end - vma->vm_start != kfd_doorbell_process_slice(dev))
140 return -EINVAL;
141
142 /* Find kfd device according to gpu id */
143 dev = kfd_device_by_id(vma->vm_pgoff);
144 if (!dev)
145 return -EINVAL; 139 return -EINVAL;
146 140
147 /* Calculate physical address of doorbell */ 141 /* Calculate physical address of doorbell */
@@ -158,19 +152,19 @@ int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
158 " vm_flags == 0x%04lX\n" 152 " vm_flags == 0x%04lX\n"
159 " size == 0x%04lX\n", 153 " size == 0x%04lX\n",
160 (unsigned long long) vma->vm_start, address, vma->vm_flags, 154 (unsigned long long) vma->vm_start, address, vma->vm_flags,
161 doorbell_process_allocation()); 155 kfd_doorbell_process_slice(dev));
162 156
163 157
164 return io_remap_pfn_range(vma, 158 return io_remap_pfn_range(vma,
165 vma->vm_start, 159 vma->vm_start,
166 address >> PAGE_SHIFT, 160 address >> PAGE_SHIFT,
167 doorbell_process_allocation(), 161 kfd_doorbell_process_slice(dev),
168 vma->vm_page_prot); 162 vma->vm_page_prot);
169} 163}
170 164
171 165
172/* get kernel iomem pointer for a doorbell */ 166/* get kernel iomem pointer for a doorbell */
173u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd, 167void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
174 unsigned int *doorbell_off) 168 unsigned int *doorbell_off)
175{ 169{
176 u32 inx; 170 u32 inx;
@@ -185,6 +179,8 @@ u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
185 if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) 179 if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
186 return NULL; 180 return NULL;
187 181
182 inx *= kfd->device_info->doorbell_size / sizeof(u32);
183
188 /* 184 /*
189 * Calculating the kernel doorbell offset using the first 185 * Calculating the kernel doorbell offset using the first
190 * doorbell page. 186 * doorbell page.
@@ -210,7 +206,7 @@ void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr)
210 mutex_unlock(&kfd->doorbell_mutex); 206 mutex_unlock(&kfd->doorbell_mutex);
211} 207}
212 208
213inline void write_kernel_doorbell(u32 __iomem *db, u32 value) 209void write_kernel_doorbell(void __iomem *db, u32 value)
214{ 210{
215 if (db) { 211 if (db) {
216 writel(value, db); 212 writel(value, db);
@@ -218,30 +214,37 @@ inline void write_kernel_doorbell(u32 __iomem *db, u32 value)
218 } 214 }
219} 215}
220 216
221/* 217void write_kernel_doorbell64(void __iomem *db, u64 value)
222 * queue_ids are in the range [0,MAX_PROCESS_QUEUES) and are mapped 1:1 218{
223 * to doorbells with the process's doorbell page 219 if (db) {
224 */ 220 WARN(((unsigned long)db & 7) != 0,
225unsigned int kfd_queue_id_to_doorbell(struct kfd_dev *kfd, 221 "Unaligned 64-bit doorbell");
222 writeq(value, (u64 __iomem *)db);
223 pr_debug("writing %llu to doorbell address %p\n", value, db);
224 }
225}
226
227unsigned int kfd_doorbell_id_to_offset(struct kfd_dev *kfd,
226 struct kfd_process *process, 228 struct kfd_process *process,
227 unsigned int queue_id) 229 unsigned int doorbell_id)
228{ 230{
229 /* 231 /*
230 * doorbell_id_offset accounts for doorbells taken by KGD. 232 * doorbell_id_offset accounts for doorbells taken by KGD.
231 * index * doorbell_process_allocation/sizeof(u32) adjusts to 233 * index * kfd_doorbell_process_slice/sizeof(u32) adjusts to
232 * the process's doorbells. 234 * the process's doorbells. The offset returned is in dword
235 * units regardless of the ASIC-dependent doorbell size.
233 */ 236 */
234 return kfd->doorbell_id_offset + 237 return kfd->doorbell_id_offset +
235 process->doorbell_index 238 process->doorbell_index
236 * doorbell_process_allocation() / sizeof(u32) + 239 * kfd_doorbell_process_slice(kfd) / sizeof(u32) +
237 queue_id; 240 doorbell_id * kfd->device_info->doorbell_size / sizeof(u32);
238} 241}
239 242
240uint64_t kfd_get_number_elems(struct kfd_dev *kfd) 243uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
241{ 244{
242 uint64_t num_of_elems = (kfd->shared_resources.doorbell_aperture_size - 245 uint64_t num_of_elems = (kfd->shared_resources.doorbell_aperture_size -
243 kfd->shared_resources.doorbell_start_offset) / 246 kfd->shared_resources.doorbell_start_offset) /
244 doorbell_process_allocation() + 1; 247 kfd_doorbell_process_slice(kfd) + 1;
245 248
246 return num_of_elems; 249 return num_of_elems;
247 250
@@ -251,7 +254,7 @@ phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev,
251 struct kfd_process *process) 254 struct kfd_process *process)
252{ 255{
253 return dev->doorbell_base + 256 return dev->doorbell_base +
254 process->doorbell_index * doorbell_process_allocation(); 257 process->doorbell_index * kfd_doorbell_process_slice(dev);
255} 258}
256 259
257int kfd_alloc_process_doorbells(struct kfd_process *process) 260int kfd_alloc_process_doorbells(struct kfd_process *process)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index 4890a90f1e44..5562e94e786a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -345,7 +345,7 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p,
345 case KFD_EVENT_TYPE_DEBUG: 345 case KFD_EVENT_TYPE_DEBUG:
346 ret = create_signal_event(devkfd, p, ev); 346 ret = create_signal_event(devkfd, p, ev);
347 if (!ret) { 347 if (!ret) {
348 *event_page_offset = KFD_MMAP_EVENTS_MASK; 348 *event_page_offset = KFD_MMAP_TYPE_EVENTS;
349 *event_page_offset <<= PAGE_SHIFT; 349 *event_page_offset <<= PAGE_SHIFT;
350 *event_slot_index = ev->event_id; 350 *event_slot_index = ev->event_id;
351 } 351 }
@@ -496,7 +496,7 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id,
496 pr_debug_ratelimited("Partial ID invalid: %u (%u valid bits)\n", 496 pr_debug_ratelimited("Partial ID invalid: %u (%u valid bits)\n",
497 partial_id, valid_id_bits); 497 partial_id, valid_id_bits);
498 498
499 if (p->signal_event_count < KFD_SIGNAL_EVENT_LIMIT/2) { 499 if (p->signal_event_count < KFD_SIGNAL_EVENT_LIMIT / 64) {
500 /* With relatively few events, it's faster to 500 /* With relatively few events, it's faster to
501 * iterate over the event IDR 501 * iterate over the event IDR
502 */ 502 */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
index 66852de410c8..97d5423c5673 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
@@ -275,23 +275,35 @@
275 * for FLAT_* / S_LOAD operations. 275 * for FLAT_* / S_LOAD operations.
276 */ 276 */
277 277
278#define MAKE_GPUVM_APP_BASE(gpu_num) \ 278#define MAKE_GPUVM_APP_BASE_VI(gpu_num) \
279 (((uint64_t)(gpu_num) << 61) + 0x1000000000000L) 279 (((uint64_t)(gpu_num) << 61) + 0x1000000000000L)
280 280
281#define MAKE_GPUVM_APP_LIMIT(base, size) \ 281#define MAKE_GPUVM_APP_LIMIT(base, size) \
282 (((uint64_t)(base) & 0xFFFFFF0000000000UL) + (size) - 1) 282 (((uint64_t)(base) & 0xFFFFFF0000000000UL) + (size) - 1)
283 283
284#define MAKE_SCRATCH_APP_BASE() \ 284#define MAKE_SCRATCH_APP_BASE_VI() \
285 (((uint64_t)(0x1UL) << 61) + 0x100000000L) 285 (((uint64_t)(0x1UL) << 61) + 0x100000000L)
286 286
287#define MAKE_SCRATCH_APP_LIMIT(base) \ 287#define MAKE_SCRATCH_APP_LIMIT(base) \
288 (((uint64_t)base & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF) 288 (((uint64_t)base & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF)
289 289
290#define MAKE_LDS_APP_BASE() \ 290#define MAKE_LDS_APP_BASE_VI() \
291 (((uint64_t)(0x1UL) << 61) + 0x0) 291 (((uint64_t)(0x1UL) << 61) + 0x0)
292#define MAKE_LDS_APP_LIMIT(base) \ 292#define MAKE_LDS_APP_LIMIT(base) \
293 (((uint64_t)(base) & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF) 293 (((uint64_t)(base) & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF)
294 294
295/* On GFXv9 the LDS and scratch apertures are programmed independently
296 * using the high 16 bits of the 64-bit virtual address. They must be
297 * in the hole, which will be the case as long as the high 16 bits are
298 * not 0.
299 *
300 * The aperture sizes are still 4GB implicitly.
301 *
302 * A GPUVM aperture is not applicable on GFXv9.
303 */
304#define MAKE_LDS_APP_BASE_V9() ((uint64_t)(0x1UL) << 48)
305#define MAKE_SCRATCH_APP_BASE_V9() ((uint64_t)(0x2UL) << 48)
306
295/* User mode manages most of the SVM aperture address space. The low 307/* User mode manages most of the SVM aperture address space. The low
296 * 16MB are reserved for kernel use (CWSR trap handler and kernel IB 308 * 16MB are reserved for kernel use (CWSR trap handler and kernel IB
297 * for now). 309 * for now).
@@ -300,6 +312,55 @@
300#define SVM_CWSR_BASE (SVM_USER_BASE - KFD_CWSR_TBA_TMA_SIZE) 312#define SVM_CWSR_BASE (SVM_USER_BASE - KFD_CWSR_TBA_TMA_SIZE)
301#define SVM_IB_BASE (SVM_CWSR_BASE - PAGE_SIZE) 313#define SVM_IB_BASE (SVM_CWSR_BASE - PAGE_SIZE)
302 314
315static void kfd_init_apertures_vi(struct kfd_process_device *pdd, uint8_t id)
316{
317 /*
318 * node id couldn't be 0 - the three MSB bits of
319 * aperture shoudn't be 0
320 */
321 pdd->lds_base = MAKE_LDS_APP_BASE_VI();
322 pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base);
323
324 if (!pdd->dev->device_info->needs_iommu_device) {
325 /* dGPUs: SVM aperture starting at 0
326 * with small reserved space for kernel.
327 * Set them to CANONICAL addresses.
328 */
329 pdd->gpuvm_base = SVM_USER_BASE;
330 pdd->gpuvm_limit =
331 pdd->dev->shared_resources.gpuvm_size - 1;
332 } else {
333 /* set them to non CANONICAL addresses, and no SVM is
334 * allocated.
335 */
336 pdd->gpuvm_base = MAKE_GPUVM_APP_BASE_VI(id + 1);
337 pdd->gpuvm_limit = MAKE_GPUVM_APP_LIMIT(pdd->gpuvm_base,
338 pdd->dev->shared_resources.gpuvm_size);
339 }
340
341 pdd->scratch_base = MAKE_SCRATCH_APP_BASE_VI();
342 pdd->scratch_limit = MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base);
343}
344
345static void kfd_init_apertures_v9(struct kfd_process_device *pdd, uint8_t id)
346{
347 pdd->lds_base = MAKE_LDS_APP_BASE_V9();
348 pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base);
349
350 /* Raven needs SVM to support graphic handle, etc. Leave the small
351 * reserved space before SVM on Raven as well, even though we don't
352 * have to.
353 * Set gpuvm_base and gpuvm_limit to CANONICAL addresses so that they
354 * are used in Thunk to reserve SVM.
355 */
356 pdd->gpuvm_base = SVM_USER_BASE;
357 pdd->gpuvm_limit =
358 pdd->dev->shared_resources.gpuvm_size - 1;
359
360 pdd->scratch_base = MAKE_SCRATCH_APP_BASE_V9();
361 pdd->scratch_limit = MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base);
362}
363
303int kfd_init_apertures(struct kfd_process *process) 364int kfd_init_apertures(struct kfd_process *process)
304{ 365{
305 uint8_t id = 0; 366 uint8_t id = 0;
@@ -307,9 +368,7 @@ int kfd_init_apertures(struct kfd_process *process)
307 struct kfd_process_device *pdd; 368 struct kfd_process_device *pdd;
308 369
309 /*Iterating over all devices*/ 370 /*Iterating over all devices*/
310 while (kfd_topology_enum_kfd_devices(id, &dev) == 0 && 371 while (kfd_topology_enum_kfd_devices(id, &dev) == 0) {
311 id < NUM_OF_SUPPORTED_GPUS) {
312
313 if (!dev) { 372 if (!dev) {
314 id++; /* Skip non GPU devices */ 373 id++; /* Skip non GPU devices */
315 continue; 374 continue;
@@ -318,7 +377,7 @@ int kfd_init_apertures(struct kfd_process *process)
318 pdd = kfd_create_process_device_data(dev, process); 377 pdd = kfd_create_process_device_data(dev, process);
319 if (!pdd) { 378 if (!pdd) {
320 pr_err("Failed to create process device data\n"); 379 pr_err("Failed to create process device data\n");
321 return -1; 380 return -ENOMEM;
322 } 381 }
323 /* 382 /*
324 * For 64 bit process apertures will be statically reserved in 383 * For 64 bit process apertures will be statically reserved in
@@ -330,32 +389,30 @@ int kfd_init_apertures(struct kfd_process *process)
330 pdd->gpuvm_base = pdd->gpuvm_limit = 0; 389 pdd->gpuvm_base = pdd->gpuvm_limit = 0;
331 pdd->scratch_base = pdd->scratch_limit = 0; 390 pdd->scratch_base = pdd->scratch_limit = 0;
332 } else { 391 } else {
333 /* Same LDS and scratch apertures can be used 392 switch (dev->device_info->asic_family) {
334 * on all GPUs. This allows using more dGPUs 393 case CHIP_KAVERI:
335 * than placement options for apertures. 394 case CHIP_HAWAII:
336 */ 395 case CHIP_CARRIZO:
337 pdd->lds_base = MAKE_LDS_APP_BASE(); 396 case CHIP_TONGA:
338 pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base); 397 case CHIP_FIJI:
339 398 case CHIP_POLARIS10:
340 pdd->scratch_base = MAKE_SCRATCH_APP_BASE(); 399 case CHIP_POLARIS11:
341 pdd->scratch_limit = 400 kfd_init_apertures_vi(pdd, id);
342 MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base); 401 break;
402 case CHIP_VEGA10:
403 case CHIP_RAVEN:
404 kfd_init_apertures_v9(pdd, id);
405 break;
406 default:
407 WARN(1, "Unexpected ASIC family %u",
408 dev->device_info->asic_family);
409 return -EINVAL;
410 }
343 411
344 if (dev->device_info->needs_iommu_device) { 412 if (!dev->device_info->needs_iommu_device) {
345 /* APUs: GPUVM aperture in 413 /* dGPUs: the reserved space for kernel
346 * non-canonical address space 414 * before SVM
347 */
348 pdd->gpuvm_base = MAKE_GPUVM_APP_BASE(id + 1);
349 pdd->gpuvm_limit = MAKE_GPUVM_APP_LIMIT(
350 pdd->gpuvm_base,
351 dev->shared_resources.gpuvm_size);
352 } else {
353 /* dGPUs: SVM aperture starting at 0
354 * with small reserved space for kernel
355 */ 415 */
356 pdd->gpuvm_base = SVM_USER_BASE;
357 pdd->gpuvm_limit =
358 dev->shared_resources.gpuvm_size - 1;
359 pdd->qpd.cwsr_base = SVM_CWSR_BASE; 416 pdd->qpd.cwsr_base = SVM_CWSR_BASE;
360 pdd->qpd.ib_base = SVM_IB_BASE; 417 pdd->qpd.ib_base = SVM_IB_BASE;
361 } 418 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
new file mode 100644
index 000000000000..37029baa3346
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
@@ -0,0 +1,92 @@
1/*
2 * Copyright 2016-2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#include "kfd_priv.h"
24#include "kfd_events.h"
25#include "soc15_int.h"
26
27
28static bool event_interrupt_isr_v9(struct kfd_dev *dev,
29 const uint32_t *ih_ring_entry)
30{
31 uint16_t source_id, client_id, pasid, vmid;
32 const uint32_t *data = ih_ring_entry;
33
34 /* Only handle interrupts from KFD VMIDs */
35 vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry);
36 if (vmid < dev->vm_info.first_vmid_kfd ||
37 vmid > dev->vm_info.last_vmid_kfd)
38 return 0;
39
40 /* If there is no valid PASID, it's likely a firmware bug */
41 pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry);
42 if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt"))
43 return 0;
44
45 source_id = SOC15_SOURCE_ID_FROM_IH_ENTRY(ih_ring_entry);
46 client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry);
47
48 pr_debug("client id 0x%x, source id %d, pasid 0x%x. raw data:\n",
49 client_id, source_id, pasid);
50 pr_debug("%8X, %8X, %8X, %8X, %8X, %8X, %8X, %8X.\n",
51 data[0], data[1], data[2], data[3],
52 data[4], data[5], data[6], data[7]);
53
54 /* Interrupt types we care about: various signals and faults.
55 * They will be forwarded to a work queue (see below).
56 */
57 return source_id == SOC15_INTSRC_CP_END_OF_PIPE ||
58 source_id == SOC15_INTSRC_SDMA_TRAP ||
59 source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG ||
60 source_id == SOC15_INTSRC_CP_BAD_OPCODE;
61}
62
63static void event_interrupt_wq_v9(struct kfd_dev *dev,
64 const uint32_t *ih_ring_entry)
65{
66 uint16_t source_id, client_id, pasid, vmid;
67 uint32_t context_id;
68
69 source_id = SOC15_SOURCE_ID_FROM_IH_ENTRY(ih_ring_entry);
70 client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry);
71 pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry);
72 vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry);
73 context_id = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry);
74
75 if (source_id == SOC15_INTSRC_CP_END_OF_PIPE)
76 kfd_signal_event_interrupt(pasid, context_id, 32);
77 else if (source_id == SOC15_INTSRC_SDMA_TRAP)
78 kfd_signal_event_interrupt(pasid, context_id & 0xfffffff, 28);
79 else if (source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG)
80 kfd_signal_event_interrupt(pasid, context_id & 0xffffff, 24);
81 else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE)
82 kfd_signal_hw_exception_event(pasid);
83 else if (client_id == SOC15_IH_CLIENTID_VMC ||
84 client_id == SOC15_IH_CLIENTID_UTCL2) {
85 /* TODO */
86 }
87}
88
89const struct kfd_event_interrupt_class event_interrupt_class_v9 = {
90 .interrupt_isr = event_interrupt_isr_v9,
91 .interrupt_wq = event_interrupt_wq_v9,
92};
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
index 035c351f47c5..db6d9336b80d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
@@ -139,10 +139,12 @@ static void interrupt_wq(struct work_struct *work)
139{ 139{
140 struct kfd_dev *dev = container_of(work, struct kfd_dev, 140 struct kfd_dev *dev = container_of(work, struct kfd_dev,
141 interrupt_work); 141 interrupt_work);
142 uint32_t ih_ring_entry[KFD_MAX_RING_ENTRY_SIZE];
142 143
143 uint32_t ih_ring_entry[DIV_ROUND_UP( 144 if (dev->device_info->ih_ring_entry_size > sizeof(ih_ring_entry)) {
144 dev->device_info->ih_ring_entry_size, 145 dev_err_once(kfd_chardev(), "Ring entry too small\n");
145 sizeof(uint32_t))]; 146 return;
147 }
146 148
147 while (dequeue_ih_ring_entry(dev, ih_ring_entry)) 149 while (dequeue_ih_ring_entry(dev, ih_ring_entry))
148 dev->device_info->event_interrupt_class->interrupt_wq(dev, 150 dev->device_info->event_interrupt_class->interrupt_wq(dev,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
index 69f496485331..476951d8c91c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
@@ -99,7 +99,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
99 kq->rptr_kernel = kq->rptr_mem->cpu_ptr; 99 kq->rptr_kernel = kq->rptr_mem->cpu_ptr;
100 kq->rptr_gpu_addr = kq->rptr_mem->gpu_addr; 100 kq->rptr_gpu_addr = kq->rptr_mem->gpu_addr;
101 101
102 retval = kfd_gtt_sa_allocate(dev, sizeof(*kq->wptr_kernel), 102 retval = kfd_gtt_sa_allocate(dev, dev->device_info->doorbell_size,
103 &kq->wptr_mem); 103 &kq->wptr_mem);
104 104
105 if (retval != 0) 105 if (retval != 0)
@@ -208,6 +208,7 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
208 size_t available_size; 208 size_t available_size;
209 size_t queue_size_dwords; 209 size_t queue_size_dwords;
210 uint32_t wptr, rptr; 210 uint32_t wptr, rptr;
211 uint64_t wptr64;
211 unsigned int *queue_address; 212 unsigned int *queue_address;
212 213
213 /* When rptr == wptr, the buffer is empty. 214 /* When rptr == wptr, the buffer is empty.
@@ -216,7 +217,8 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
216 * the opposite. So we can only use up to queue_size_dwords - 1 dwords. 217 * the opposite. So we can only use up to queue_size_dwords - 1 dwords.
217 */ 218 */
218 rptr = *kq->rptr_kernel; 219 rptr = *kq->rptr_kernel;
219 wptr = *kq->wptr_kernel; 220 wptr = kq->pending_wptr;
221 wptr64 = kq->pending_wptr64;
220 queue_address = (unsigned int *)kq->pq_kernel_addr; 222 queue_address = (unsigned int *)kq->pq_kernel_addr;
221 queue_size_dwords = kq->queue->properties.queue_size / 4; 223 queue_size_dwords = kq->queue->properties.queue_size / 4;
222 224
@@ -232,29 +234,33 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
232 * make sure calling functions know 234 * make sure calling functions know
233 * acquire_packet_buffer() failed 235 * acquire_packet_buffer() failed
234 */ 236 */
235 *buffer_ptr = NULL; 237 goto err_no_space;
236 return -ENOMEM;
237 } 238 }
238 239
239 if (wptr + packet_size_in_dwords >= queue_size_dwords) { 240 if (wptr + packet_size_in_dwords >= queue_size_dwords) {
240 /* make sure after rolling back to position 0, there is 241 /* make sure after rolling back to position 0, there is
241 * still enough space. 242 * still enough space.
242 */ 243 */
243 if (packet_size_in_dwords >= rptr) { 244 if (packet_size_in_dwords >= rptr)
244 *buffer_ptr = NULL; 245 goto err_no_space;
245 return -ENOMEM; 246
246 }
247 /* fill nops, roll back and start at position 0 */ 247 /* fill nops, roll back and start at position 0 */
248 while (wptr > 0) { 248 while (wptr > 0) {
249 queue_address[wptr] = kq->nop_packet; 249 queue_address[wptr] = kq->nop_packet;
250 wptr = (wptr + 1) % queue_size_dwords; 250 wptr = (wptr + 1) % queue_size_dwords;
251 wptr64++;
251 } 252 }
252 } 253 }
253 254
254 *buffer_ptr = &queue_address[wptr]; 255 *buffer_ptr = &queue_address[wptr];
255 kq->pending_wptr = wptr + packet_size_in_dwords; 256 kq->pending_wptr = wptr + packet_size_in_dwords;
257 kq->pending_wptr64 = wptr64 + packet_size_in_dwords;
256 258
257 return 0; 259 return 0;
260
261err_no_space:
262 *buffer_ptr = NULL;
263 return -ENOMEM;
258} 264}
259 265
260static void submit_packet(struct kernel_queue *kq) 266static void submit_packet(struct kernel_queue *kq)
@@ -270,14 +276,18 @@ static void submit_packet(struct kernel_queue *kq)
270 pr_debug("\n"); 276 pr_debug("\n");
271#endif 277#endif
272 278
273 *kq->wptr_kernel = kq->pending_wptr; 279 kq->ops_asic_specific.submit_packet(kq);
274 write_kernel_doorbell(kq->queue->properties.doorbell_ptr,
275 kq->pending_wptr);
276} 280}
277 281
278static void rollback_packet(struct kernel_queue *kq) 282static void rollback_packet(struct kernel_queue *kq)
279{ 283{
280 kq->pending_wptr = *kq->queue->properties.write_ptr; 284 if (kq->dev->device_info->doorbell_size == 8) {
285 kq->pending_wptr64 = *kq->wptr64_kernel;
286 kq->pending_wptr = *kq->wptr_kernel %
287 (kq->queue->properties.queue_size / 4);
288 } else {
289 kq->pending_wptr = *kq->wptr_kernel;
290 }
281} 291}
282 292
283struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, 293struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
@@ -308,6 +318,11 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
308 case CHIP_HAWAII: 318 case CHIP_HAWAII:
309 kernel_queue_init_cik(&kq->ops_asic_specific); 319 kernel_queue_init_cik(&kq->ops_asic_specific);
310 break; 320 break;
321
322 case CHIP_VEGA10:
323 case CHIP_RAVEN:
324 kernel_queue_init_v9(&kq->ops_asic_specific);
325 break;
311 default: 326 default:
312 WARN(1, "Unexpected ASIC family %u", 327 WARN(1, "Unexpected ASIC family %u",
313 dev->device_info->asic_family); 328 dev->device_info->asic_family);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h
index 594053136ee4..97aff2041a5d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h
@@ -72,6 +72,7 @@ struct kernel_queue {
72 struct kfd_dev *dev; 72 struct kfd_dev *dev;
73 struct mqd_manager *mqd; 73 struct mqd_manager *mqd;
74 struct queue *queue; 74 struct queue *queue;
75 uint64_t pending_wptr64;
75 uint32_t pending_wptr; 76 uint32_t pending_wptr;
76 unsigned int nop_packet; 77 unsigned int nop_packet;
77 78
@@ -79,7 +80,10 @@ struct kernel_queue {
79 uint32_t *rptr_kernel; 80 uint32_t *rptr_kernel;
80 uint64_t rptr_gpu_addr; 81 uint64_t rptr_gpu_addr;
81 struct kfd_mem_obj *wptr_mem; 82 struct kfd_mem_obj *wptr_mem;
82 uint32_t *wptr_kernel; 83 union {
84 uint64_t *wptr64_kernel;
85 uint32_t *wptr_kernel;
86 };
83 uint64_t wptr_gpu_addr; 87 uint64_t wptr_gpu_addr;
84 struct kfd_mem_obj *pq; 88 struct kfd_mem_obj *pq;
85 uint64_t pq_gpu_addr; 89 uint64_t pq_gpu_addr;
@@ -97,5 +101,6 @@ struct kernel_queue {
97 101
98void kernel_queue_init_cik(struct kernel_queue_ops *ops); 102void kernel_queue_init_cik(struct kernel_queue_ops *ops);
99void kernel_queue_init_vi(struct kernel_queue_ops *ops); 103void kernel_queue_init_vi(struct kernel_queue_ops *ops);
104void kernel_queue_init_v9(struct kernel_queue_ops *ops);
100 105
101#endif /* KFD_KERNEL_QUEUE_H_ */ 106#endif /* KFD_KERNEL_QUEUE_H_ */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c
index a90eb440b1fb..19e54acb4125 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c
@@ -26,11 +26,13 @@
26static bool initialize_cik(struct kernel_queue *kq, struct kfd_dev *dev, 26static bool initialize_cik(struct kernel_queue *kq, struct kfd_dev *dev,
27 enum kfd_queue_type type, unsigned int queue_size); 27 enum kfd_queue_type type, unsigned int queue_size);
28static void uninitialize_cik(struct kernel_queue *kq); 28static void uninitialize_cik(struct kernel_queue *kq);
29static void submit_packet_cik(struct kernel_queue *kq);
29 30
30void kernel_queue_init_cik(struct kernel_queue_ops *ops) 31void kernel_queue_init_cik(struct kernel_queue_ops *ops)
31{ 32{
32 ops->initialize = initialize_cik; 33 ops->initialize = initialize_cik;
33 ops->uninitialize = uninitialize_cik; 34 ops->uninitialize = uninitialize_cik;
35 ops->submit_packet = submit_packet_cik;
34} 36}
35 37
36static bool initialize_cik(struct kernel_queue *kq, struct kfd_dev *dev, 38static bool initialize_cik(struct kernel_queue *kq, struct kfd_dev *dev,
@@ -42,3 +44,10 @@ static bool initialize_cik(struct kernel_queue *kq, struct kfd_dev *dev,
42static void uninitialize_cik(struct kernel_queue *kq) 44static void uninitialize_cik(struct kernel_queue *kq)
43{ 45{
44} 46}
47
48static void submit_packet_cik(struct kernel_queue *kq)
49{
50 *kq->wptr_kernel = kq->pending_wptr;
51 write_kernel_doorbell(kq->queue->properties.doorbell_ptr,
52 kq->pending_wptr);
53}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_v9.c
new file mode 100644
index 000000000000..684a3bf07efd
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_v9.c
@@ -0,0 +1,340 @@
1/*
2 * Copyright 2016-2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "kfd_kernel_queue.h"
25#include "kfd_device_queue_manager.h"
26#include "kfd_pm4_headers_ai.h"
27#include "kfd_pm4_opcodes.h"
28
29static bool initialize_v9(struct kernel_queue *kq, struct kfd_dev *dev,
30 enum kfd_queue_type type, unsigned int queue_size);
31static void uninitialize_v9(struct kernel_queue *kq);
32static void submit_packet_v9(struct kernel_queue *kq);
33
34void kernel_queue_init_v9(struct kernel_queue_ops *ops)
35{
36 ops->initialize = initialize_v9;
37 ops->uninitialize = uninitialize_v9;
38 ops->submit_packet = submit_packet_v9;
39}
40
41static bool initialize_v9(struct kernel_queue *kq, struct kfd_dev *dev,
42 enum kfd_queue_type type, unsigned int queue_size)
43{
44 int retval;
45
46 retval = kfd_gtt_sa_allocate(dev, PAGE_SIZE, &kq->eop_mem);
47 if (retval)
48 return false;
49
50 kq->eop_gpu_addr = kq->eop_mem->gpu_addr;
51 kq->eop_kernel_addr = kq->eop_mem->cpu_ptr;
52
53 memset(kq->eop_kernel_addr, 0, PAGE_SIZE);
54
55 return true;
56}
57
58static void uninitialize_v9(struct kernel_queue *kq)
59{
60 kfd_gtt_sa_free(kq->dev, kq->eop_mem);
61}
62
63static void submit_packet_v9(struct kernel_queue *kq)
64{
65 *kq->wptr64_kernel = kq->pending_wptr64;
66 write_kernel_doorbell64(kq->queue->properties.doorbell_ptr,
67 kq->pending_wptr64);
68}
69
70static int pm_map_process_v9(struct packet_manager *pm,
71 uint32_t *buffer, struct qcm_process_device *qpd)
72{
73 struct pm4_mes_map_process *packet;
74 uint64_t vm_page_table_base_addr =
75 (uint64_t)(qpd->page_table_base) << 12;
76
77 packet = (struct pm4_mes_map_process *)buffer;
78 memset(buffer, 0, sizeof(struct pm4_mes_map_process));
79
80 packet->header.u32All = pm_build_pm4_header(IT_MAP_PROCESS,
81 sizeof(struct pm4_mes_map_process));
82 packet->bitfields2.diq_enable = (qpd->is_debug) ? 1 : 0;
83 packet->bitfields2.process_quantum = 1;
84 packet->bitfields2.pasid = qpd->pqm->process->pasid;
85 packet->bitfields14.gds_size = qpd->gds_size;
86 packet->bitfields14.num_gws = qpd->num_gws;
87 packet->bitfields14.num_oac = qpd->num_oac;
88 packet->bitfields14.sdma_enable = 1;
89 packet->bitfields14.num_queues = (qpd->is_debug) ? 0 : qpd->queue_count;
90
91 packet->sh_mem_config = qpd->sh_mem_config;
92 packet->sh_mem_bases = qpd->sh_mem_bases;
93 packet->sq_shader_tba_lo = lower_32_bits(qpd->tba_addr >> 8);
94 packet->sq_shader_tba_hi = upper_32_bits(qpd->tba_addr >> 8);
95 packet->sq_shader_tma_lo = lower_32_bits(qpd->tma_addr >> 8);
96 packet->sq_shader_tma_hi = upper_32_bits(qpd->tma_addr >> 8);
97
98 packet->gds_addr_lo = lower_32_bits(qpd->gds_context_area);
99 packet->gds_addr_hi = upper_32_bits(qpd->gds_context_area);
100
101 packet->vm_context_page_table_base_addr_lo32 =
102 lower_32_bits(vm_page_table_base_addr);
103 packet->vm_context_page_table_base_addr_hi32 =
104 upper_32_bits(vm_page_table_base_addr);
105
106 return 0;
107}
108
109static int pm_runlist_v9(struct packet_manager *pm, uint32_t *buffer,
110 uint64_t ib, size_t ib_size_in_dwords, bool chain)
111{
112 struct pm4_mes_runlist *packet;
113
114 int concurrent_proc_cnt = 0;
115 struct kfd_dev *kfd = pm->dqm->dev;
116
117 /* Determine the number of processes to map together to HW:
118 * it can not exceed the number of VMIDs available to the
119 * scheduler, and it is determined by the smaller of the number
120 * of processes in the runlist and kfd module parameter
121 * hws_max_conc_proc.
122 * Note: the arbitration between the number of VMIDs and
123 * hws_max_conc_proc has been done in
124 * kgd2kfd_device_init().
125 */
126 concurrent_proc_cnt = min(pm->dqm->processes_count,
127 kfd->max_proc_per_quantum);
128
129 packet = (struct pm4_mes_runlist *)buffer;
130
131 memset(buffer, 0, sizeof(struct pm4_mes_runlist));
132 packet->header.u32All = pm_build_pm4_header(IT_RUN_LIST,
133 sizeof(struct pm4_mes_runlist));
134
135 packet->bitfields4.ib_size = ib_size_in_dwords;
136 packet->bitfields4.chain = chain ? 1 : 0;
137 packet->bitfields4.offload_polling = 0;
138 packet->bitfields4.valid = 1;
139 packet->bitfields4.process_cnt = concurrent_proc_cnt;
140 packet->ordinal2 = lower_32_bits(ib);
141 packet->ib_base_hi = upper_32_bits(ib);
142
143 return 0;
144}
145
146static int pm_map_queues_v9(struct packet_manager *pm, uint32_t *buffer,
147 struct queue *q, bool is_static)
148{
149 struct pm4_mes_map_queues *packet;
150 bool use_static = is_static;
151
152 packet = (struct pm4_mes_map_queues *)buffer;
153 memset(buffer, 0, sizeof(struct pm4_mes_map_queues));
154
155 packet->header.u32All = pm_build_pm4_header(IT_MAP_QUEUES,
156 sizeof(struct pm4_mes_map_queues));
157 packet->bitfields2.alloc_format =
158 alloc_format__mes_map_queues__one_per_pipe_vi;
159 packet->bitfields2.num_queues = 1;
160 packet->bitfields2.queue_sel =
161 queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi;
162
163 packet->bitfields2.engine_sel =
164 engine_sel__mes_map_queues__compute_vi;
165 packet->bitfields2.queue_type =
166 queue_type__mes_map_queues__normal_compute_vi;
167
168 switch (q->properties.type) {
169 case KFD_QUEUE_TYPE_COMPUTE:
170 if (use_static)
171 packet->bitfields2.queue_type =
172 queue_type__mes_map_queues__normal_latency_static_queue_vi;
173 break;
174 case KFD_QUEUE_TYPE_DIQ:
175 packet->bitfields2.queue_type =
176 queue_type__mes_map_queues__debug_interface_queue_vi;
177 break;
178 case KFD_QUEUE_TYPE_SDMA:
179 packet->bitfields2.engine_sel = q->properties.sdma_engine_id +
180 engine_sel__mes_map_queues__sdma0_vi;
181 use_static = false; /* no static queues under SDMA */
182 break;
183 default:
184 WARN(1, "queue type %d", q->properties.type);
185 return -EINVAL;
186 }
187 packet->bitfields3.doorbell_offset =
188 q->properties.doorbell_off;
189
190 packet->mqd_addr_lo =
191 lower_32_bits(q->gart_mqd_addr);
192
193 packet->mqd_addr_hi =
194 upper_32_bits(q->gart_mqd_addr);
195
196 packet->wptr_addr_lo =
197 lower_32_bits((uint64_t)q->properties.write_ptr);
198
199 packet->wptr_addr_hi =
200 upper_32_bits((uint64_t)q->properties.write_ptr);
201
202 return 0;
203}
204
205static int pm_unmap_queues_v9(struct packet_manager *pm, uint32_t *buffer,
206 enum kfd_queue_type type,
207 enum kfd_unmap_queues_filter filter,
208 uint32_t filter_param, bool reset,
209 unsigned int sdma_engine)
210{
211 struct pm4_mes_unmap_queues *packet;
212
213 packet = (struct pm4_mes_unmap_queues *)buffer;
214 memset(buffer, 0, sizeof(struct pm4_mes_unmap_queues));
215
216 packet->header.u32All = pm_build_pm4_header(IT_UNMAP_QUEUES,
217 sizeof(struct pm4_mes_unmap_queues));
218 switch (type) {
219 case KFD_QUEUE_TYPE_COMPUTE:
220 case KFD_QUEUE_TYPE_DIQ:
221 packet->bitfields2.engine_sel =
222 engine_sel__mes_unmap_queues__compute;
223 break;
224 case KFD_QUEUE_TYPE_SDMA:
225 packet->bitfields2.engine_sel =
226 engine_sel__mes_unmap_queues__sdma0 + sdma_engine;
227 break;
228 default:
229 WARN(1, "queue type %d", type);
230 return -EINVAL;
231 }
232
233 if (reset)
234 packet->bitfields2.action =
235 action__mes_unmap_queues__reset_queues;
236 else
237 packet->bitfields2.action =
238 action__mes_unmap_queues__preempt_queues;
239
240 switch (filter) {
241 case KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE:
242 packet->bitfields2.queue_sel =
243 queue_sel__mes_unmap_queues__perform_request_on_specified_queues;
244 packet->bitfields2.num_queues = 1;
245 packet->bitfields3b.doorbell_offset0 = filter_param;
246 break;
247 case KFD_UNMAP_QUEUES_FILTER_BY_PASID:
248 packet->bitfields2.queue_sel =
249 queue_sel__mes_unmap_queues__perform_request_on_pasid_queues;
250 packet->bitfields3a.pasid = filter_param;
251 break;
252 case KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES:
253 packet->bitfields2.queue_sel =
254 queue_sel__mes_unmap_queues__unmap_all_queues;
255 break;
256 case KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES:
257 /* in this case, we do not preempt static queues */
258 packet->bitfields2.queue_sel =
259 queue_sel__mes_unmap_queues__unmap_all_non_static_queues;
260 break;
261 default:
262 WARN(1, "filter %d", filter);
263 return -EINVAL;
264 }
265
266 return 0;
267
268}
269
270static int pm_query_status_v9(struct packet_manager *pm, uint32_t *buffer,
271 uint64_t fence_address, uint32_t fence_value)
272{
273 struct pm4_mes_query_status *packet;
274
275 packet = (struct pm4_mes_query_status *)buffer;
276 memset(buffer, 0, sizeof(struct pm4_mes_query_status));
277
278
279 packet->header.u32All = pm_build_pm4_header(IT_QUERY_STATUS,
280 sizeof(struct pm4_mes_query_status));
281
282 packet->bitfields2.context_id = 0;
283 packet->bitfields2.interrupt_sel =
284 interrupt_sel__mes_query_status__completion_status;
285 packet->bitfields2.command =
286 command__mes_query_status__fence_only_after_write_ack;
287
288 packet->addr_hi = upper_32_bits((uint64_t)fence_address);
289 packet->addr_lo = lower_32_bits((uint64_t)fence_address);
290 packet->data_hi = upper_32_bits((uint64_t)fence_value);
291 packet->data_lo = lower_32_bits((uint64_t)fence_value);
292
293 return 0;
294}
295
296
297static int pm_release_mem_v9(uint64_t gpu_addr, uint32_t *buffer)
298{
299 struct pm4_mec_release_mem *packet;
300
301 packet = (struct pm4_mec_release_mem *)buffer;
302 memset(buffer, 0, sizeof(struct pm4_mec_release_mem));
303
304 packet->header.u32All = pm_build_pm4_header(IT_RELEASE_MEM,
305 sizeof(struct pm4_mec_release_mem));
306
307 packet->bitfields2.event_type = CACHE_FLUSH_AND_INV_TS_EVENT;
308 packet->bitfields2.event_index = event_index__mec_release_mem__end_of_pipe;
309 packet->bitfields2.tcl1_action_ena = 1;
310 packet->bitfields2.tc_action_ena = 1;
311 packet->bitfields2.cache_policy = cache_policy__mec_release_mem__lru;
312
313 packet->bitfields3.data_sel = data_sel__mec_release_mem__send_32_bit_low;
314 packet->bitfields3.int_sel =
315 int_sel__mec_release_mem__send_interrupt_after_write_confirm;
316
317 packet->bitfields4.address_lo_32b = (gpu_addr & 0xffffffff) >> 2;
318 packet->address_hi = upper_32_bits(gpu_addr);
319
320 packet->data_lo = 0;
321
322 return 0;
323}
324
325const struct packet_manager_funcs kfd_v9_pm_funcs = {
326 .map_process = pm_map_process_v9,
327 .runlist = pm_runlist_v9,
328 .set_resources = pm_set_resources_vi,
329 .map_queues = pm_map_queues_v9,
330 .unmap_queues = pm_unmap_queues_v9,
331 .query_status = pm_query_status_v9,
332 .release_mem = pm_release_mem_v9,
333 .map_process_size = sizeof(struct pm4_mes_map_process),
334 .runlist_size = sizeof(struct pm4_mes_runlist),
335 .set_resources_size = sizeof(struct pm4_mes_set_resources),
336 .map_queues_size = sizeof(struct pm4_mes_map_queues),
337 .unmap_queues_size = sizeof(struct pm4_mes_unmap_queues),
338 .query_status_size = sizeof(struct pm4_mes_query_status),
339 .release_mem_size = sizeof(struct pm4_mec_release_mem)
340};
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c
index f1d48281e322..bf20c6d32ef3 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c
@@ -22,15 +22,20 @@
22 */ 22 */
23 23
24#include "kfd_kernel_queue.h" 24#include "kfd_kernel_queue.h"
25#include "kfd_device_queue_manager.h"
26#include "kfd_pm4_headers_vi.h"
27#include "kfd_pm4_opcodes.h"
25 28
26static bool initialize_vi(struct kernel_queue *kq, struct kfd_dev *dev, 29static bool initialize_vi(struct kernel_queue *kq, struct kfd_dev *dev,
27 enum kfd_queue_type type, unsigned int queue_size); 30 enum kfd_queue_type type, unsigned int queue_size);
28static void uninitialize_vi(struct kernel_queue *kq); 31static void uninitialize_vi(struct kernel_queue *kq);
32static void submit_packet_vi(struct kernel_queue *kq);
29 33
30void kernel_queue_init_vi(struct kernel_queue_ops *ops) 34void kernel_queue_init_vi(struct kernel_queue_ops *ops)
31{ 35{
32 ops->initialize = initialize_vi; 36 ops->initialize = initialize_vi;
33 ops->uninitialize = uninitialize_vi; 37 ops->uninitialize = uninitialize_vi;
38 ops->submit_packet = submit_packet_vi;
34} 39}
35 40
36static bool initialize_vi(struct kernel_queue *kq, struct kfd_dev *dev, 41static bool initialize_vi(struct kernel_queue *kq, struct kfd_dev *dev,
@@ -54,3 +59,317 @@ static void uninitialize_vi(struct kernel_queue *kq)
54{ 59{
55 kfd_gtt_sa_free(kq->dev, kq->eop_mem); 60 kfd_gtt_sa_free(kq->dev, kq->eop_mem);
56} 61}
62
63static void submit_packet_vi(struct kernel_queue *kq)
64{
65 *kq->wptr_kernel = kq->pending_wptr;
66 write_kernel_doorbell(kq->queue->properties.doorbell_ptr,
67 kq->pending_wptr);
68}
69
70unsigned int pm_build_pm4_header(unsigned int opcode, size_t packet_size)
71{
72 union PM4_MES_TYPE_3_HEADER header;
73
74 header.u32All = 0;
75 header.opcode = opcode;
76 header.count = packet_size / 4 - 2;
77 header.type = PM4_TYPE_3;
78
79 return header.u32All;
80}
81
82static int pm_map_process_vi(struct packet_manager *pm, uint32_t *buffer,
83 struct qcm_process_device *qpd)
84{
85 struct pm4_mes_map_process *packet;
86
87 packet = (struct pm4_mes_map_process *)buffer;
88
89 memset(buffer, 0, sizeof(struct pm4_mes_map_process));
90
91 packet->header.u32All = pm_build_pm4_header(IT_MAP_PROCESS,
92 sizeof(struct pm4_mes_map_process));
93 packet->bitfields2.diq_enable = (qpd->is_debug) ? 1 : 0;
94 packet->bitfields2.process_quantum = 1;
95 packet->bitfields2.pasid = qpd->pqm->process->pasid;
96 packet->bitfields3.page_table_base = qpd->page_table_base;
97 packet->bitfields10.gds_size = qpd->gds_size;
98 packet->bitfields10.num_gws = qpd->num_gws;
99 packet->bitfields10.num_oac = qpd->num_oac;
100 packet->bitfields10.num_queues = (qpd->is_debug) ? 0 : qpd->queue_count;
101
102 packet->sh_mem_config = qpd->sh_mem_config;
103 packet->sh_mem_bases = qpd->sh_mem_bases;
104 packet->sh_mem_ape1_base = qpd->sh_mem_ape1_base;
105 packet->sh_mem_ape1_limit = qpd->sh_mem_ape1_limit;
106
107 packet->sh_hidden_private_base_vmid = qpd->sh_hidden_private_base;
108
109 packet->gds_addr_lo = lower_32_bits(qpd->gds_context_area);
110 packet->gds_addr_hi = upper_32_bits(qpd->gds_context_area);
111
112 return 0;
113}
114
115static int pm_runlist_vi(struct packet_manager *pm, uint32_t *buffer,
116 uint64_t ib, size_t ib_size_in_dwords, bool chain)
117{
118 struct pm4_mes_runlist *packet;
119 int concurrent_proc_cnt = 0;
120 struct kfd_dev *kfd = pm->dqm->dev;
121
122 if (WARN_ON(!ib))
123 return -EFAULT;
124
125 /* Determine the number of processes to map together to HW:
126 * it can not exceed the number of VMIDs available to the
127 * scheduler, and it is determined by the smaller of the number
128 * of processes in the runlist and kfd module parameter
129 * hws_max_conc_proc.
130 * Note: the arbitration between the number of VMIDs and
131 * hws_max_conc_proc has been done in
132 * kgd2kfd_device_init().
133 */
134 concurrent_proc_cnt = min(pm->dqm->processes_count,
135 kfd->max_proc_per_quantum);
136
137 packet = (struct pm4_mes_runlist *)buffer;
138
139 memset(buffer, 0, sizeof(struct pm4_mes_runlist));
140 packet->header.u32All = pm_build_pm4_header(IT_RUN_LIST,
141 sizeof(struct pm4_mes_runlist));
142
143 packet->bitfields4.ib_size = ib_size_in_dwords;
144 packet->bitfields4.chain = chain ? 1 : 0;
145 packet->bitfields4.offload_polling = 0;
146 packet->bitfields4.valid = 1;
147 packet->bitfields4.process_cnt = concurrent_proc_cnt;
148 packet->ordinal2 = lower_32_bits(ib);
149 packet->bitfields3.ib_base_hi = upper_32_bits(ib);
150
151 return 0;
152}
153
154int pm_set_resources_vi(struct packet_manager *pm, uint32_t *buffer,
155 struct scheduling_resources *res)
156{
157 struct pm4_mes_set_resources *packet;
158
159 packet = (struct pm4_mes_set_resources *)buffer;
160 memset(buffer, 0, sizeof(struct pm4_mes_set_resources));
161
162 packet->header.u32All = pm_build_pm4_header(IT_SET_RESOURCES,
163 sizeof(struct pm4_mes_set_resources));
164
165 packet->bitfields2.queue_type =
166 queue_type__mes_set_resources__hsa_interface_queue_hiq;
167 packet->bitfields2.vmid_mask = res->vmid_mask;
168 packet->bitfields2.unmap_latency = KFD_UNMAP_LATENCY_MS / 100;
169 packet->bitfields7.oac_mask = res->oac_mask;
170 packet->bitfields8.gds_heap_base = res->gds_heap_base;
171 packet->bitfields8.gds_heap_size = res->gds_heap_size;
172
173 packet->gws_mask_lo = lower_32_bits(res->gws_mask);
174 packet->gws_mask_hi = upper_32_bits(res->gws_mask);
175
176 packet->queue_mask_lo = lower_32_bits(res->queue_mask);
177 packet->queue_mask_hi = upper_32_bits(res->queue_mask);
178
179 return 0;
180}
181
182static int pm_map_queues_vi(struct packet_manager *pm, uint32_t *buffer,
183 struct queue *q, bool is_static)
184{
185 struct pm4_mes_map_queues *packet;
186 bool use_static = is_static;
187
188 packet = (struct pm4_mes_map_queues *)buffer;
189 memset(buffer, 0, sizeof(struct pm4_mes_map_queues));
190
191 packet->header.u32All = pm_build_pm4_header(IT_MAP_QUEUES,
192 sizeof(struct pm4_mes_map_queues));
193 packet->bitfields2.alloc_format =
194 alloc_format__mes_map_queues__one_per_pipe_vi;
195 packet->bitfields2.num_queues = 1;
196 packet->bitfields2.queue_sel =
197 queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi;
198
199 packet->bitfields2.engine_sel =
200 engine_sel__mes_map_queues__compute_vi;
201 packet->bitfields2.queue_type =
202 queue_type__mes_map_queues__normal_compute_vi;
203
204 switch (q->properties.type) {
205 case KFD_QUEUE_TYPE_COMPUTE:
206 if (use_static)
207 packet->bitfields2.queue_type =
208 queue_type__mes_map_queues__normal_latency_static_queue_vi;
209 break;
210 case KFD_QUEUE_TYPE_DIQ:
211 packet->bitfields2.queue_type =
212 queue_type__mes_map_queues__debug_interface_queue_vi;
213 break;
214 case KFD_QUEUE_TYPE_SDMA:
215 packet->bitfields2.engine_sel = q->properties.sdma_engine_id +
216 engine_sel__mes_map_queues__sdma0_vi;
217 use_static = false; /* no static queues under SDMA */
218 break;
219 default:
220 WARN(1, "queue type %d", q->properties.type);
221 return -EINVAL;
222 }
223 packet->bitfields3.doorbell_offset =
224 q->properties.doorbell_off;
225
226 packet->mqd_addr_lo =
227 lower_32_bits(q->gart_mqd_addr);
228
229 packet->mqd_addr_hi =
230 upper_32_bits(q->gart_mqd_addr);
231
232 packet->wptr_addr_lo =
233 lower_32_bits((uint64_t)q->properties.write_ptr);
234
235 packet->wptr_addr_hi =
236 upper_32_bits((uint64_t)q->properties.write_ptr);
237
238 return 0;
239}
240
241static int pm_unmap_queues_vi(struct packet_manager *pm, uint32_t *buffer,
242 enum kfd_queue_type type,
243 enum kfd_unmap_queues_filter filter,
244 uint32_t filter_param, bool reset,
245 unsigned int sdma_engine)
246{
247 struct pm4_mes_unmap_queues *packet;
248
249 packet = (struct pm4_mes_unmap_queues *)buffer;
250 memset(buffer, 0, sizeof(struct pm4_mes_unmap_queues));
251
252 packet->header.u32All = pm_build_pm4_header(IT_UNMAP_QUEUES,
253 sizeof(struct pm4_mes_unmap_queues));
254 switch (type) {
255 case KFD_QUEUE_TYPE_COMPUTE:
256 case KFD_QUEUE_TYPE_DIQ:
257 packet->bitfields2.engine_sel =
258 engine_sel__mes_unmap_queues__compute;
259 break;
260 case KFD_QUEUE_TYPE_SDMA:
261 packet->bitfields2.engine_sel =
262 engine_sel__mes_unmap_queues__sdma0 + sdma_engine;
263 break;
264 default:
265 WARN(1, "queue type %d", type);
266 return -EINVAL;
267 }
268
269 if (reset)
270 packet->bitfields2.action =
271 action__mes_unmap_queues__reset_queues;
272 else
273 packet->bitfields2.action =
274 action__mes_unmap_queues__preempt_queues;
275
276 switch (filter) {
277 case KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE:
278 packet->bitfields2.queue_sel =
279 queue_sel__mes_unmap_queues__perform_request_on_specified_queues;
280 packet->bitfields2.num_queues = 1;
281 packet->bitfields3b.doorbell_offset0 = filter_param;
282 break;
283 case KFD_UNMAP_QUEUES_FILTER_BY_PASID:
284 packet->bitfields2.queue_sel =
285 queue_sel__mes_unmap_queues__perform_request_on_pasid_queues;
286 packet->bitfields3a.pasid = filter_param;
287 break;
288 case KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES:
289 packet->bitfields2.queue_sel =
290 queue_sel__mes_unmap_queues__unmap_all_queues;
291 break;
292 case KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES:
293 /* in this case, we do not preempt static queues */
294 packet->bitfields2.queue_sel =
295 queue_sel__mes_unmap_queues__unmap_all_non_static_queues;
296 break;
297 default:
298 WARN(1, "filter %d", filter);
299 return -EINVAL;
300 }
301
302 return 0;
303
304}
305
306static int pm_query_status_vi(struct packet_manager *pm, uint32_t *buffer,
307 uint64_t fence_address, uint32_t fence_value)
308{
309 struct pm4_mes_query_status *packet;
310
311 packet = (struct pm4_mes_query_status *)buffer;
312 memset(buffer, 0, sizeof(struct pm4_mes_query_status));
313
314 packet->header.u32All = pm_build_pm4_header(IT_QUERY_STATUS,
315 sizeof(struct pm4_mes_query_status));
316
317 packet->bitfields2.context_id = 0;
318 packet->bitfields2.interrupt_sel =
319 interrupt_sel__mes_query_status__completion_status;
320 packet->bitfields2.command =
321 command__mes_query_status__fence_only_after_write_ack;
322
323 packet->addr_hi = upper_32_bits((uint64_t)fence_address);
324 packet->addr_lo = lower_32_bits((uint64_t)fence_address);
325 packet->data_hi = upper_32_bits((uint64_t)fence_value);
326 packet->data_lo = lower_32_bits((uint64_t)fence_value);
327
328 return 0;
329}
330
331static int pm_release_mem_vi(uint64_t gpu_addr, uint32_t *buffer)
332{
333 struct pm4_mec_release_mem *packet;
334
335 packet = (struct pm4_mec_release_mem *)buffer;
336 memset(buffer, 0, sizeof(*packet));
337
338 packet->header.u32All = pm_build_pm4_header(IT_RELEASE_MEM,
339 sizeof(*packet));
340
341 packet->bitfields2.event_type = CACHE_FLUSH_AND_INV_TS_EVENT;
342 packet->bitfields2.event_index = event_index___release_mem__end_of_pipe;
343 packet->bitfields2.tcl1_action_ena = 1;
344 packet->bitfields2.tc_action_ena = 1;
345 packet->bitfields2.cache_policy = cache_policy___release_mem__lru;
346 packet->bitfields2.atc = 0;
347
348 packet->bitfields3.data_sel = data_sel___release_mem__send_32_bit_low;
349 packet->bitfields3.int_sel =
350 int_sel___release_mem__send_interrupt_after_write_confirm;
351
352 packet->bitfields4.address_lo_32b = (gpu_addr & 0xffffffff) >> 2;
353 packet->address_hi = upper_32_bits(gpu_addr);
354
355 packet->data_lo = 0;
356
357 return 0;
358}
359
360const struct packet_manager_funcs kfd_vi_pm_funcs = {
361 .map_process = pm_map_process_vi,
362 .runlist = pm_runlist_vi,
363 .set_resources = pm_set_resources_vi,
364 .map_queues = pm_map_queues_vi,
365 .unmap_queues = pm_unmap_queues_vi,
366 .query_status = pm_query_status_vi,
367 .release_mem = pm_release_mem_vi,
368 .map_process_size = sizeof(struct pm4_mes_map_process),
369 .runlist_size = sizeof(struct pm4_mes_runlist),
370 .set_resources_size = sizeof(struct pm4_mes_set_resources),
371 .map_queues_size = sizeof(struct pm4_mes_map_queues),
372 .unmap_queues_size = sizeof(struct pm4_mes_unmap_queues),
373 .query_status_size = sizeof(struct pm4_mes_query_status),
374 .release_mem_size = sizeof(struct pm4_mec_release_mem)
375};
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
index e0c07d24d251..76bf2dc8aec4 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
@@ -43,6 +43,8 @@ static const struct kgd2kfd_calls kgd2kfd = {
43 .interrupt = kgd2kfd_interrupt, 43 .interrupt = kgd2kfd_interrupt,
44 .suspend = kgd2kfd_suspend, 44 .suspend = kgd2kfd_suspend,
45 .resume = kgd2kfd_resume, 45 .resume = kgd2kfd_resume,
46 .quiesce_mm = kgd2kfd_quiesce_mm,
47 .resume_mm = kgd2kfd_resume_mm,
46 .schedule_evict_and_restore_process = 48 .schedule_evict_and_restore_process =
47 kgd2kfd_schedule_evict_and_restore_process, 49 kgd2kfd_schedule_evict_and_restore_process,
48}; 50};
@@ -81,6 +83,11 @@ module_param(ignore_crat, int, 0444);
81MODULE_PARM_DESC(ignore_crat, 83MODULE_PARM_DESC(ignore_crat,
82 "Ignore CRAT table during KFD initialization (0 = use CRAT (default), 1 = ignore CRAT)"); 84 "Ignore CRAT table during KFD initialization (0 = use CRAT (default), 1 = ignore CRAT)");
83 85
86int vega10_noretry;
87module_param_named(noretry, vega10_noretry, int, 0644);
88MODULE_PARM_DESC(noretry,
89 "Set sh_mem_config.retry_disable on Vega10 (0 = retry enabled (default), 1 = retry disabled)");
90
84static int amdkfd_init_completed; 91static int amdkfd_init_completed;
85 92
86int kgd2kfd_init(unsigned int interface_version, 93int kgd2kfd_init(unsigned int interface_version,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
index ee7061e1c466..4b8eb506642b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
@@ -38,6 +38,9 @@ struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
38 case CHIP_POLARIS10: 38 case CHIP_POLARIS10:
39 case CHIP_POLARIS11: 39 case CHIP_POLARIS11:
40 return mqd_manager_init_vi_tonga(type, dev); 40 return mqd_manager_init_vi_tonga(type, dev);
41 case CHIP_VEGA10:
42 case CHIP_RAVEN:
43 return mqd_manager_init_v9(type, dev);
41 default: 44 default:
42 WARN(1, "Unexpected ASIC family %u", 45 WARN(1, "Unexpected ASIC family %u",
43 dev->device_info->asic_family); 46 dev->device_info->asic_family);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
index c00c325ed3c9..06eaa218eba6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
@@ -79,10 +79,6 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
79 m->cp_mqd_base_addr_lo = lower_32_bits(addr); 79 m->cp_mqd_base_addr_lo = lower_32_bits(addr);
80 m->cp_mqd_base_addr_hi = upper_32_bits(addr); 80 m->cp_mqd_base_addr_hi = upper_32_bits(addr);
81 81
82 m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE | IB_ATC_EN;
83 /* Although WinKFD writes this, I suspect it should not be necessary */
84 m->cp_hqd_ib_control = IB_ATC_EN | DEFAULT_MIN_IB_AVAIL_SIZE;
85
86 m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS | 82 m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
87 QUANTUM_DURATION(10); 83 QUANTUM_DURATION(10);
88 84
@@ -412,7 +408,7 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
412 if (WARN_ON(type >= KFD_MQD_TYPE_MAX)) 408 if (WARN_ON(type >= KFD_MQD_TYPE_MAX))
413 return NULL; 409 return NULL;
414 410
415 mqd = kzalloc(sizeof(*mqd), GFP_KERNEL); 411 mqd = kzalloc(sizeof(*mqd), GFP_NOIO);
416 if (!mqd) 412 if (!mqd)
417 return NULL; 413 return NULL;
418 414
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
new file mode 100644
index 000000000000..684054ff02cd
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
@@ -0,0 +1,443 @@
1/*
2 * Copyright 2016-2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include <linux/printk.h>
25#include <linux/slab.h>
26#include <linux/uaccess.h>
27#include "kfd_priv.h"
28#include "kfd_mqd_manager.h"
29#include "v9_structs.h"
30#include "gc/gc_9_0_offset.h"
31#include "gc/gc_9_0_sh_mask.h"
32#include "sdma0/sdma0_4_0_sh_mask.h"
33
34static inline struct v9_mqd *get_mqd(void *mqd)
35{
36 return (struct v9_mqd *)mqd;
37}
38
39static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd)
40{
41 return (struct v9_sdma_mqd *)mqd;
42}
43
44static int init_mqd(struct mqd_manager *mm, void **mqd,
45 struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
46 struct queue_properties *q)
47{
48 int retval;
49 uint64_t addr;
50 struct v9_mqd *m;
51 struct kfd_dev *kfd = mm->dev;
52
53 /* From V9, for CWSR, the control stack is located on the next page
54 * boundary after the mqd, we will use the gtt allocation function
55 * instead of sub-allocation function.
56 */
57 if (kfd->cwsr_enabled && (q->type == KFD_QUEUE_TYPE_COMPUTE)) {
58 *mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_NOIO);
59 if (!*mqd_mem_obj)
60 return -ENOMEM;
61 retval = kfd->kfd2kgd->init_gtt_mem_allocation(kfd->kgd,
62 ALIGN(q->ctl_stack_size, PAGE_SIZE) +
63 ALIGN(sizeof(struct v9_mqd), PAGE_SIZE),
64 &((*mqd_mem_obj)->gtt_mem),
65 &((*mqd_mem_obj)->gpu_addr),
66 (void *)&((*mqd_mem_obj)->cpu_ptr));
67 } else
68 retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct v9_mqd),
69 mqd_mem_obj);
70 if (retval != 0)
71 return -ENOMEM;
72
73 m = (struct v9_mqd *) (*mqd_mem_obj)->cpu_ptr;
74 addr = (*mqd_mem_obj)->gpu_addr;
75
76 memset(m, 0, sizeof(struct v9_mqd));
77
78 m->header = 0xC0310800;
79 m->compute_pipelinestat_enable = 1;
80 m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
81 m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
82 m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
83 m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
84
85 m->cp_hqd_persistent_state = CP_HQD_PERSISTENT_STATE__PRELOAD_REQ_MASK |
86 0x53 << CP_HQD_PERSISTENT_STATE__PRELOAD_SIZE__SHIFT;
87
88 m->cp_mqd_control = 1 << CP_MQD_CONTROL__PRIV_STATE__SHIFT;
89
90 m->cp_mqd_base_addr_lo = lower_32_bits(addr);
91 m->cp_mqd_base_addr_hi = upper_32_bits(addr);
92
93 m->cp_hqd_quantum = 1 << CP_HQD_QUANTUM__QUANTUM_EN__SHIFT |
94 1 << CP_HQD_QUANTUM__QUANTUM_SCALE__SHIFT |
95 10 << CP_HQD_QUANTUM__QUANTUM_DURATION__SHIFT;
96
97 m->cp_hqd_pipe_priority = 1;
98 m->cp_hqd_queue_priority = 15;
99
100 if (q->format == KFD_QUEUE_FORMAT_AQL) {
101 m->cp_hqd_aql_control =
102 1 << CP_HQD_AQL_CONTROL__CONTROL0__SHIFT;
103 }
104
105 if (q->tba_addr) {
106 m->compute_pgm_rsrc2 |=
107 (1 << COMPUTE_PGM_RSRC2__TRAP_PRESENT__SHIFT);
108 }
109
110 if (mm->dev->cwsr_enabled && q->ctx_save_restore_area_address) {
111 m->cp_hqd_persistent_state |=
112 (1 << CP_HQD_PERSISTENT_STATE__QSWITCH_MODE__SHIFT);
113 m->cp_hqd_ctx_save_base_addr_lo =
114 lower_32_bits(q->ctx_save_restore_area_address);
115 m->cp_hqd_ctx_save_base_addr_hi =
116 upper_32_bits(q->ctx_save_restore_area_address);
117 m->cp_hqd_ctx_save_size = q->ctx_save_restore_area_size;
118 m->cp_hqd_cntl_stack_size = q->ctl_stack_size;
119 m->cp_hqd_cntl_stack_offset = q->ctl_stack_size;
120 m->cp_hqd_wg_state_offset = q->ctl_stack_size;
121 }
122
123 *mqd = m;
124 if (gart_addr)
125 *gart_addr = addr;
126 retval = mm->update_mqd(mm, m, q);
127
128 return retval;
129}
130
131static int load_mqd(struct mqd_manager *mm, void *mqd,
132 uint32_t pipe_id, uint32_t queue_id,
133 struct queue_properties *p, struct mm_struct *mms)
134{
135 /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */
136 uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
137
138 return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
139 (uint32_t __user *)p->write_ptr,
140 wptr_shift, 0, mms);
141}
142
143static int update_mqd(struct mqd_manager *mm, void *mqd,
144 struct queue_properties *q)
145{
146 struct v9_mqd *m;
147
148 m = get_mqd(mqd);
149
150 m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
151 m->cp_hqd_pq_control |= order_base_2(q->queue_size / 4) - 1;
152 pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
153
154 m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
155 m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
156
157 m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
158 m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
159 m->cp_hqd_pq_wptr_poll_addr_lo = lower_32_bits((uint64_t)q->write_ptr);
160 m->cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits((uint64_t)q->write_ptr);
161
162 m->cp_hqd_pq_doorbell_control =
163 q->doorbell_off <<
164 CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
165 pr_debug("cp_hqd_pq_doorbell_control 0x%x\n",
166 m->cp_hqd_pq_doorbell_control);
167
168 m->cp_hqd_ib_control =
169 3 << CP_HQD_IB_CONTROL__MIN_IB_AVAIL_SIZE__SHIFT |
170 1 << CP_HQD_IB_CONTROL__IB_EXE_DISABLE__SHIFT;
171
172 /*
173 * HW does not clamp this field correctly. Maximum EOP queue size
174 * is constrained by per-SE EOP done signal count, which is 8-bit.
175 * Limit is 0xFF EOP entries (= 0x7F8 dwords). CP will not submit
176 * more than (EOP entry count - 1) so a queue size of 0x800 dwords
177 * is safe, giving a maximum field value of 0xA.
178 */
179 m->cp_hqd_eop_control = min(0xA,
180 order_base_2(q->eop_ring_buffer_size / 4) - 1);
181 m->cp_hqd_eop_base_addr_lo =
182 lower_32_bits(q->eop_ring_buffer_address >> 8);
183 m->cp_hqd_eop_base_addr_hi =
184 upper_32_bits(q->eop_ring_buffer_address >> 8);
185
186 m->cp_hqd_iq_timer = 0;
187
188 m->cp_hqd_vmid = q->vmid;
189
190 if (q->format == KFD_QUEUE_FORMAT_AQL) {
191 m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__NO_UPDATE_RPTR_MASK |
192 2 << CP_HQD_PQ_CONTROL__SLOT_BASED_WPTR__SHIFT |
193 1 << CP_HQD_PQ_CONTROL__QUEUE_FULL_EN__SHIFT |
194 1 << CP_HQD_PQ_CONTROL__WPP_CLAMP_EN__SHIFT;
195 m->cp_hqd_pq_doorbell_control |= 1 <<
196 CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_BIF_DROP__SHIFT;
197 }
198 if (mm->dev->cwsr_enabled && q->ctx_save_restore_area_address)
199 m->cp_hqd_ctx_save_control = 0;
200
201 q->is_active = (q->queue_size > 0 &&
202 q->queue_address != 0 &&
203 q->queue_percent > 0 &&
204 !q->is_evicted);
205
206 return 0;
207}
208
209
210static int destroy_mqd(struct mqd_manager *mm, void *mqd,
211 enum kfd_preempt_type type,
212 unsigned int timeout, uint32_t pipe_id,
213 uint32_t queue_id)
214{
215 return mm->dev->kfd2kgd->hqd_destroy
216 (mm->dev->kgd, mqd, type, timeout,
217 pipe_id, queue_id);
218}
219
220static void uninit_mqd(struct mqd_manager *mm, void *mqd,
221 struct kfd_mem_obj *mqd_mem_obj)
222{
223 struct kfd_dev *kfd = mm->dev;
224
225 if (mqd_mem_obj->gtt_mem) {
226 kfd->kfd2kgd->free_gtt_mem(kfd->kgd, mqd_mem_obj->gtt_mem);
227 kfree(mqd_mem_obj);
228 } else {
229 kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
230 }
231}
232
233static bool is_occupied(struct mqd_manager *mm, void *mqd,
234 uint64_t queue_address, uint32_t pipe_id,
235 uint32_t queue_id)
236{
237 return mm->dev->kfd2kgd->hqd_is_occupied(
238 mm->dev->kgd, queue_address,
239 pipe_id, queue_id);
240}
241
242static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,
243 struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
244 struct queue_properties *q)
245{
246 struct v9_mqd *m;
247 int retval = init_mqd(mm, mqd, mqd_mem_obj, gart_addr, q);
248
249 if (retval != 0)
250 return retval;
251
252 m = get_mqd(*mqd);
253
254 m->cp_hqd_pq_control |= 1 << CP_HQD_PQ_CONTROL__PRIV_STATE__SHIFT |
255 1 << CP_HQD_PQ_CONTROL__KMD_QUEUE__SHIFT;
256
257 return retval;
258}
259
260static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
261 struct queue_properties *q)
262{
263 struct v9_mqd *m;
264 int retval = update_mqd(mm, mqd, q);
265
266 if (retval != 0)
267 return retval;
268
269 /* TODO: what's the point? update_mqd already does this. */
270 m = get_mqd(mqd);
271 m->cp_hqd_vmid = q->vmid;
272 return retval;
273}
274
275static int init_mqd_sdma(struct mqd_manager *mm, void **mqd,
276 struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
277 struct queue_properties *q)
278{
279 int retval;
280 struct v9_sdma_mqd *m;
281
282
283 retval = kfd_gtt_sa_allocate(mm->dev,
284 sizeof(struct v9_sdma_mqd),
285 mqd_mem_obj);
286
287 if (retval != 0)
288 return -ENOMEM;
289
290 m = (struct v9_sdma_mqd *) (*mqd_mem_obj)->cpu_ptr;
291
292 memset(m, 0, sizeof(struct v9_sdma_mqd));
293
294 *mqd = m;
295 if (gart_addr)
296 *gart_addr = (*mqd_mem_obj)->gpu_addr;
297
298 retval = mm->update_mqd(mm, m, q);
299
300 return retval;
301}
302
303static void uninit_mqd_sdma(struct mqd_manager *mm, void *mqd,
304 struct kfd_mem_obj *mqd_mem_obj)
305{
306 kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
307}
308
309static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
310 uint32_t pipe_id, uint32_t queue_id,
311 struct queue_properties *p, struct mm_struct *mms)
312{
313 return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd,
314 (uint32_t __user *)p->write_ptr,
315 mms);
316}
317
318#define SDMA_RLC_DUMMY_DEFAULT 0xf
319
320static int update_mqd_sdma(struct mqd_manager *mm, void *mqd,
321 struct queue_properties *q)
322{
323 struct v9_sdma_mqd *m;
324
325 m = get_sdma_mqd(mqd);
326 m->sdmax_rlcx_rb_cntl = order_base_2(q->queue_size / 4)
327 << SDMA0_RLC0_RB_CNTL__RB_SIZE__SHIFT |
328 q->vmid << SDMA0_RLC0_RB_CNTL__RB_VMID__SHIFT |
329 1 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT |
330 6 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT;
331
332 m->sdmax_rlcx_rb_base = lower_32_bits(q->queue_address >> 8);
333 m->sdmax_rlcx_rb_base_hi = upper_32_bits(q->queue_address >> 8);
334 m->sdmax_rlcx_rb_rptr_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
335 m->sdmax_rlcx_rb_rptr_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
336 m->sdmax_rlcx_doorbell_offset =
337 q->doorbell_off << SDMA0_RLC0_DOORBELL_OFFSET__OFFSET__SHIFT;
338
339 m->sdma_engine_id = q->sdma_engine_id;
340 m->sdma_queue_id = q->sdma_queue_id;
341 m->sdmax_rlcx_dummy_reg = SDMA_RLC_DUMMY_DEFAULT;
342
343 q->is_active = (q->queue_size > 0 &&
344 q->queue_address != 0 &&
345 q->queue_percent > 0 &&
346 !q->is_evicted);
347
348 return 0;
349}
350
351/*
352 * * preempt type here is ignored because there is only one way
353 * * to preempt sdma queue
354 */
355static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
356 enum kfd_preempt_type type,
357 unsigned int timeout, uint32_t pipe_id,
358 uint32_t queue_id)
359{
360 return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout);
361}
362
363static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
364 uint64_t queue_address, uint32_t pipe_id,
365 uint32_t queue_id)
366{
367 return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
368}
369
370#if defined(CONFIG_DEBUG_FS)
371
372static int debugfs_show_mqd(struct seq_file *m, void *data)
373{
374 seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 32, 4,
375 data, sizeof(struct v9_mqd), false);
376 return 0;
377}
378
379static int debugfs_show_mqd_sdma(struct seq_file *m, void *data)
380{
381 seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 32, 4,
382 data, sizeof(struct v9_sdma_mqd), false);
383 return 0;
384}
385
386#endif
387
388struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
389 struct kfd_dev *dev)
390{
391 struct mqd_manager *mqd;
392
393 if (WARN_ON(type >= KFD_MQD_TYPE_MAX))
394 return NULL;
395
396 mqd = kzalloc(sizeof(*mqd), GFP_NOIO);
397 if (!mqd)
398 return NULL;
399
400 mqd->dev = dev;
401
402 switch (type) {
403 case KFD_MQD_TYPE_CP:
404 case KFD_MQD_TYPE_COMPUTE:
405 mqd->init_mqd = init_mqd;
406 mqd->uninit_mqd = uninit_mqd;
407 mqd->load_mqd = load_mqd;
408 mqd->update_mqd = update_mqd;
409 mqd->destroy_mqd = destroy_mqd;
410 mqd->is_occupied = is_occupied;
411#if defined(CONFIG_DEBUG_FS)
412 mqd->debugfs_show_mqd = debugfs_show_mqd;
413#endif
414 break;
415 case KFD_MQD_TYPE_HIQ:
416 mqd->init_mqd = init_mqd_hiq;
417 mqd->uninit_mqd = uninit_mqd;
418 mqd->load_mqd = load_mqd;
419 mqd->update_mqd = update_mqd_hiq;
420 mqd->destroy_mqd = destroy_mqd;
421 mqd->is_occupied = is_occupied;
422#if defined(CONFIG_DEBUG_FS)
423 mqd->debugfs_show_mqd = debugfs_show_mqd;
424#endif
425 break;
426 case KFD_MQD_TYPE_SDMA:
427 mqd->init_mqd = init_mqd_sdma;
428 mqd->uninit_mqd = uninit_mqd_sdma;
429 mqd->load_mqd = load_mqd_sdma;
430 mqd->update_mqd = update_mqd_sdma;
431 mqd->destroy_mqd = destroy_mqd_sdma;
432 mqd->is_occupied = is_occupied_sdma;
433#if defined(CONFIG_DEBUG_FS)
434 mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
435#endif
436 break;
437 default:
438 kfree(mqd);
439 return NULL;
440 }
441
442 return mqd;
443}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
index 89e4242e43e7..481307b8b4db 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
@@ -394,7 +394,7 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
394 if (WARN_ON(type >= KFD_MQD_TYPE_MAX)) 394 if (WARN_ON(type >= KFD_MQD_TYPE_MAX))
395 return NULL; 395 return NULL;
396 396
397 mqd = kzalloc(sizeof(*mqd), GFP_KERNEL); 397 mqd = kzalloc(sizeof(*mqd), GFP_NOIO);
398 if (!mqd) 398 if (!mqd)
399 return NULL; 399 return NULL;
400 400
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
index 89ba4c670ec5..c317feb43f69 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
@@ -26,8 +26,6 @@
26#include "kfd_device_queue_manager.h" 26#include "kfd_device_queue_manager.h"
27#include "kfd_kernel_queue.h" 27#include "kfd_kernel_queue.h"
28#include "kfd_priv.h" 28#include "kfd_priv.h"
29#include "kfd_pm4_headers_vi.h"
30#include "kfd_pm4_opcodes.h"
31 29
32static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes, 30static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes,
33 unsigned int buffer_size_bytes) 31 unsigned int buffer_size_bytes)
@@ -39,18 +37,6 @@ static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes,
39 *wptr = temp; 37 *wptr = temp;
40} 38}
41 39
42static unsigned int build_pm4_header(unsigned int opcode, size_t packet_size)
43{
44 union PM4_MES_TYPE_3_HEADER header;
45
46 header.u32All = 0;
47 header.opcode = opcode;
48 header.count = packet_size / 4 - 2;
49 header.type = PM4_TYPE_3;
50
51 return header.u32All;
52}
53
54static void pm_calc_rlib_size(struct packet_manager *pm, 40static void pm_calc_rlib_size(struct packet_manager *pm,
55 unsigned int *rlib_size, 41 unsigned int *rlib_size,
56 bool *over_subscription) 42 bool *over_subscription)
@@ -80,9 +66,9 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
80 pr_debug("Over subscribed runlist\n"); 66 pr_debug("Over subscribed runlist\n");
81 } 67 }
82 68
83 map_queue_size = sizeof(struct pm4_mes_map_queues); 69 map_queue_size = pm->pmf->map_queues_size;
84 /* calculate run list ib allocation size */ 70 /* calculate run list ib allocation size */
85 *rlib_size = process_count * sizeof(struct pm4_mes_map_process) + 71 *rlib_size = process_count * pm->pmf->map_process_size +
86 queue_count * map_queue_size; 72 queue_count * map_queue_size;
87 73
88 /* 74 /*
@@ -90,7 +76,7 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
90 * when over subscription 76 * when over subscription
91 */ 77 */
92 if (*over_subscription) 78 if (*over_subscription)
93 *rlib_size += sizeof(struct pm4_mes_runlist); 79 *rlib_size += pm->pmf->runlist_size;
94 80
95 pr_debug("runlist ib size %d\n", *rlib_size); 81 pr_debug("runlist ib size %d\n", *rlib_size);
96} 82}
@@ -108,12 +94,14 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm,
108 94
109 pm_calc_rlib_size(pm, rl_buffer_size, is_over_subscription); 95 pm_calc_rlib_size(pm, rl_buffer_size, is_over_subscription);
110 96
97 mutex_lock(&pm->lock);
98
111 retval = kfd_gtt_sa_allocate(pm->dqm->dev, *rl_buffer_size, 99 retval = kfd_gtt_sa_allocate(pm->dqm->dev, *rl_buffer_size,
112 &pm->ib_buffer_obj); 100 &pm->ib_buffer_obj);
113 101
114 if (retval) { 102 if (retval) {
115 pr_err("Failed to allocate runlist IB\n"); 103 pr_err("Failed to allocate runlist IB\n");
116 return retval; 104 goto out;
117 } 105 }
118 106
119 *(void **)rl_buffer = pm->ib_buffer_obj->cpu_ptr; 107 *(void **)rl_buffer = pm->ib_buffer_obj->cpu_ptr;
@@ -121,138 +109,10 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm,
121 109
122 memset(*rl_buffer, 0, *rl_buffer_size); 110 memset(*rl_buffer, 0, *rl_buffer_size);
123 pm->allocated = true; 111 pm->allocated = true;
124 return retval;
125}
126
127static int pm_create_runlist(struct packet_manager *pm, uint32_t *buffer,
128 uint64_t ib, size_t ib_size_in_dwords, bool chain)
129{
130 struct pm4_mes_runlist *packet;
131 int concurrent_proc_cnt = 0;
132 struct kfd_dev *kfd = pm->dqm->dev;
133
134 if (WARN_ON(!ib))
135 return -EFAULT;
136
137 /* Determine the number of processes to map together to HW:
138 * it can not exceed the number of VMIDs available to the
139 * scheduler, and it is determined by the smaller of the number
140 * of processes in the runlist and kfd module parameter
141 * hws_max_conc_proc.
142 * Note: the arbitration between the number of VMIDs and
143 * hws_max_conc_proc has been done in
144 * kgd2kfd_device_init().
145 */
146 concurrent_proc_cnt = min(pm->dqm->processes_count,
147 kfd->max_proc_per_quantum);
148
149 packet = (struct pm4_mes_runlist *)buffer;
150
151 memset(buffer, 0, sizeof(struct pm4_mes_runlist));
152 packet->header.u32All = build_pm4_header(IT_RUN_LIST,
153 sizeof(struct pm4_mes_runlist));
154
155 packet->bitfields4.ib_size = ib_size_in_dwords;
156 packet->bitfields4.chain = chain ? 1 : 0;
157 packet->bitfields4.offload_polling = 0;
158 packet->bitfields4.valid = 1;
159 packet->bitfields4.process_cnt = concurrent_proc_cnt;
160 packet->ordinal2 = lower_32_bits(ib);
161 packet->bitfields3.ib_base_hi = upper_32_bits(ib);
162
163 return 0;
164}
165
166static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer,
167 struct qcm_process_device *qpd)
168{
169 struct pm4_mes_map_process *packet;
170
171 packet = (struct pm4_mes_map_process *)buffer;
172 112
173 memset(buffer, 0, sizeof(struct pm4_mes_map_process)); 113out:
174 114 mutex_unlock(&pm->lock);
175 packet->header.u32All = build_pm4_header(IT_MAP_PROCESS, 115 return retval;
176 sizeof(struct pm4_mes_map_process));
177 packet->bitfields2.diq_enable = (qpd->is_debug) ? 1 : 0;
178 packet->bitfields2.process_quantum = 1;
179 packet->bitfields2.pasid = qpd->pqm->process->pasid;
180 packet->bitfields3.page_table_base = qpd->page_table_base;
181 packet->bitfields10.gds_size = qpd->gds_size;
182 packet->bitfields10.num_gws = qpd->num_gws;
183 packet->bitfields10.num_oac = qpd->num_oac;
184 packet->bitfields10.num_queues = (qpd->is_debug) ? 0 : qpd->queue_count;
185
186 packet->sh_mem_config = qpd->sh_mem_config;
187 packet->sh_mem_bases = qpd->sh_mem_bases;
188 packet->sh_mem_ape1_base = qpd->sh_mem_ape1_base;
189 packet->sh_mem_ape1_limit = qpd->sh_mem_ape1_limit;
190
191 packet->sh_hidden_private_base_vmid = qpd->sh_hidden_private_base;
192
193 packet->gds_addr_lo = lower_32_bits(qpd->gds_context_area);
194 packet->gds_addr_hi = upper_32_bits(qpd->gds_context_area);
195
196 return 0;
197}
198
199static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer,
200 struct queue *q, bool is_static)
201{
202 struct pm4_mes_map_queues *packet;
203 bool use_static = is_static;
204
205 packet = (struct pm4_mes_map_queues *)buffer;
206 memset(buffer, 0, sizeof(struct pm4_mes_map_queues));
207
208 packet->header.u32All = build_pm4_header(IT_MAP_QUEUES,
209 sizeof(struct pm4_mes_map_queues));
210 packet->bitfields2.alloc_format =
211 alloc_format__mes_map_queues__one_per_pipe_vi;
212 packet->bitfields2.num_queues = 1;
213 packet->bitfields2.queue_sel =
214 queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi;
215
216 packet->bitfields2.engine_sel =
217 engine_sel__mes_map_queues__compute_vi;
218 packet->bitfields2.queue_type =
219 queue_type__mes_map_queues__normal_compute_vi;
220
221 switch (q->properties.type) {
222 case KFD_QUEUE_TYPE_COMPUTE:
223 if (use_static)
224 packet->bitfields2.queue_type =
225 queue_type__mes_map_queues__normal_latency_static_queue_vi;
226 break;
227 case KFD_QUEUE_TYPE_DIQ:
228 packet->bitfields2.queue_type =
229 queue_type__mes_map_queues__debug_interface_queue_vi;
230 break;
231 case KFD_QUEUE_TYPE_SDMA:
232 packet->bitfields2.engine_sel = q->properties.sdma_engine_id +
233 engine_sel__mes_map_queues__sdma0_vi;
234 use_static = false; /* no static queues under SDMA */
235 break;
236 default:
237 WARN(1, "queue type %d", q->properties.type);
238 return -EINVAL;
239 }
240 packet->bitfields3.doorbell_offset =
241 q->properties.doorbell_off;
242
243 packet->mqd_addr_lo =
244 lower_32_bits(q->gart_mqd_addr);
245
246 packet->mqd_addr_hi =
247 upper_32_bits(q->gart_mqd_addr);
248
249 packet->wptr_addr_lo =
250 lower_32_bits((uint64_t)q->properties.write_ptr);
251
252 packet->wptr_addr_hi =
253 upper_32_bits((uint64_t)q->properties.write_ptr);
254
255 return 0;
256} 116}
257 117
258static int pm_create_runlist_ib(struct packet_manager *pm, 118static int pm_create_runlist_ib(struct packet_manager *pm,
@@ -292,12 +152,12 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
292 return -ENOMEM; 152 return -ENOMEM;
293 } 153 }
294 154
295 retval = pm_create_map_process(pm, &rl_buffer[rl_wptr], qpd); 155 retval = pm->pmf->map_process(pm, &rl_buffer[rl_wptr], qpd);
296 if (retval) 156 if (retval)
297 return retval; 157 return retval;
298 158
299 proccesses_mapped++; 159 proccesses_mapped++;
300 inc_wptr(&rl_wptr, sizeof(struct pm4_mes_map_process), 160 inc_wptr(&rl_wptr, pm->pmf->map_process_size,
301 alloc_size_bytes); 161 alloc_size_bytes);
302 162
303 list_for_each_entry(kq, &qpd->priv_queue_list, list) { 163 list_for_each_entry(kq, &qpd->priv_queue_list, list) {
@@ -307,7 +167,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
307 pr_debug("static_queue, mapping kernel q %d, is debug status %d\n", 167 pr_debug("static_queue, mapping kernel q %d, is debug status %d\n",
308 kq->queue->queue, qpd->is_debug); 168 kq->queue->queue, qpd->is_debug);
309 169
310 retval = pm_create_map_queue(pm, 170 retval = pm->pmf->map_queues(pm,
311 &rl_buffer[rl_wptr], 171 &rl_buffer[rl_wptr],
312 kq->queue, 172 kq->queue,
313 qpd->is_debug); 173 qpd->is_debug);
@@ -315,7 +175,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
315 return retval; 175 return retval;
316 176
317 inc_wptr(&rl_wptr, 177 inc_wptr(&rl_wptr,
318 sizeof(struct pm4_mes_map_queues), 178 pm->pmf->map_queues_size,
319 alloc_size_bytes); 179 alloc_size_bytes);
320 } 180 }
321 181
@@ -326,7 +186,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
326 pr_debug("static_queue, mapping user queue %d, is debug status %d\n", 186 pr_debug("static_queue, mapping user queue %d, is debug status %d\n",
327 q->queue, qpd->is_debug); 187 q->queue, qpd->is_debug);
328 188
329 retval = pm_create_map_queue(pm, 189 retval = pm->pmf->map_queues(pm,
330 &rl_buffer[rl_wptr], 190 &rl_buffer[rl_wptr],
331 q, 191 q,
332 qpd->is_debug); 192 qpd->is_debug);
@@ -335,7 +195,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
335 return retval; 195 return retval;
336 196
337 inc_wptr(&rl_wptr, 197 inc_wptr(&rl_wptr,
338 sizeof(struct pm4_mes_map_queues), 198 pm->pmf->map_queues_size,
339 alloc_size_bytes); 199 alloc_size_bytes);
340 } 200 }
341 } 201 }
@@ -343,7 +203,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
343 pr_debug("Finished map process and queues to runlist\n"); 203 pr_debug("Finished map process and queues to runlist\n");
344 204
345 if (is_over_subscription) 205 if (is_over_subscription)
346 retval = pm_create_runlist(pm, &rl_buffer[rl_wptr], 206 retval = pm->pmf->runlist(pm, &rl_buffer[rl_wptr],
347 *rl_gpu_addr, 207 *rl_gpu_addr,
348 alloc_size_bytes / sizeof(uint32_t), 208 alloc_size_bytes / sizeof(uint32_t),
349 true); 209 true);
@@ -355,45 +215,29 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
355 return retval; 215 return retval;
356} 216}
357 217
358/* pm_create_release_mem - Create a RELEASE_MEM packet and return the size
359 * of this packet
360 * @gpu_addr - GPU address of the packet. It's a virtual address.
361 * @buffer - buffer to fill up with the packet. It's a CPU kernel pointer
362 * Return - length of the packet
363 */
364uint32_t pm_create_release_mem(uint64_t gpu_addr, uint32_t *buffer)
365{
366 struct pm4_mec_release_mem *packet;
367
368 WARN_ON(!buffer);
369
370 packet = (struct pm4_mec_release_mem *)buffer;
371 memset(buffer, 0, sizeof(*packet));
372
373 packet->header.u32All = build_pm4_header(IT_RELEASE_MEM,
374 sizeof(*packet));
375
376 packet->bitfields2.event_type = CACHE_FLUSH_AND_INV_TS_EVENT;
377 packet->bitfields2.event_index = event_index___release_mem__end_of_pipe;
378 packet->bitfields2.tcl1_action_ena = 1;
379 packet->bitfields2.tc_action_ena = 1;
380 packet->bitfields2.cache_policy = cache_policy___release_mem__lru;
381 packet->bitfields2.atc = 0;
382
383 packet->bitfields3.data_sel = data_sel___release_mem__send_32_bit_low;
384 packet->bitfields3.int_sel =
385 int_sel___release_mem__send_interrupt_after_write_confirm;
386
387 packet->bitfields4.address_lo_32b = (gpu_addr & 0xffffffff) >> 2;
388 packet->address_hi = upper_32_bits(gpu_addr);
389
390 packet->data_lo = 0;
391
392 return sizeof(*packet) / sizeof(unsigned int);
393}
394
395int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm) 218int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm)
396{ 219{
220 switch (dqm->dev->device_info->asic_family) {
221 case CHIP_KAVERI:
222 case CHIP_HAWAII:
223 /* PM4 packet structures on CIK are the same as on VI */
224 case CHIP_CARRIZO:
225 case CHIP_TONGA:
226 case CHIP_FIJI:
227 case CHIP_POLARIS10:
228 case CHIP_POLARIS11:
229 pm->pmf = &kfd_vi_pm_funcs;
230 break;
231 case CHIP_VEGA10:
232 case CHIP_RAVEN:
233 pm->pmf = &kfd_v9_pm_funcs;
234 break;
235 default:
236 WARN(1, "Unexpected ASIC family %u",
237 dqm->dev->device_info->asic_family);
238 return -EINVAL;
239 }
240
397 pm->dqm = dqm; 241 pm->dqm = dqm;
398 mutex_init(&pm->lock); 242 mutex_init(&pm->lock);
399 pm->priv_queue = kernel_queue_init(dqm->dev, KFD_QUEUE_TYPE_HIQ); 243 pm->priv_queue = kernel_queue_init(dqm->dev, KFD_QUEUE_TYPE_HIQ);
@@ -415,38 +259,25 @@ void pm_uninit(struct packet_manager *pm)
415int pm_send_set_resources(struct packet_manager *pm, 259int pm_send_set_resources(struct packet_manager *pm,
416 struct scheduling_resources *res) 260 struct scheduling_resources *res)
417{ 261{
418 struct pm4_mes_set_resources *packet; 262 uint32_t *buffer, size;
419 int retval = 0; 263 int retval = 0;
420 264
265 size = pm->pmf->set_resources_size;
421 mutex_lock(&pm->lock); 266 mutex_lock(&pm->lock);
422 pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue, 267 pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
423 sizeof(*packet) / sizeof(uint32_t), 268 size / sizeof(uint32_t),
424 (unsigned int **)&packet); 269 (unsigned int **)&buffer);
425 if (!packet) { 270 if (!buffer) {
426 pr_err("Failed to allocate buffer on kernel queue\n"); 271 pr_err("Failed to allocate buffer on kernel queue\n");
427 retval = -ENOMEM; 272 retval = -ENOMEM;
428 goto out; 273 goto out;
429 } 274 }
430 275
431 memset(packet, 0, sizeof(struct pm4_mes_set_resources)); 276 retval = pm->pmf->set_resources(pm, buffer, res);
432 packet->header.u32All = build_pm4_header(IT_SET_RESOURCES, 277 if (!retval)
433 sizeof(struct pm4_mes_set_resources)); 278 pm->priv_queue->ops.submit_packet(pm->priv_queue);
434 279 else
435 packet->bitfields2.queue_type = 280 pm->priv_queue->ops.rollback_packet(pm->priv_queue);
436 queue_type__mes_set_resources__hsa_interface_queue_hiq;
437 packet->bitfields2.vmid_mask = res->vmid_mask;
438 packet->bitfields2.unmap_latency = KFD_UNMAP_LATENCY_MS / 100;
439 packet->bitfields7.oac_mask = res->oac_mask;
440 packet->bitfields8.gds_heap_base = res->gds_heap_base;
441 packet->bitfields8.gds_heap_size = res->gds_heap_size;
442
443 packet->gws_mask_lo = lower_32_bits(res->gws_mask);
444 packet->gws_mask_hi = upper_32_bits(res->gws_mask);
445
446 packet->queue_mask_lo = lower_32_bits(res->queue_mask);
447 packet->queue_mask_hi = upper_32_bits(res->queue_mask);
448
449 pm->priv_queue->ops.submit_packet(pm->priv_queue);
450 281
451out: 282out:
452 mutex_unlock(&pm->lock); 283 mutex_unlock(&pm->lock);
@@ -468,7 +299,7 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
468 299
469 pr_debug("runlist IB address: 0x%llX\n", rl_gpu_ib_addr); 300 pr_debug("runlist IB address: 0x%llX\n", rl_gpu_ib_addr);
470 301
471 packet_size_dwords = sizeof(struct pm4_mes_runlist) / sizeof(uint32_t); 302 packet_size_dwords = pm->pmf->runlist_size / sizeof(uint32_t);
472 mutex_lock(&pm->lock); 303 mutex_lock(&pm->lock);
473 304
474 retval = pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue, 305 retval = pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
@@ -476,7 +307,7 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
476 if (retval) 307 if (retval)
477 goto fail_acquire_packet_buffer; 308 goto fail_acquire_packet_buffer;
478 309
479 retval = pm_create_runlist(pm, rl_buffer, rl_gpu_ib_addr, 310 retval = pm->pmf->runlist(pm, rl_buffer, rl_gpu_ib_addr,
480 rl_ib_size / sizeof(uint32_t), false); 311 rl_ib_size / sizeof(uint32_t), false);
481 if (retval) 312 if (retval)
482 goto fail_create_runlist; 313 goto fail_create_runlist;
@@ -499,37 +330,29 @@ fail_create_runlist_ib:
499int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, 330int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
500 uint32_t fence_value) 331 uint32_t fence_value)
501{ 332{
502 int retval; 333 uint32_t *buffer, size;
503 struct pm4_mes_query_status *packet; 334 int retval = 0;
504 335
505 if (WARN_ON(!fence_address)) 336 if (WARN_ON(!fence_address))
506 return -EFAULT; 337 return -EFAULT;
507 338
339 size = pm->pmf->query_status_size;
508 mutex_lock(&pm->lock); 340 mutex_lock(&pm->lock);
509 retval = pm->priv_queue->ops.acquire_packet_buffer( 341 pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
510 pm->priv_queue, 342 size / sizeof(uint32_t), (unsigned int **)&buffer);
511 sizeof(struct pm4_mes_query_status) / sizeof(uint32_t), 343 if (!buffer) {
512 (unsigned int **)&packet); 344 pr_err("Failed to allocate buffer on kernel queue\n");
513 if (retval) 345 retval = -ENOMEM;
514 goto fail_acquire_packet_buffer; 346 goto out;
515 347 }
516 packet->header.u32All = build_pm4_header(IT_QUERY_STATUS,
517 sizeof(struct pm4_mes_query_status));
518
519 packet->bitfields2.context_id = 0;
520 packet->bitfields2.interrupt_sel =
521 interrupt_sel__mes_query_status__completion_status;
522 packet->bitfields2.command =
523 command__mes_query_status__fence_only_after_write_ack;
524
525 packet->addr_hi = upper_32_bits((uint64_t)fence_address);
526 packet->addr_lo = lower_32_bits((uint64_t)fence_address);
527 packet->data_hi = upper_32_bits((uint64_t)fence_value);
528 packet->data_lo = lower_32_bits((uint64_t)fence_value);
529 348
530 pm->priv_queue->ops.submit_packet(pm->priv_queue); 349 retval = pm->pmf->query_status(pm, buffer, fence_address, fence_value);
350 if (!retval)
351 pm->priv_queue->ops.submit_packet(pm->priv_queue);
352 else
353 pm->priv_queue->ops.rollback_packet(pm->priv_queue);
531 354
532fail_acquire_packet_buffer: 355out:
533 mutex_unlock(&pm->lock); 356 mutex_unlock(&pm->lock);
534 return retval; 357 return retval;
535} 358}
@@ -539,82 +362,27 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
539 uint32_t filter_param, bool reset, 362 uint32_t filter_param, bool reset,
540 unsigned int sdma_engine) 363 unsigned int sdma_engine)
541{ 364{
542 int retval; 365 uint32_t *buffer, size;
543 uint32_t *buffer; 366 int retval = 0;
544 struct pm4_mes_unmap_queues *packet;
545 367
368 size = pm->pmf->unmap_queues_size;
546 mutex_lock(&pm->lock); 369 mutex_lock(&pm->lock);
547 retval = pm->priv_queue->ops.acquire_packet_buffer( 370 pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
548 pm->priv_queue, 371 size / sizeof(uint32_t), (unsigned int **)&buffer);
549 sizeof(struct pm4_mes_unmap_queues) / sizeof(uint32_t), 372 if (!buffer) {
550 &buffer); 373 pr_err("Failed to allocate buffer on kernel queue\n");
551 if (retval) 374 retval = -ENOMEM;
552 goto err_acquire_packet_buffer; 375 goto out;
553
554 packet = (struct pm4_mes_unmap_queues *)buffer;
555 memset(buffer, 0, sizeof(struct pm4_mes_unmap_queues));
556 pr_debug("static_queue: unmapping queues: filter is %d , reset is %d , type is %d\n",
557 filter, reset, type);
558 packet->header.u32All = build_pm4_header(IT_UNMAP_QUEUES,
559 sizeof(struct pm4_mes_unmap_queues));
560 switch (type) {
561 case KFD_QUEUE_TYPE_COMPUTE:
562 case KFD_QUEUE_TYPE_DIQ:
563 packet->bitfields2.engine_sel =
564 engine_sel__mes_unmap_queues__compute;
565 break;
566 case KFD_QUEUE_TYPE_SDMA:
567 packet->bitfields2.engine_sel =
568 engine_sel__mes_unmap_queues__sdma0 + sdma_engine;
569 break;
570 default:
571 WARN(1, "queue type %d", type);
572 retval = -EINVAL;
573 goto err_invalid;
574 } 376 }
575 377
576 if (reset) 378 retval = pm->pmf->unmap_queues(pm, buffer, type, filter, filter_param,
577 packet->bitfields2.action = 379 reset, sdma_engine);
578 action__mes_unmap_queues__reset_queues; 380 if (!retval)
381 pm->priv_queue->ops.submit_packet(pm->priv_queue);
579 else 382 else
580 packet->bitfields2.action = 383 pm->priv_queue->ops.rollback_packet(pm->priv_queue);
581 action__mes_unmap_queues__preempt_queues;
582
583 switch (filter) {
584 case KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE:
585 packet->bitfields2.queue_sel =
586 queue_sel__mes_unmap_queues__perform_request_on_specified_queues;
587 packet->bitfields2.num_queues = 1;
588 packet->bitfields3b.doorbell_offset0 = filter_param;
589 break;
590 case KFD_UNMAP_QUEUES_FILTER_BY_PASID:
591 packet->bitfields2.queue_sel =
592 queue_sel__mes_unmap_queues__perform_request_on_pasid_queues;
593 packet->bitfields3a.pasid = filter_param;
594 break;
595 case KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES:
596 packet->bitfields2.queue_sel =
597 queue_sel__mes_unmap_queues__unmap_all_queues;
598 break;
599 case KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES:
600 /* in this case, we do not preempt static queues */
601 packet->bitfields2.queue_sel =
602 queue_sel__mes_unmap_queues__unmap_all_non_static_queues;
603 break;
604 default:
605 WARN(1, "filter %d", filter);
606 retval = -EINVAL;
607 goto err_invalid;
608 }
609 384
610 pm->priv_queue->ops.submit_packet(pm->priv_queue); 385out:
611
612 mutex_unlock(&pm->lock);
613 return 0;
614
615err_invalid:
616 pm->priv_queue->ops.rollback_packet(pm->priv_queue);
617err_acquire_packet_buffer:
618 mutex_unlock(&pm->lock); 386 mutex_unlock(&pm->lock);
619 return retval; 387 return retval;
620} 388}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h
new file mode 100644
index 000000000000..f2bcf5c092ea
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h
@@ -0,0 +1,583 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#ifndef F32_MES_PM4_PACKETS_H
25#define F32_MES_PM4_PACKETS_H
26
27#ifndef PM4_MES_HEADER_DEFINED
28#define PM4_MES_HEADER_DEFINED
29union PM4_MES_TYPE_3_HEADER {
30 struct {
31 uint32_t reserved1 : 8; /* < reserved */
32 uint32_t opcode : 8; /* < IT opcode */
33 uint32_t count : 14;/* < number of DWORDs - 1 in the
34 * information body.
35 */
36 uint32_t type : 2; /* < packet identifier.
37 * It should be 3 for type 3 packets
38 */
39 };
40 uint32_t u32All;
41};
42#endif /* PM4_MES_HEADER_DEFINED */
43
44/*--------------------MES_SET_RESOURCES--------------------*/
45
46#ifndef PM4_MES_SET_RESOURCES_DEFINED
47#define PM4_MES_SET_RESOURCES_DEFINED
48enum mes_set_resources_queue_type_enum {
49 queue_type__mes_set_resources__kernel_interface_queue_kiq = 0,
50 queue_type__mes_set_resources__hsa_interface_queue_hiq = 1,
51 queue_type__mes_set_resources__hsa_debug_interface_queue = 4
52};
53
54
55struct pm4_mes_set_resources {
56 union {
57 union PM4_MES_TYPE_3_HEADER header; /* header */
58 uint32_t ordinal1;
59 };
60
61 union {
62 struct {
63 uint32_t vmid_mask:16;
64 uint32_t unmap_latency:8;
65 uint32_t reserved1:5;
66 enum mes_set_resources_queue_type_enum queue_type:3;
67 } bitfields2;
68 uint32_t ordinal2;
69 };
70
71 uint32_t queue_mask_lo;
72 uint32_t queue_mask_hi;
73 uint32_t gws_mask_lo;
74 uint32_t gws_mask_hi;
75
76 union {
77 struct {
78 uint32_t oac_mask:16;
79 uint32_t reserved2:16;
80 } bitfields7;
81 uint32_t ordinal7;
82 };
83
84 union {
85 struct {
86 uint32_t gds_heap_base:6;
87 uint32_t reserved3:5;
88 uint32_t gds_heap_size:6;
89 uint32_t reserved4:15;
90 } bitfields8;
91 uint32_t ordinal8;
92 };
93
94};
95#endif
96
97/*--------------------MES_RUN_LIST--------------------*/
98
99#ifndef PM4_MES_RUN_LIST_DEFINED
100#define PM4_MES_RUN_LIST_DEFINED
101
102struct pm4_mes_runlist {
103 union {
104 union PM4_MES_TYPE_3_HEADER header; /* header */
105 uint32_t ordinal1;
106 };
107
108 union {
109 struct {
110 uint32_t reserved1:2;
111 uint32_t ib_base_lo:30;
112 } bitfields2;
113 uint32_t ordinal2;
114 };
115
116 uint32_t ib_base_hi;
117
118 union {
119 struct {
120 uint32_t ib_size:20;
121 uint32_t chain:1;
122 uint32_t offload_polling:1;
123 uint32_t reserved2:1;
124 uint32_t valid:1;
125 uint32_t process_cnt:4;
126 uint32_t reserved3:4;
127 } bitfields4;
128 uint32_t ordinal4;
129 };
130
131};
132#endif
133
134/*--------------------MES_MAP_PROCESS--------------------*/
135
136#ifndef PM4_MES_MAP_PROCESS_DEFINED
137#define PM4_MES_MAP_PROCESS_DEFINED
138
139struct pm4_mes_map_process {
140 union {
141 union PM4_MES_TYPE_3_HEADER header; /* header */
142 uint32_t ordinal1;
143 };
144
145 union {
146 struct {
147 uint32_t pasid:16;
148 uint32_t reserved1:8;
149 uint32_t diq_enable:1;
150 uint32_t process_quantum:7;
151 } bitfields2;
152 uint32_t ordinal2;
153 };
154
155 uint32_t vm_context_page_table_base_addr_lo32;
156
157 uint32_t vm_context_page_table_base_addr_hi32;
158
159 uint32_t sh_mem_bases;
160
161 uint32_t sh_mem_config;
162
163 uint32_t sq_shader_tba_lo;
164
165 uint32_t sq_shader_tba_hi;
166
167 uint32_t sq_shader_tma_lo;
168
169 uint32_t sq_shader_tma_hi;
170
171 uint32_t reserved6;
172
173 uint32_t gds_addr_lo;
174
175 uint32_t gds_addr_hi;
176
177 union {
178 struct {
179 uint32_t num_gws:6;
180 uint32_t reserved7:1;
181 uint32_t sdma_enable:1;
182 uint32_t num_oac:4;
183 uint32_t reserved8:4;
184 uint32_t gds_size:6;
185 uint32_t num_queues:10;
186 } bitfields14;
187 uint32_t ordinal14;
188 };
189
190 uint32_t completion_signal_lo;
191
192 uint32_t completion_signal_hi;
193
194};
195
196#endif
197
198/*--------------------MES_MAP_PROCESS_VM--------------------*/
199
200#ifndef PM4_MES_MAP_PROCESS_VM_DEFINED
201#define PM4_MES_MAP_PROCESS_VM_DEFINED
202
203struct PM4_MES_MAP_PROCESS_VM {
204 union {
205 union PM4_MES_TYPE_3_HEADER header; /* header */
206 uint32_t ordinal1;
207 };
208
209 uint32_t reserved1;
210
211 uint32_t vm_context_cntl;
212
213 uint32_t reserved2;
214
215 uint32_t vm_context_page_table_end_addr_lo32;
216
217 uint32_t vm_context_page_table_end_addr_hi32;
218
219 uint32_t vm_context_page_table_start_addr_lo32;
220
221 uint32_t vm_context_page_table_start_addr_hi32;
222
223 uint32_t reserved3;
224
225 uint32_t reserved4;
226
227 uint32_t reserved5;
228
229 uint32_t reserved6;
230
231 uint32_t reserved7;
232
233 uint32_t reserved8;
234
235 uint32_t completion_signal_lo32;
236
237 uint32_t completion_signal_hi32;
238
239};
240#endif
241
242/*--------------------MES_MAP_QUEUES--------------------*/
243
244#ifndef PM4_MES_MAP_QUEUES_VI_DEFINED
245#define PM4_MES_MAP_QUEUES_VI_DEFINED
246enum mes_map_queues_queue_sel_enum {
247 queue_sel__mes_map_queues__map_to_specified_queue_slots_vi = 0,
248queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi = 1
249};
250
251enum mes_map_queues_queue_type_enum {
252 queue_type__mes_map_queues__normal_compute_vi = 0,
253 queue_type__mes_map_queues__debug_interface_queue_vi = 1,
254 queue_type__mes_map_queues__normal_latency_static_queue_vi = 2,
255queue_type__mes_map_queues__low_latency_static_queue_vi = 3
256};
257
258enum mes_map_queues_alloc_format_enum {
259 alloc_format__mes_map_queues__one_per_pipe_vi = 0,
260alloc_format__mes_map_queues__all_on_one_pipe_vi = 1
261};
262
263enum mes_map_queues_engine_sel_enum {
264 engine_sel__mes_map_queues__compute_vi = 0,
265 engine_sel__mes_map_queues__sdma0_vi = 2,
266 engine_sel__mes_map_queues__sdma1_vi = 3
267};
268
269
270struct pm4_mes_map_queues {
271 union {
272 union PM4_MES_TYPE_3_HEADER header; /* header */
273 uint32_t ordinal1;
274 };
275
276 union {
277 struct {
278 uint32_t reserved1:4;
279 enum mes_map_queues_queue_sel_enum queue_sel:2;
280 uint32_t reserved2:15;
281 enum mes_map_queues_queue_type_enum queue_type:3;
282 enum mes_map_queues_alloc_format_enum alloc_format:2;
283 enum mes_map_queues_engine_sel_enum engine_sel:3;
284 uint32_t num_queues:3;
285 } bitfields2;
286 uint32_t ordinal2;
287 };
288
289 union {
290 struct {
291 uint32_t reserved3:1;
292 uint32_t check_disable:1;
293 uint32_t doorbell_offset:26;
294 uint32_t reserved4:4;
295 } bitfields3;
296 uint32_t ordinal3;
297 };
298
299 uint32_t mqd_addr_lo;
300 uint32_t mqd_addr_hi;
301 uint32_t wptr_addr_lo;
302 uint32_t wptr_addr_hi;
303};
304#endif
305
306/*--------------------MES_QUERY_STATUS--------------------*/
307
308#ifndef PM4_MES_QUERY_STATUS_DEFINED
309#define PM4_MES_QUERY_STATUS_DEFINED
310enum mes_query_status_interrupt_sel_enum {
311 interrupt_sel__mes_query_status__completion_status = 0,
312 interrupt_sel__mes_query_status__process_status = 1,
313 interrupt_sel__mes_query_status__queue_status = 2
314};
315
316enum mes_query_status_command_enum {
317 command__mes_query_status__interrupt_only = 0,
318 command__mes_query_status__fence_only_immediate = 1,
319 command__mes_query_status__fence_only_after_write_ack = 2,
320 command__mes_query_status__fence_wait_for_write_ack_send_interrupt = 3
321};
322
323enum mes_query_status_engine_sel_enum {
324 engine_sel__mes_query_status__compute = 0,
325 engine_sel__mes_query_status__sdma0_queue = 2,
326 engine_sel__mes_query_status__sdma1_queue = 3
327};
328
329struct pm4_mes_query_status {
330 union {
331 union PM4_MES_TYPE_3_HEADER header; /* header */
332 uint32_t ordinal1;
333 };
334
335 union {
336 struct {
337 uint32_t context_id:28;
338 enum mes_query_status_interrupt_sel_enum interrupt_sel:2;
339 enum mes_query_status_command_enum command:2;
340 } bitfields2;
341 uint32_t ordinal2;
342 };
343
344 union {
345 struct {
346 uint32_t pasid:16;
347 uint32_t reserved1:16;
348 } bitfields3a;
349 struct {
350 uint32_t reserved2:2;
351 uint32_t doorbell_offset:26;
352 enum mes_query_status_engine_sel_enum engine_sel:3;
353 uint32_t reserved3:1;
354 } bitfields3b;
355 uint32_t ordinal3;
356 };
357
358 uint32_t addr_lo;
359 uint32_t addr_hi;
360 uint32_t data_lo;
361 uint32_t data_hi;
362};
363#endif
364
365/*--------------------MES_UNMAP_QUEUES--------------------*/
366
367#ifndef PM4_MES_UNMAP_QUEUES_DEFINED
368#define PM4_MES_UNMAP_QUEUES_DEFINED
369enum mes_unmap_queues_action_enum {
370 action__mes_unmap_queues__preempt_queues = 0,
371 action__mes_unmap_queues__reset_queues = 1,
372 action__mes_unmap_queues__disable_process_queues = 2,
373 action__mes_unmap_queues__reserved = 3
374};
375
376enum mes_unmap_queues_queue_sel_enum {
377 queue_sel__mes_unmap_queues__perform_request_on_specified_queues = 0,
378 queue_sel__mes_unmap_queues__perform_request_on_pasid_queues = 1,
379 queue_sel__mes_unmap_queues__unmap_all_queues = 2,
380 queue_sel__mes_unmap_queues__unmap_all_non_static_queues = 3
381};
382
383enum mes_unmap_queues_engine_sel_enum {
384 engine_sel__mes_unmap_queues__compute = 0,
385 engine_sel__mes_unmap_queues__sdma0 = 2,
386 engine_sel__mes_unmap_queues__sdmal = 3
387};
388
389struct pm4_mes_unmap_queues {
390 union {
391 union PM4_MES_TYPE_3_HEADER header; /* header */
392 uint32_t ordinal1;
393 };
394
395 union {
396 struct {
397 enum mes_unmap_queues_action_enum action:2;
398 uint32_t reserved1:2;
399 enum mes_unmap_queues_queue_sel_enum queue_sel:2;
400 uint32_t reserved2:20;
401 enum mes_unmap_queues_engine_sel_enum engine_sel:3;
402 uint32_t num_queues:3;
403 } bitfields2;
404 uint32_t ordinal2;
405 };
406
407 union {
408 struct {
409 uint32_t pasid:16;
410 uint32_t reserved3:16;
411 } bitfields3a;
412 struct {
413 uint32_t reserved4:2;
414 uint32_t doorbell_offset0:26;
415 int32_t reserved5:4;
416 } bitfields3b;
417 uint32_t ordinal3;
418 };
419
420 union {
421 struct {
422 uint32_t reserved6:2;
423 uint32_t doorbell_offset1:26;
424 uint32_t reserved7:4;
425 } bitfields4;
426 uint32_t ordinal4;
427 };
428
429 union {
430 struct {
431 uint32_t reserved8:2;
432 uint32_t doorbell_offset2:26;
433 uint32_t reserved9:4;
434 } bitfields5;
435 uint32_t ordinal5;
436 };
437
438 union {
439 struct {
440 uint32_t reserved10:2;
441 uint32_t doorbell_offset3:26;
442 uint32_t reserved11:4;
443 } bitfields6;
444 uint32_t ordinal6;
445 };
446};
447#endif
448
449#ifndef PM4_MEC_RELEASE_MEM_DEFINED
450#define PM4_MEC_RELEASE_MEM_DEFINED
451
452enum mec_release_mem_event_index_enum {
453 event_index__mec_release_mem__end_of_pipe = 5,
454 event_index__mec_release_mem__shader_done = 6
455};
456
457enum mec_release_mem_cache_policy_enum {
458 cache_policy__mec_release_mem__lru = 0,
459 cache_policy__mec_release_mem__stream = 1
460};
461
462enum mec_release_mem_pq_exe_status_enum {
463 pq_exe_status__mec_release_mem__default = 0,
464 pq_exe_status__mec_release_mem__phase_update = 1
465};
466
467enum mec_release_mem_dst_sel_enum {
468 dst_sel__mec_release_mem__memory_controller = 0,
469 dst_sel__mec_release_mem__tc_l2 = 1,
470 dst_sel__mec_release_mem__queue_write_pointer_register = 2,
471 dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit = 3
472};
473
474enum mec_release_mem_int_sel_enum {
475 int_sel__mec_release_mem__none = 0,
476 int_sel__mec_release_mem__send_interrupt_only = 1,
477 int_sel__mec_release_mem__send_interrupt_after_write_confirm = 2,
478 int_sel__mec_release_mem__send_data_after_write_confirm = 3,
479 int_sel__mec_release_mem__unconditionally_send_int_ctxid = 4,
480 int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare = 5,
481 int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare = 6
482};
483
484enum mec_release_mem_data_sel_enum {
485 data_sel__mec_release_mem__none = 0,
486 data_sel__mec_release_mem__send_32_bit_low = 1,
487 data_sel__mec_release_mem__send_64_bit_data = 2,
488 data_sel__mec_release_mem__send_gpu_clock_counter = 3,
489 data_sel__mec_release_mem__send_cp_perfcounter_hi_lo = 4,
490 data_sel__mec_release_mem__store_gds_data_to_memory = 5
491};
492
493struct pm4_mec_release_mem {
494 union {
495 union PM4_MES_TYPE_3_HEADER header; /*header */
496 unsigned int ordinal1;
497 };
498
499 union {
500 struct {
501 unsigned int event_type:6;
502 unsigned int reserved1:2;
503 enum mec_release_mem_event_index_enum event_index:4;
504 unsigned int tcl1_vol_action_ena:1;
505 unsigned int tc_vol_action_ena:1;
506 unsigned int reserved2:1;
507 unsigned int tc_wb_action_ena:1;
508 unsigned int tcl1_action_ena:1;
509 unsigned int tc_action_ena:1;
510 uint32_t reserved3:1;
511 uint32_t tc_nc_action_ena:1;
512 uint32_t tc_wc_action_ena:1;
513 uint32_t tc_md_action_ena:1;
514 uint32_t reserved4:3;
515 enum mec_release_mem_cache_policy_enum cache_policy:2;
516 uint32_t reserved5:2;
517 enum mec_release_mem_pq_exe_status_enum pq_exe_status:1;
518 uint32_t reserved6:2;
519 } bitfields2;
520 unsigned int ordinal2;
521 };
522
523 union {
524 struct {
525 uint32_t reserved7:16;
526 enum mec_release_mem_dst_sel_enum dst_sel:2;
527 uint32_t reserved8:6;
528 enum mec_release_mem_int_sel_enum int_sel:3;
529 uint32_t reserved9:2;
530 enum mec_release_mem_data_sel_enum data_sel:3;
531 } bitfields3;
532 unsigned int ordinal3;
533 };
534
535 union {
536 struct {
537 uint32_t reserved10:2;
538 unsigned int address_lo_32b:30;
539 } bitfields4;
540 struct {
541 uint32_t reserved11:3;
542 uint32_t address_lo_64b:29;
543 } bitfields4b;
544 uint32_t reserved12;
545 unsigned int ordinal4;
546 };
547
548 union {
549 uint32_t address_hi;
550 uint32_t reserved13;
551 uint32_t ordinal5;
552 };
553
554 union {
555 uint32_t data_lo;
556 uint32_t cmp_data_lo;
557 struct {
558 uint32_t dw_offset:16;
559 uint32_t num_dwords:16;
560 } bitfields6c;
561 uint32_t reserved14;
562 uint32_t ordinal6;
563 };
564
565 union {
566 uint32_t data_hi;
567 uint32_t cmp_data_hi;
568 uint32_t reserved15;
569 uint32_t reserved16;
570 uint32_t ordinal7;
571 };
572
573 uint32_t int_ctxid;
574
575};
576
577#endif
578
579enum {
580 CACHE_FLUSH_AND_INV_TS_EVENT = 0x00000014
581};
582#endif
583
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 96a9cc0f02c9..5e3990bb4c4b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -39,11 +39,37 @@
39 39
40#include "amd_shared.h" 40#include "amd_shared.h"
41 41
42#define KFD_MAX_RING_ENTRY_SIZE 8
43
42#define KFD_SYSFS_FILE_MODE 0444 44#define KFD_SYSFS_FILE_MODE 0444
43 45
44#define KFD_MMAP_DOORBELL_MASK 0x8000000000000ull 46/* GPU ID hash width in bits */
45#define KFD_MMAP_EVENTS_MASK 0x4000000000000ull 47#define KFD_GPU_ID_HASH_WIDTH 16
46#define KFD_MMAP_RESERVED_MEM_MASK 0x2000000000000ull 48
49/* Use upper bits of mmap offset to store KFD driver specific information.
50 * BITS[63:62] - Encode MMAP type
51 * BITS[61:46] - Encode gpu_id. To identify to which GPU the offset belongs to
52 * BITS[45:0] - MMAP offset value
53 *
54 * NOTE: struct vm_area_struct.vm_pgoff uses offset in pages. Hence, these
55 * defines are w.r.t to PAGE_SIZE
56 */
57#define KFD_MMAP_TYPE_SHIFT (62 - PAGE_SHIFT)
58#define KFD_MMAP_TYPE_MASK (0x3ULL << KFD_MMAP_TYPE_SHIFT)
59#define KFD_MMAP_TYPE_DOORBELL (0x3ULL << KFD_MMAP_TYPE_SHIFT)
60#define KFD_MMAP_TYPE_EVENTS (0x2ULL << KFD_MMAP_TYPE_SHIFT)
61#define KFD_MMAP_TYPE_RESERVED_MEM (0x1ULL << KFD_MMAP_TYPE_SHIFT)
62
63#define KFD_MMAP_GPU_ID_SHIFT (46 - PAGE_SHIFT)
64#define KFD_MMAP_GPU_ID_MASK (((1ULL << KFD_GPU_ID_HASH_WIDTH) - 1) \
65 << KFD_MMAP_GPU_ID_SHIFT)
66#define KFD_MMAP_GPU_ID(gpu_id) ((((uint64_t)gpu_id) << KFD_MMAP_GPU_ID_SHIFT)\
67 & KFD_MMAP_GPU_ID_MASK)
68#define KFD_MMAP_GPU_ID_GET(offset) ((offset & KFD_MMAP_GPU_ID_MASK) \
69 >> KFD_MMAP_GPU_ID_SHIFT)
70
71#define KFD_MMAP_OFFSET_VALUE_MASK (0x3FFFFFFFFFFFULL >> PAGE_SHIFT)
72#define KFD_MMAP_OFFSET_VALUE_GET(offset) (offset & KFD_MMAP_OFFSET_VALUE_MASK)
47 73
48/* 74/*
49 * When working with cp scheduler we should assign the HIQ manually or via 75 * When working with cp scheduler we should assign the HIQ manually or via
@@ -55,9 +81,6 @@
55#define KFD_CIK_HIQ_PIPE 4 81#define KFD_CIK_HIQ_PIPE 4
56#define KFD_CIK_HIQ_QUEUE 0 82#define KFD_CIK_HIQ_QUEUE 0
57 83
58/* GPU ID hash width in bits */
59#define KFD_GPU_ID_HASH_WIDTH 16
60
61/* Macro for allocating structures */ 84/* Macro for allocating structures */
62#define kfd_alloc_struct(ptr_to_struct) \ 85#define kfd_alloc_struct(ptr_to_struct) \
63 ((typeof(ptr_to_struct)) kzalloc(sizeof(*ptr_to_struct), GFP_KERNEL)) 86 ((typeof(ptr_to_struct)) kzalloc(sizeof(*ptr_to_struct), GFP_KERNEL))
@@ -116,6 +139,11 @@ extern int debug_largebar;
116 */ 139 */
117extern int ignore_crat; 140extern int ignore_crat;
118 141
142/*
143 * Set sh_mem_config.retry_disable on Vega10
144 */
145extern int vega10_noretry;
146
119/** 147/**
120 * enum kfd_sched_policy 148 * enum kfd_sched_policy
121 * 149 *
@@ -148,6 +176,8 @@ enum cache_policy {
148 cache_policy_noncoherent 176 cache_policy_noncoherent
149}; 177};
150 178
179#define KFD_IS_SOC15(chip) ((chip) >= CHIP_VEGA10)
180
151struct kfd_event_interrupt_class { 181struct kfd_event_interrupt_class {
152 bool (*interrupt_isr)(struct kfd_dev *dev, 182 bool (*interrupt_isr)(struct kfd_dev *dev,
153 const uint32_t *ih_ring_entry); 183 const uint32_t *ih_ring_entry);
@@ -160,6 +190,7 @@ struct kfd_device_info {
160 const struct kfd_event_interrupt_class *event_interrupt_class; 190 const struct kfd_event_interrupt_class *event_interrupt_class;
161 unsigned int max_pasid_bits; 191 unsigned int max_pasid_bits;
162 unsigned int max_no_of_hqd; 192 unsigned int max_no_of_hqd;
193 unsigned int doorbell_size;
163 size_t ih_ring_entry_size; 194 size_t ih_ring_entry_size;
164 uint8_t num_of_watch_points; 195 uint8_t num_of_watch_points;
165 uint16_t mqd_size_aligned; 196 uint16_t mqd_size_aligned;
@@ -173,6 +204,7 @@ struct kfd_mem_obj {
173 uint32_t range_end; 204 uint32_t range_end;
174 uint64_t gpu_addr; 205 uint64_t gpu_addr;
175 uint32_t *cpu_ptr; 206 uint32_t *cpu_ptr;
207 void *gtt_mem;
176}; 208};
177 209
178struct kfd_vmid_info { 210struct kfd_vmid_info {
@@ -364,7 +396,7 @@ struct queue_properties {
364 uint32_t queue_percent; 396 uint32_t queue_percent;
365 uint32_t *read_ptr; 397 uint32_t *read_ptr;
366 uint32_t *write_ptr; 398 uint32_t *write_ptr;
367 uint32_t __iomem *doorbell_ptr; 399 void __iomem *doorbell_ptr;
368 uint32_t doorbell_off; 400 uint32_t doorbell_off;
369 bool is_interop; 401 bool is_interop;
370 bool is_evicted; 402 bool is_evicted;
@@ -427,6 +459,7 @@ struct queue {
427 uint32_t queue; 459 uint32_t queue;
428 460
429 unsigned int sdma_id; 461 unsigned int sdma_id;
462 unsigned int doorbell_id;
430 463
431 struct kfd_process *process; 464 struct kfd_process *process;
432 struct kfd_dev *device; 465 struct kfd_dev *device;
@@ -501,6 +534,9 @@ struct qcm_process_device {
501 /* IB memory */ 534 /* IB memory */
502 uint64_t ib_base; 535 uint64_t ib_base;
503 void *ib_kaddr; 536 void *ib_kaddr;
537
538 /* doorbell resources per process per device */
539 unsigned long *doorbell_bitmap;
504}; 540};
505 541
506/* KFD Memory Eviction */ 542/* KFD Memory Eviction */
@@ -512,6 +548,8 @@ struct qcm_process_device {
512/* Approx. time before evicting the process again */ 548/* Approx. time before evicting the process again */
513#define PROCESS_ACTIVE_TIME_MS 10 549#define PROCESS_ACTIVE_TIME_MS 10
514 550
551int kgd2kfd_quiesce_mm(struct mm_struct *mm);
552int kgd2kfd_resume_mm(struct mm_struct *mm);
515int kgd2kfd_schedule_evict_and_restore_process(struct mm_struct *mm, 553int kgd2kfd_schedule_evict_and_restore_process(struct mm_struct *mm,
516 struct dma_fence *fence); 554 struct dma_fence *fence);
517 555
@@ -681,6 +719,8 @@ struct kfd_process *kfd_get_process(const struct task_struct *);
681struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid); 719struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid);
682struct kfd_process *kfd_lookup_process_by_mm(const struct mm_struct *mm); 720struct kfd_process *kfd_lookup_process_by_mm(const struct mm_struct *mm);
683void kfd_unref_process(struct kfd_process *p); 721void kfd_unref_process(struct kfd_process *p);
722int kfd_process_evict_queues(struct kfd_process *p);
723int kfd_process_restore_queues(struct kfd_process *p);
684void kfd_suspend_all_processes(void); 724void kfd_suspend_all_processes(void);
685int kfd_resume_all_processes(void); 725int kfd_resume_all_processes(void);
686 726
@@ -693,7 +733,7 @@ struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
693struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev, 733struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
694 struct kfd_process *p); 734 struct kfd_process *p);
695 735
696int kfd_reserved_mem_mmap(struct kfd_process *process, 736int kfd_reserved_mem_mmap(struct kfd_dev *dev, struct kfd_process *process,
697 struct vm_area_struct *vma); 737 struct vm_area_struct *vma);
698 738
699/* KFD process API for creating and translating handles */ 739/* KFD process API for creating and translating handles */
@@ -721,17 +761,20 @@ unsigned int kfd_pasid_alloc(void);
721void kfd_pasid_free(unsigned int pasid); 761void kfd_pasid_free(unsigned int pasid);
722 762
723/* Doorbells */ 763/* Doorbells */
764size_t kfd_doorbell_process_slice(struct kfd_dev *kfd);
724int kfd_doorbell_init(struct kfd_dev *kfd); 765int kfd_doorbell_init(struct kfd_dev *kfd);
725void kfd_doorbell_fini(struct kfd_dev *kfd); 766void kfd_doorbell_fini(struct kfd_dev *kfd);
726int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma); 767int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process,
727u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd, 768 struct vm_area_struct *vma);
769void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
728 unsigned int *doorbell_off); 770 unsigned int *doorbell_off);
729void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr); 771void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr);
730u32 read_kernel_doorbell(u32 __iomem *db); 772u32 read_kernel_doorbell(u32 __iomem *db);
731void write_kernel_doorbell(u32 __iomem *db, u32 value); 773void write_kernel_doorbell(void __iomem *db, u32 value);
732unsigned int kfd_queue_id_to_doorbell(struct kfd_dev *kfd, 774void write_kernel_doorbell64(void __iomem *db, u64 value);
775unsigned int kfd_doorbell_id_to_offset(struct kfd_dev *kfd,
733 struct kfd_process *process, 776 struct kfd_process *process,
734 unsigned int queue_id); 777 unsigned int doorbell_id);
735phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev, 778phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev,
736 struct kfd_process *process); 779 struct kfd_process *process);
737int kfd_alloc_process_doorbells(struct kfd_process *process); 780int kfd_alloc_process_doorbells(struct kfd_process *process);
@@ -788,6 +831,8 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
788 struct kfd_dev *dev); 831 struct kfd_dev *dev);
789struct mqd_manager *mqd_manager_init_vi_tonga(enum KFD_MQD_TYPE type, 832struct mqd_manager *mqd_manager_init_vi_tonga(enum KFD_MQD_TYPE type,
790 struct kfd_dev *dev); 833 struct kfd_dev *dev);
834struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
835 struct kfd_dev *dev);
791struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev); 836struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev);
792void device_queue_manager_uninit(struct device_queue_manager *dqm); 837void device_queue_manager_uninit(struct device_queue_manager *dqm);
793struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, 838struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
@@ -832,8 +877,42 @@ struct packet_manager {
832 bool allocated; 877 bool allocated;
833 struct kfd_mem_obj *ib_buffer_obj; 878 struct kfd_mem_obj *ib_buffer_obj;
834 unsigned int ib_size_bytes; 879 unsigned int ib_size_bytes;
880
881 const struct packet_manager_funcs *pmf;
882};
883
884struct packet_manager_funcs {
885 /* Support ASIC-specific packet formats for PM4 packets */
886 int (*map_process)(struct packet_manager *pm, uint32_t *buffer,
887 struct qcm_process_device *qpd);
888 int (*runlist)(struct packet_manager *pm, uint32_t *buffer,
889 uint64_t ib, size_t ib_size_in_dwords, bool chain);
890 int (*set_resources)(struct packet_manager *pm, uint32_t *buffer,
891 struct scheduling_resources *res);
892 int (*map_queues)(struct packet_manager *pm, uint32_t *buffer,
893 struct queue *q, bool is_static);
894 int (*unmap_queues)(struct packet_manager *pm, uint32_t *buffer,
895 enum kfd_queue_type type,
896 enum kfd_unmap_queues_filter mode,
897 uint32_t filter_param, bool reset,
898 unsigned int sdma_engine);
899 int (*query_status)(struct packet_manager *pm, uint32_t *buffer,
900 uint64_t fence_address, uint32_t fence_value);
901 int (*release_mem)(uint64_t gpu_addr, uint32_t *buffer);
902
903 /* Packet sizes */
904 int map_process_size;
905 int runlist_size;
906 int set_resources_size;
907 int map_queues_size;
908 int unmap_queues_size;
909 int query_status_size;
910 int release_mem_size;
835}; 911};
836 912
913extern const struct packet_manager_funcs kfd_vi_pm_funcs;
914extern const struct packet_manager_funcs kfd_v9_pm_funcs;
915
837int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm); 916int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm);
838void pm_uninit(struct packet_manager *pm); 917void pm_uninit(struct packet_manager *pm);
839int pm_send_set_resources(struct packet_manager *pm, 918int pm_send_set_resources(struct packet_manager *pm,
@@ -849,12 +928,17 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
849 928
850void pm_release_ib(struct packet_manager *pm); 929void pm_release_ib(struct packet_manager *pm);
851 930
852uint32_t pm_create_release_mem(uint64_t gpu_addr, uint32_t *buffer); 931/* Following PM funcs can be shared among VI and AI */
932unsigned int pm_build_pm4_header(unsigned int opcode, size_t packet_size);
933int pm_set_resources_vi(struct packet_manager *pm, uint32_t *buffer,
934 struct scheduling_resources *res);
853 935
854uint64_t kfd_get_number_elems(struct kfd_dev *kfd); 936uint64_t kfd_get_number_elems(struct kfd_dev *kfd);
855 937
856/* Events */ 938/* Events */
857extern const struct kfd_event_interrupt_class event_interrupt_class_cik; 939extern const struct kfd_event_interrupt_class event_interrupt_class_cik;
940extern const struct kfd_event_interrupt_class event_interrupt_class_v9;
941
858extern const struct kfd_device_global_init_class device_global_init_class_cik; 942extern const struct kfd_device_global_init_class device_global_init_class_cik;
859 943
860void kfd_event_init_process(struct kfd_process *p); 944void kfd_event_init_process(struct kfd_process *p);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 1711ad0642f7..1d80b4f7c681 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -332,6 +332,7 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
332 free_pages((unsigned long)pdd->qpd.cwsr_kaddr, 332 free_pages((unsigned long)pdd->qpd.cwsr_kaddr,
333 get_order(KFD_CWSR_TBA_TMA_SIZE)); 333 get_order(KFD_CWSR_TBA_TMA_SIZE));
334 334
335 kfree(pdd->qpd.doorbell_bitmap);
335 idr_destroy(&pdd->alloc_idr); 336 idr_destroy(&pdd->alloc_idr);
336 337
337 kfree(pdd); 338 kfree(pdd);
@@ -451,7 +452,8 @@ static int kfd_process_init_cwsr_apu(struct kfd_process *p, struct file *filep)
451 if (!dev->cwsr_enabled || qpd->cwsr_kaddr || qpd->cwsr_base) 452 if (!dev->cwsr_enabled || qpd->cwsr_kaddr || qpd->cwsr_base)
452 continue; 453 continue;
453 454
454 offset = (dev->id | KFD_MMAP_RESERVED_MEM_MASK) << PAGE_SHIFT; 455 offset = (KFD_MMAP_TYPE_RESERVED_MEM | KFD_MMAP_GPU_ID(dev->id))
456 << PAGE_SHIFT;
455 qpd->tba_addr = (int64_t)vm_mmap(filep, 0, 457 qpd->tba_addr = (int64_t)vm_mmap(filep, 0,
456 KFD_CWSR_TBA_TMA_SIZE, PROT_READ | PROT_EXEC, 458 KFD_CWSR_TBA_TMA_SIZE, PROT_READ | PROT_EXEC,
457 MAP_SHARED, offset); 459 MAP_SHARED, offset);
@@ -585,6 +587,31 @@ err_alloc_process:
585 return ERR_PTR(err); 587 return ERR_PTR(err);
586} 588}
587 589
590static int init_doorbell_bitmap(struct qcm_process_device *qpd,
591 struct kfd_dev *dev)
592{
593 unsigned int i;
594
595 if (!KFD_IS_SOC15(dev->device_info->asic_family))
596 return 0;
597
598 qpd->doorbell_bitmap =
599 kzalloc(DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
600 BITS_PER_BYTE), GFP_KERNEL);
601 if (!qpd->doorbell_bitmap)
602 return -ENOMEM;
603
604 /* Mask out any reserved doorbells */
605 for (i = 0; i < KFD_MAX_NUM_OF_QUEUES_PER_PROCESS; i++)
606 if ((dev->shared_resources.reserved_doorbell_mask & i) ==
607 dev->shared_resources.reserved_doorbell_val) {
608 set_bit(i, qpd->doorbell_bitmap);
609 pr_debug("reserved doorbell 0x%03x\n", i);
610 }
611
612 return 0;
613}
614
588struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, 615struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
589 struct kfd_process *p) 616 struct kfd_process *p)
590{ 617{
@@ -606,6 +633,12 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
606 if (!pdd) 633 if (!pdd)
607 return NULL; 634 return NULL;
608 635
636 if (init_doorbell_bitmap(&pdd->qpd, dev)) {
637 pr_err("Failed to init doorbell for process\n");
638 kfree(pdd);
639 return NULL;
640 }
641
609 pdd->dev = dev; 642 pdd->dev = dev;
610 INIT_LIST_HEAD(&pdd->qpd.queues_list); 643 INIT_LIST_HEAD(&pdd->qpd.queues_list);
611 INIT_LIST_HEAD(&pdd->qpd.priv_queue_list); 644 INIT_LIST_HEAD(&pdd->qpd.priv_queue_list);
@@ -808,7 +841,7 @@ struct kfd_process *kfd_lookup_process_by_mm(const struct mm_struct *mm)
808 * Eviction is reference-counted per process-device. This means multiple 841 * Eviction is reference-counted per process-device. This means multiple
809 * evictions from different sources can be nested safely. 842 * evictions from different sources can be nested safely.
810 */ 843 */
811static int process_evict_queues(struct kfd_process *p) 844int kfd_process_evict_queues(struct kfd_process *p)
812{ 845{
813 struct kfd_process_device *pdd; 846 struct kfd_process_device *pdd;
814 int r = 0; 847 int r = 0;
@@ -844,7 +877,7 @@ fail:
844} 877}
845 878
846/* process_restore_queues - Restore all user queues of a process */ 879/* process_restore_queues - Restore all user queues of a process */
847static int process_restore_queues(struct kfd_process *p) 880int kfd_process_restore_queues(struct kfd_process *p)
848{ 881{
849 struct kfd_process_device *pdd; 882 struct kfd_process_device *pdd;
850 int r, ret = 0; 883 int r, ret = 0;
@@ -886,7 +919,7 @@ static void evict_process_worker(struct work_struct *work)
886 flush_delayed_work(&p->restore_work); 919 flush_delayed_work(&p->restore_work);
887 920
888 pr_debug("Started evicting pasid %d\n", p->pasid); 921 pr_debug("Started evicting pasid %d\n", p->pasid);
889 ret = process_evict_queues(p); 922 ret = kfd_process_evict_queues(p);
890 if (!ret) { 923 if (!ret) {
891 dma_fence_signal(p->ef); 924 dma_fence_signal(p->ef);
892 dma_fence_put(p->ef); 925 dma_fence_put(p->ef);
@@ -946,7 +979,7 @@ static void restore_process_worker(struct work_struct *work)
946 return; 979 return;
947 } 980 }
948 981
949 ret = process_restore_queues(p); 982 ret = kfd_process_restore_queues(p);
950 if (!ret) 983 if (!ret)
951 pr_debug("Finished restoring pasid %d\n", p->pasid); 984 pr_debug("Finished restoring pasid %d\n", p->pasid);
952 else 985 else
@@ -963,7 +996,7 @@ void kfd_suspend_all_processes(void)
963 cancel_delayed_work_sync(&p->eviction_work); 996 cancel_delayed_work_sync(&p->eviction_work);
964 cancel_delayed_work_sync(&p->restore_work); 997 cancel_delayed_work_sync(&p->restore_work);
965 998
966 if (process_evict_queues(p)) 999 if (kfd_process_evict_queues(p))
967 pr_err("Failed to suspend process %d\n", p->pasid); 1000 pr_err("Failed to suspend process %d\n", p->pasid);
968 dma_fence_signal(p->ef); 1001 dma_fence_signal(p->ef);
969 dma_fence_put(p->ef); 1002 dma_fence_put(p->ef);
@@ -989,15 +1022,12 @@ int kfd_resume_all_processes(void)
989 return ret; 1022 return ret;
990} 1023}
991 1024
992int kfd_reserved_mem_mmap(struct kfd_process *process, 1025int kfd_reserved_mem_mmap(struct kfd_dev *dev, struct kfd_process *process,
993 struct vm_area_struct *vma) 1026 struct vm_area_struct *vma)
994{ 1027{
995 struct kfd_dev *dev = kfd_device_by_id(vma->vm_pgoff);
996 struct kfd_process_device *pdd; 1028 struct kfd_process_device *pdd;
997 struct qcm_process_device *qpd; 1029 struct qcm_process_device *qpd;
998 1030
999 if (!dev)
1000 return -EINVAL;
1001 if ((vma->vm_end - vma->vm_start) != KFD_CWSR_TBA_TMA_SIZE) { 1031 if ((vma->vm_end - vma->vm_start) != KFD_CWSR_TBA_TMA_SIZE) {
1002 pr_err("Incorrect CWSR mapping size.\n"); 1032 pr_err("Incorrect CWSR mapping size.\n");
1003 return -EINVAL; 1033 return -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 7817e327ea6d..d65ce0436b31 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -119,9 +119,6 @@ static int create_cp_queue(struct process_queue_manager *pqm,
119 /* Doorbell initialized in user space*/ 119 /* Doorbell initialized in user space*/
120 q_properties->doorbell_ptr = NULL; 120 q_properties->doorbell_ptr = NULL;
121 121
122 q_properties->doorbell_off =
123 kfd_queue_id_to_doorbell(dev, pqm->process, qid);
124
125 /* let DQM handle it*/ 122 /* let DQM handle it*/
126 q_properties->vmid = 0; 123 q_properties->vmid = 0;
127 q_properties->queue_id = qid; 124 q_properties->queue_id = qid;
@@ -244,10 +241,20 @@ int pqm_create_queue(struct process_queue_manager *pqm,
244 } 241 }
245 242
246 if (retval != 0) { 243 if (retval != 0) {
247 pr_err("DQM create queue failed\n"); 244 pr_err("Pasid %d DQM create queue %d failed. ret %d\n",
245 pqm->process->pasid, type, retval);
248 goto err_create_queue; 246 goto err_create_queue;
249 } 247 }
250 248
249 if (q)
250 /* Return the doorbell offset within the doorbell page
251 * to the caller so it can be passed up to user mode
252 * (in bytes).
253 */
254 properties->doorbell_off =
255 (q->properties.doorbell_off * sizeof(uint32_t)) &
256 (kfd_doorbell_process_slice(dev) - 1);
257
251 pr_debug("PQM After DQM create queue\n"); 258 pr_debug("PQM After DQM create queue\n");
252 259
253 list_add(&pqn->process_queue_list, &pqm->queues); 260 list_add(&pqn->process_queue_list, &pqm->queues);
@@ -313,8 +320,11 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
313 dqm = pqn->q->device->dqm; 320 dqm = pqn->q->device->dqm;
314 retval = dqm->ops.destroy_queue(dqm, &pdd->qpd, pqn->q); 321 retval = dqm->ops.destroy_queue(dqm, &pdd->qpd, pqn->q);
315 if (retval) { 322 if (retval) {
316 pr_debug("Destroy queue failed, returned %d\n", retval); 323 pr_err("Pasid %d destroy queue %d failed, ret %d\n",
317 goto err_destroy_queue; 324 pqm->process->pasid,
325 pqn->q->properties.queue_id, retval);
326 if (retval != -ETIME)
327 goto err_destroy_queue;
318 } 328 }
319 uninit_queue(pqn->q); 329 uninit_queue(pqn->q);
320 } 330 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
index a5315d4f1c95..6dcd621e5b71 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
@@ -36,8 +36,8 @@ void print_queue_properties(struct queue_properties *q)
36 pr_debug("Queue Address: 0x%llX\n", q->queue_address); 36 pr_debug("Queue Address: 0x%llX\n", q->queue_address);
37 pr_debug("Queue Id: %u\n", q->queue_id); 37 pr_debug("Queue Id: %u\n", q->queue_id);
38 pr_debug("Queue Process Vmid: %u\n", q->vmid); 38 pr_debug("Queue Process Vmid: %u\n", q->vmid);
39 pr_debug("Queue Read Pointer: 0x%p\n", q->read_ptr); 39 pr_debug("Queue Read Pointer: 0x%px\n", q->read_ptr);
40 pr_debug("Queue Write Pointer: 0x%p\n", q->write_ptr); 40 pr_debug("Queue Write Pointer: 0x%px\n", q->write_ptr);
41 pr_debug("Queue Doorbell Pointer: 0x%p\n", q->doorbell_ptr); 41 pr_debug("Queue Doorbell Pointer: 0x%p\n", q->doorbell_ptr);
42 pr_debug("Queue Doorbell Offset: %u\n", q->doorbell_off); 42 pr_debug("Queue Doorbell Offset: %u\n", q->doorbell_off);
43} 43}
@@ -53,8 +53,8 @@ void print_queue(struct queue *q)
53 pr_debug("Queue Address: 0x%llX\n", q->properties.queue_address); 53 pr_debug("Queue Address: 0x%llX\n", q->properties.queue_address);
54 pr_debug("Queue Id: %u\n", q->properties.queue_id); 54 pr_debug("Queue Id: %u\n", q->properties.queue_id);
55 pr_debug("Queue Process Vmid: %u\n", q->properties.vmid); 55 pr_debug("Queue Process Vmid: %u\n", q->properties.vmid);
56 pr_debug("Queue Read Pointer: 0x%p\n", q->properties.read_ptr); 56 pr_debug("Queue Read Pointer: 0x%px\n", q->properties.read_ptr);
57 pr_debug("Queue Write Pointer: 0x%p\n", q->properties.write_ptr); 57 pr_debug("Queue Write Pointer: 0x%px\n", q->properties.write_ptr);
58 pr_debug("Queue Doorbell Pointer: 0x%p\n", q->properties.doorbell_ptr); 58 pr_debug("Queue Doorbell Pointer: 0x%p\n", q->properties.doorbell_ptr);
59 pr_debug("Queue Doorbell Offset: %u\n", q->properties.doorbell_off); 59 pr_debug("Queue Doorbell Offset: %u\n", q->properties.doorbell_off);
60 pr_debug("Queue MQD Address: 0x%p\n", q->mqd); 60 pr_debug("Queue MQD Address: 0x%p\n", q->mqd);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index ac28abc94e57..bc95d4dfee2e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -1239,6 +1239,12 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
1239 HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) & 1239 HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) &
1240 HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK); 1240 HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK);
1241 break; 1241 break;
1242 case CHIP_VEGA10:
1243 case CHIP_RAVEN:
1244 dev->node_props.capability |= ((HSA_CAP_DOORBELL_TYPE_2_0 <<
1245 HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) &
1246 HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK);
1247 break;
1242 default: 1248 default:
1243 WARN(1, "Unexpected ASIC family %u", 1249 WARN(1, "Unexpected ASIC family %u",
1244 dev->gpu->device_info->asic_family); 1250 dev->gpu->device_info->asic_family);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
index eb54cfcaf039..7d9c3f948dff 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
@@ -45,6 +45,7 @@
45 45
46#define HSA_CAP_DOORBELL_TYPE_PRE_1_0 0x0 46#define HSA_CAP_DOORBELL_TYPE_PRE_1_0 0x0
47#define HSA_CAP_DOORBELL_TYPE_1_0 0x1 47#define HSA_CAP_DOORBELL_TYPE_1_0 0x1
48#define HSA_CAP_DOORBELL_TYPE_2_0 0x2
48#define HSA_CAP_AQL_QUEUE_DOUBLE_MAP 0x00004000 49#define HSA_CAP_AQL_QUEUE_DOUBLE_MAP 0x00004000
49 50
50struct kfd_node_properties { 51struct kfd_node_properties {
diff --git a/drivers/gpu/drm/amd/amdkfd/soc15_int.h b/drivers/gpu/drm/amd/amdkfd/soc15_int.h
new file mode 100644
index 000000000000..0bc0b25cb410
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/soc15_int.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright 2016-2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef HSA_SOC15_INT_H_INCLUDED
24#define HSA_SOC15_INT_H_INCLUDED
25
26#include "soc15_ih_clientid.h"
27
28#define SOC15_INTSRC_CP_END_OF_PIPE 181
29#define SOC15_INTSRC_CP_BAD_OPCODE 183
30#define SOC15_INTSRC_SQ_INTERRUPT_MSG 239
31#define SOC15_INTSRC_VMC_FAULT 0
32#define SOC15_INTSRC_SDMA_TRAP 224
33
34
35#define SOC15_CLIENT_ID_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[0]) & 0xff)
36#define SOC15_SOURCE_ID_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[0]) >> 8 & 0xff)
37#define SOC15_RING_ID_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[0]) >> 16 & 0xff)
38#define SOC15_VMID_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[0]) >> 24 & 0xf)
39#define SOC15_VMID_TYPE_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[0]) >> 31 & 0x1)
40#define SOC15_PASID_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[3]) & 0xffff)
41#define SOC15_CONTEXT_ID0_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[4]))
42#define SOC15_CONTEXT_ID1_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[5]))
43#define SOC15_CONTEXT_ID2_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[6]))
44#define SOC15_CONTEXT_ID3_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[7]))
45
46#endif
47
diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 5b124a67404c..d5d4586e6176 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -9,14 +9,6 @@ config DRM_AMD_DC
9 support for AMDGPU. This adds required support for Vega and 9 support for AMDGPU. This adds required support for Vega and
10 Raven ASICs. 10 Raven ASICs.
11 11
12config DRM_AMD_DC_PRE_VEGA
13 bool "DC support for Polaris and older ASICs"
14 default y
15 help
16 Choose this option to enable the new DC support for older asics
17 by default. This includes Polaris, Carrizo, Tonga, Bonaire,
18 and Hawaii.
19
20config DRM_AMD_DC_FBC 12config DRM_AMD_DC_FBC
21 bool "AMD FBC - Enable Frame Buffer Compression" 13 bool "AMD FBC - Enable Frame Buffer Compression"
22 depends on DRM_AMD_DC 14 depends on DRM_AMD_DC
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 27579443cdc5..f9b9ab90558c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -433,11 +433,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
433 433
434 init_data.dce_environment = DCE_ENV_PRODUCTION_DRV; 434 init_data.dce_environment = DCE_ENV_PRODUCTION_DRV;
435 435
436 if (amdgpu_dc_log)
437 init_data.log_mask = DC_DEFAULT_LOG_MASK;
438 else
439 init_data.log_mask = DC_MIN_LOG_MASK;
440
441 /* 436 /*
442 * TODO debug why this doesn't work on Raven 437 * TODO debug why this doesn't work on Raven
443 */ 438 */
@@ -649,18 +644,6 @@ amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
649static int dm_resume(void *handle) 644static int dm_resume(void *handle)
650{ 645{
651 struct amdgpu_device *adev = handle; 646 struct amdgpu_device *adev = handle;
652 struct amdgpu_display_manager *dm = &adev->dm;
653 int ret = 0;
654
655 /* power on hardware */
656 dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
657
658 ret = amdgpu_dm_display_resume(adev);
659 return ret;
660}
661
662int amdgpu_dm_display_resume(struct amdgpu_device *adev)
663{
664 struct drm_device *ddev = adev->ddev; 647 struct drm_device *ddev = adev->ddev;
665 struct amdgpu_display_manager *dm = &adev->dm; 648 struct amdgpu_display_manager *dm = &adev->dm;
666 struct amdgpu_dm_connector *aconnector; 649 struct amdgpu_dm_connector *aconnector;
@@ -671,10 +654,12 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
671 struct drm_plane *plane; 654 struct drm_plane *plane;
672 struct drm_plane_state *new_plane_state; 655 struct drm_plane_state *new_plane_state;
673 struct dm_plane_state *dm_new_plane_state; 656 struct dm_plane_state *dm_new_plane_state;
674 657 int ret;
675 int ret = 0;
676 int i; 658 int i;
677 659
660 /* power on hardware */
661 dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
662
678 /* program HPD filter */ 663 /* program HPD filter */
679 dc_resume(dm->dc); 664 dc_resume(dm->dc);
680 665
@@ -688,8 +673,7 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
688 amdgpu_dm_irq_resume_early(adev); 673 amdgpu_dm_irq_resume_early(adev);
689 674
690 /* Do detection*/ 675 /* Do detection*/
691 list_for_each_entry(connector, 676 list_for_each_entry(connector, &ddev->mode_config.connector_list, head) {
692 &ddev->mode_config.connector_list, head) {
693 aconnector = to_amdgpu_dm_connector(connector); 677 aconnector = to_amdgpu_dm_connector(connector);
694 678
695 /* 679 /*
@@ -711,7 +695,7 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
711 } 695 }
712 696
713 /* Force mode set in atomic comit */ 697 /* Force mode set in atomic comit */
714 for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) 698 for_each_new_crtc_in_state(dm->cached_state, crtc, new_crtc_state, i)
715 new_crtc_state->active_changed = true; 699 new_crtc_state->active_changed = true;
716 700
717 /* 701 /*
@@ -719,7 +703,7 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
719 * them here, since they were duplicated as part of the suspend 703 * them here, since they were duplicated as part of the suspend
720 * procedure. 704 * procedure.
721 */ 705 */
722 for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) { 706 for_each_new_crtc_in_state(dm->cached_state, crtc, new_crtc_state, i) {
723 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); 707 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
724 if (dm_new_crtc_state->stream) { 708 if (dm_new_crtc_state->stream) {
725 WARN_ON(kref_read(&dm_new_crtc_state->stream->refcount) > 1); 709 WARN_ON(kref_read(&dm_new_crtc_state->stream->refcount) > 1);
@@ -728,7 +712,7 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
728 } 712 }
729 } 713 }
730 714
731 for_each_new_plane_in_state(adev->dm.cached_state, plane, new_plane_state, i) { 715 for_each_new_plane_in_state(dm->cached_state, plane, new_plane_state, i) {
732 dm_new_plane_state = to_dm_plane_state(new_plane_state); 716 dm_new_plane_state = to_dm_plane_state(new_plane_state);
733 if (dm_new_plane_state->dc_state) { 717 if (dm_new_plane_state->dc_state) {
734 WARN_ON(kref_read(&dm_new_plane_state->dc_state->refcount) > 1); 718 WARN_ON(kref_read(&dm_new_plane_state->dc_state->refcount) > 1);
@@ -737,9 +721,9 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
737 } 721 }
738 } 722 }
739 723
740 ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state); 724 ret = drm_atomic_helper_resume(ddev, dm->cached_state);
741 725
742 adev->dm.cached_state = NULL; 726 dm->cached_state = NULL;
743 727
744 amdgpu_dm_irq_resume_late(adev); 728 amdgpu_dm_irq_resume_late(adev);
745 729
@@ -927,6 +911,7 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
927 drm_mode_connector_update_edid_property(connector, NULL); 911 drm_mode_connector_update_edid_property(connector, NULL);
928 aconnector->num_modes = 0; 912 aconnector->num_modes = 0;
929 aconnector->dc_sink = NULL; 913 aconnector->dc_sink = NULL;
914 aconnector->edid = NULL;
930 } 915 }
931 916
932 mutex_unlock(&dev->mode_config.mutex); 917 mutex_unlock(&dev->mode_config.mutex);
@@ -1131,6 +1116,7 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev)
1131 1116
1132 if (adev->asic_type == CHIP_VEGA10 || 1117 if (adev->asic_type == CHIP_VEGA10 ||
1133 adev->asic_type == CHIP_VEGA12 || 1118 adev->asic_type == CHIP_VEGA12 ||
1119 adev->asic_type == CHIP_VEGA20 ||
1134 adev->asic_type == CHIP_RAVEN) 1120 adev->asic_type == CHIP_RAVEN)
1135 client_id = SOC15_IH_CLIENTID_DCE; 1121 client_id = SOC15_IH_CLIENTID_DCE;
1136 1122
@@ -1529,8 +1515,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
1529 case CHIP_POLARIS11: 1515 case CHIP_POLARIS11:
1530 case CHIP_POLARIS10: 1516 case CHIP_POLARIS10:
1531 case CHIP_POLARIS12: 1517 case CHIP_POLARIS12:
1518 case CHIP_VEGAM:
1532 case CHIP_VEGA10: 1519 case CHIP_VEGA10:
1533 case CHIP_VEGA12: 1520 case CHIP_VEGA12:
1521 case CHIP_VEGA20:
1534 if (dce110_register_irq_handlers(dm->adev)) { 1522 if (dce110_register_irq_handlers(dm->adev)) {
1535 DRM_ERROR("DM: Failed to initialize IRQ\n"); 1523 DRM_ERROR("DM: Failed to initialize IRQ\n");
1536 goto fail; 1524 goto fail;
@@ -1549,7 +1537,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
1549 break; 1537 break;
1550#endif 1538#endif
1551 default: 1539 default:
1552 DRM_ERROR("Usupported ASIC type: 0x%X\n", adev->asic_type); 1540 DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type);
1553 goto fail; 1541 goto fail;
1554 } 1542 }
1555 1543
@@ -1657,7 +1645,6 @@ static ssize_t s3_debug_store(struct device *device,
1657 if (ret == 0) { 1645 if (ret == 0) {
1658 if (s3_state) { 1646 if (s3_state) {
1659 dm_resume(adev); 1647 dm_resume(adev);
1660 amdgpu_dm_display_resume(adev);
1661 drm_kms_helper_hotplug_event(adev->ddev); 1648 drm_kms_helper_hotplug_event(adev->ddev);
1662 } else 1649 } else
1663 dm_suspend(adev); 1650 dm_suspend(adev);
@@ -1722,6 +1709,7 @@ static int dm_early_init(void *handle)
1722 adev->mode_info.plane_type = dm_plane_type_default; 1709 adev->mode_info.plane_type = dm_plane_type_default;
1723 break; 1710 break;
1724 case CHIP_POLARIS10: 1711 case CHIP_POLARIS10:
1712 case CHIP_VEGAM:
1725 adev->mode_info.num_crtc = 6; 1713 adev->mode_info.num_crtc = 6;
1726 adev->mode_info.num_hpd = 6; 1714 adev->mode_info.num_hpd = 6;
1727 adev->mode_info.num_dig = 6; 1715 adev->mode_info.num_dig = 6;
@@ -1729,6 +1717,7 @@ static int dm_early_init(void *handle)
1729 break; 1717 break;
1730 case CHIP_VEGA10: 1718 case CHIP_VEGA10:
1731 case CHIP_VEGA12: 1719 case CHIP_VEGA12:
1720 case CHIP_VEGA20:
1732 adev->mode_info.num_crtc = 6; 1721 adev->mode_info.num_crtc = 6;
1733 adev->mode_info.num_hpd = 6; 1722 adev->mode_info.num_hpd = 6;
1734 adev->mode_info.num_dig = 6; 1723 adev->mode_info.num_dig = 6;
@@ -1743,7 +1732,7 @@ static int dm_early_init(void *handle)
1743 break; 1732 break;
1744#endif 1733#endif
1745 default: 1734 default:
1746 DRM_ERROR("Usupported ASIC type: 0x%X\n", adev->asic_type); 1735 DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type);
1747 return -EINVAL; 1736 return -EINVAL;
1748 } 1737 }
1749 1738
@@ -1848,7 +1837,7 @@ static bool fill_rects_from_plane_state(const struct drm_plane_state *state,
1848static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, 1837static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
1849 uint64_t *tiling_flags) 1838 uint64_t *tiling_flags)
1850{ 1839{
1851 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(amdgpu_fb->obj); 1840 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
1852 int r = amdgpu_bo_reserve(rbo, false); 1841 int r = amdgpu_bo_reserve(rbo, false);
1853 1842
1854 if (unlikely(r)) { 1843 if (unlikely(r)) {
@@ -1977,6 +1966,7 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev,
1977 1966
1978 if (adev->asic_type == CHIP_VEGA10 || 1967 if (adev->asic_type == CHIP_VEGA10 ||
1979 adev->asic_type == CHIP_VEGA12 || 1968 adev->asic_type == CHIP_VEGA12 ||
1969 adev->asic_type == CHIP_VEGA20 ||
1980 adev->asic_type == CHIP_RAVEN) { 1970 adev->asic_type == CHIP_RAVEN) {
1981 /* Fill GFX9 params */ 1971 /* Fill GFX9 params */
1982 plane_state->tiling_info.gfx9.num_pipes = 1972 plane_state->tiling_info.gfx9.num_pipes =
@@ -2017,7 +2007,6 @@ static int fill_plane_attributes(struct amdgpu_device *adev,
2017 const struct amdgpu_framebuffer *amdgpu_fb = 2007 const struct amdgpu_framebuffer *amdgpu_fb =
2018 to_amdgpu_framebuffer(plane_state->fb); 2008 to_amdgpu_framebuffer(plane_state->fb);
2019 const struct drm_crtc *crtc = plane_state->crtc; 2009 const struct drm_crtc *crtc = plane_state->crtc;
2020 struct dc_transfer_func *input_tf;
2021 int ret = 0; 2010 int ret = 0;
2022 2011
2023 if (!fill_rects_from_plane_state(plane_state, dc_plane_state)) 2012 if (!fill_rects_from_plane_state(plane_state, dc_plane_state))
@@ -2031,13 +2020,6 @@ static int fill_plane_attributes(struct amdgpu_device *adev,
2031 if (ret) 2020 if (ret)
2032 return ret; 2021 return ret;
2033 2022
2034 input_tf = dc_create_transfer_func();
2035
2036 if (input_tf == NULL)
2037 return -ENOMEM;
2038
2039 dc_plane_state->in_transfer_func = input_tf;
2040
2041 /* 2023 /*
2042 * Always set input transfer function, since plane state is refreshed 2024 * Always set input transfer function, since plane state is refreshed
2043 * every time. 2025 * every time.
@@ -2206,7 +2188,6 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
2206 const struct drm_connector *connector) 2188 const struct drm_connector *connector)
2207{ 2189{
2208 struct dc_crtc_timing *timing_out = &stream->timing; 2190 struct dc_crtc_timing *timing_out = &stream->timing;
2209 struct dc_transfer_func *tf = dc_create_transfer_func();
2210 2191
2211 memset(timing_out, 0, sizeof(struct dc_crtc_timing)); 2192 memset(timing_out, 0, sizeof(struct dc_crtc_timing));
2212 2193
@@ -2250,9 +2231,8 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
2250 2231
2251 stream->output_color_space = get_output_color_space(timing_out); 2232 stream->output_color_space = get_output_color_space(timing_out);
2252 2233
2253 tf->type = TF_TYPE_PREDEFINED; 2234 stream->out_transfer_func->type = TF_TYPE_PREDEFINED;
2254 tf->tf = TRANSFER_FUNCTION_SRGB; 2235 stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
2255 stream->out_transfer_func = tf;
2256} 2236}
2257 2237
2258static void fill_audio_info(struct audio_info *audio_info, 2238static void fill_audio_info(struct audio_info *audio_info,
@@ -2488,6 +2468,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
2488 2468
2489 update_stream_signal(stream); 2469 update_stream_signal(stream);
2490 2470
2471 if (dm_state && dm_state->freesync_capable)
2472 stream->ignore_msa_timing_param = true;
2473
2491 return stream; 2474 return stream;
2492} 2475}
2493 2476
@@ -2710,18 +2693,15 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
2710 const struct dc_link *link = aconnector->dc_link; 2693 const struct dc_link *link = aconnector->dc_link;
2711 struct amdgpu_device *adev = connector->dev->dev_private; 2694 struct amdgpu_device *adev = connector->dev->dev_private;
2712 struct amdgpu_display_manager *dm = &adev->dm; 2695 struct amdgpu_display_manager *dm = &adev->dm;
2696
2713#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\ 2697#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
2714 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) 2698 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
2715 2699
2716 if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) && 2700 if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) &&
2717 link->type != dc_connection_none) { 2701 link->type != dc_connection_none &&
2718 amdgpu_dm_register_backlight_device(dm); 2702 dm->backlight_dev) {
2719 2703 backlight_device_unregister(dm->backlight_dev);
2720 if (dm->backlight_dev) { 2704 dm->backlight_dev = NULL;
2721 backlight_device_unregister(dm->backlight_dev);
2722 dm->backlight_dev = NULL;
2723 }
2724
2725 } 2705 }
2726#endif 2706#endif
2727 drm_connector_unregister(connector); 2707 drm_connector_unregister(connector);
@@ -2855,7 +2835,7 @@ static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
2855 create_eml_sink(aconnector); 2835 create_eml_sink(aconnector);
2856} 2836}
2857 2837
2858int amdgpu_dm_connector_mode_valid(struct drm_connector *connector, 2838enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
2859 struct drm_display_mode *mode) 2839 struct drm_display_mode *mode)
2860{ 2840{
2861 int result = MODE_ERROR; 2841 int result = MODE_ERROR;
@@ -3058,8 +3038,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
3058 } 3038 }
3059 3039
3060 afb = to_amdgpu_framebuffer(new_state->fb); 3040 afb = to_amdgpu_framebuffer(new_state->fb);
3061 3041 obj = new_state->fb->obj[0];
3062 obj = afb->obj;
3063 rbo = gem_to_amdgpu_bo(obj); 3042 rbo = gem_to_amdgpu_bo(obj);
3064 adev = amdgpu_ttm_adev(rbo->tbo.bdev); 3043 adev = amdgpu_ttm_adev(rbo->tbo.bdev);
3065 r = amdgpu_bo_reserve(rbo, false); 3044 r = amdgpu_bo_reserve(rbo, false);
@@ -3067,12 +3046,11 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
3067 return r; 3046 return r;
3068 3047
3069 if (plane->type != DRM_PLANE_TYPE_CURSOR) 3048 if (plane->type != DRM_PLANE_TYPE_CURSOR)
3070 domain = amdgpu_display_framebuffer_domains(adev); 3049 domain = amdgpu_display_supported_domains(adev);
3071 else 3050 else
3072 domain = AMDGPU_GEM_DOMAIN_VRAM; 3051 domain = AMDGPU_GEM_DOMAIN_VRAM;
3073 3052
3074 r = amdgpu_bo_pin(rbo, domain, &afb->address); 3053 r = amdgpu_bo_pin(rbo, domain, &afb->address);
3075
3076 amdgpu_bo_unreserve(rbo); 3054 amdgpu_bo_unreserve(rbo);
3077 3055
3078 if (unlikely(r != 0)) { 3056 if (unlikely(r != 0)) {
@@ -3123,14 +3101,12 @@ static void dm_plane_helper_cleanup_fb(struct drm_plane *plane,
3123 struct drm_plane_state *old_state) 3101 struct drm_plane_state *old_state)
3124{ 3102{
3125 struct amdgpu_bo *rbo; 3103 struct amdgpu_bo *rbo;
3126 struct amdgpu_framebuffer *afb;
3127 int r; 3104 int r;
3128 3105
3129 if (!old_state->fb) 3106 if (!old_state->fb)
3130 return; 3107 return;
3131 3108
3132 afb = to_amdgpu_framebuffer(old_state->fb); 3109 rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
3133 rbo = gem_to_amdgpu_bo(afb->obj);
3134 r = amdgpu_bo_reserve(rbo, false); 3110 r = amdgpu_bo_reserve(rbo, false);
3135 if (unlikely(r)) { 3111 if (unlikely(r)) {
3136 DRM_ERROR("failed to reserve rbo before unpin\n"); 3112 DRM_ERROR("failed to reserve rbo before unpin\n");
@@ -3773,7 +3749,7 @@ static void remove_stream(struct amdgpu_device *adev,
3773static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, 3749static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
3774 struct dc_cursor_position *position) 3750 struct dc_cursor_position *position)
3775{ 3751{
3776 struct amdgpu_crtc *amdgpu_crtc = amdgpu_crtc = to_amdgpu_crtc(crtc); 3752 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
3777 int x, y; 3753 int x, y;
3778 int xorigin = 0, yorigin = 0; 3754 int xorigin = 0, yorigin = 0;
3779 3755
@@ -3905,7 +3881,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
3905 int r, vpos, hpos; 3881 int r, vpos, hpos;
3906 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); 3882 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3907 struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(fb); 3883 struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(fb);
3908 struct amdgpu_bo *abo = gem_to_amdgpu_bo(afb->obj); 3884 struct amdgpu_bo *abo = gem_to_amdgpu_bo(fb->obj[0]);
3909 struct amdgpu_device *adev = crtc->dev->dev_private; 3885 struct amdgpu_device *adev = crtc->dev->dev_private;
3910 bool async_flip = (crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0; 3886 bool async_flip = (crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0;
3911 struct dc_flip_addrs addr = { {0} }; 3887 struct dc_flip_addrs addr = { {0} };
@@ -3986,6 +3962,96 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
3986 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 3962 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
3987} 3963}
3988 3964
3965/*
3966 * TODO this whole function needs to go
3967 *
3968 * dc_surface_update is needlessly complex. See if we can just replace this
3969 * with a dc_plane_state and follow the atomic model a bit more closely here.
3970 */
3971static bool commit_planes_to_stream(
3972 struct dc *dc,
3973 struct dc_plane_state **plane_states,
3974 uint8_t new_plane_count,
3975 struct dm_crtc_state *dm_new_crtc_state,
3976 struct dm_crtc_state *dm_old_crtc_state,
3977 struct dc_state *state)
3978{
3979 /* no need to dynamically allocate this. it's pretty small */
3980 struct dc_surface_update updates[MAX_SURFACES];
3981 struct dc_flip_addrs *flip_addr;
3982 struct dc_plane_info *plane_info;
3983 struct dc_scaling_info *scaling_info;
3984 int i;
3985 struct dc_stream_state *dc_stream = dm_new_crtc_state->stream;
3986 struct dc_stream_update *stream_update =
3987 kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL);
3988
3989 if (!stream_update) {
3990 BREAK_TO_DEBUGGER();
3991 return false;
3992 }
3993
3994 flip_addr = kcalloc(MAX_SURFACES, sizeof(struct dc_flip_addrs),
3995 GFP_KERNEL);
3996 plane_info = kcalloc(MAX_SURFACES, sizeof(struct dc_plane_info),
3997 GFP_KERNEL);
3998 scaling_info = kcalloc(MAX_SURFACES, sizeof(struct dc_scaling_info),
3999 GFP_KERNEL);
4000
4001 if (!flip_addr || !plane_info || !scaling_info) {
4002 kfree(flip_addr);
4003 kfree(plane_info);
4004 kfree(scaling_info);
4005 kfree(stream_update);
4006 return false;
4007 }
4008
4009 memset(updates, 0, sizeof(updates));
4010
4011 stream_update->src = dc_stream->src;
4012 stream_update->dst = dc_stream->dst;
4013 stream_update->out_transfer_func = dc_stream->out_transfer_func;
4014
4015 for (i = 0; i < new_plane_count; i++) {
4016 updates[i].surface = plane_states[i];
4017 updates[i].gamma =
4018 (struct dc_gamma *)plane_states[i]->gamma_correction;
4019 updates[i].in_transfer_func = plane_states[i]->in_transfer_func;
4020 flip_addr[i].address = plane_states[i]->address;
4021 flip_addr[i].flip_immediate = plane_states[i]->flip_immediate;
4022 plane_info[i].color_space = plane_states[i]->color_space;
4023 plane_info[i].format = plane_states[i]->format;
4024 plane_info[i].plane_size = plane_states[i]->plane_size;
4025 plane_info[i].rotation = plane_states[i]->rotation;
4026 plane_info[i].horizontal_mirror = plane_states[i]->horizontal_mirror;
4027 plane_info[i].stereo_format = plane_states[i]->stereo_format;
4028 plane_info[i].tiling_info = plane_states[i]->tiling_info;
4029 plane_info[i].visible = plane_states[i]->visible;
4030 plane_info[i].per_pixel_alpha = plane_states[i]->per_pixel_alpha;
4031 plane_info[i].dcc = plane_states[i]->dcc;
4032 scaling_info[i].scaling_quality = plane_states[i]->scaling_quality;
4033 scaling_info[i].src_rect = plane_states[i]->src_rect;
4034 scaling_info[i].dst_rect = plane_states[i]->dst_rect;
4035 scaling_info[i].clip_rect = plane_states[i]->clip_rect;
4036
4037 updates[i].flip_addr = &flip_addr[i];
4038 updates[i].plane_info = &plane_info[i];
4039 updates[i].scaling_info = &scaling_info[i];
4040 }
4041
4042 dc_commit_updates_for_stream(
4043 dc,
4044 updates,
4045 new_plane_count,
4046 dc_stream, stream_update, plane_states, state);
4047
4048 kfree(flip_addr);
4049 kfree(plane_info);
4050 kfree(scaling_info);
4051 kfree(stream_update);
4052 return true;
4053}
4054
3989static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, 4055static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
3990 struct drm_device *dev, 4056 struct drm_device *dev,
3991 struct amdgpu_display_manager *dm, 4057 struct amdgpu_display_manager *dm,
@@ -4001,6 +4067,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
4001 struct drm_crtc_state *new_pcrtc_state = 4067 struct drm_crtc_state *new_pcrtc_state =
4002 drm_atomic_get_new_crtc_state(state, pcrtc); 4068 drm_atomic_get_new_crtc_state(state, pcrtc);
4003 struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state); 4069 struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state);
4070 struct dm_crtc_state *dm_old_crtc_state =
4071 to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc));
4004 struct dm_atomic_state *dm_state = to_dm_atomic_state(state); 4072 struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
4005 int planes_count = 0; 4073 int planes_count = 0;
4006 unsigned long flags; 4074 unsigned long flags;
@@ -4037,7 +4105,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
4037 } 4105 }
4038 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 4106 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
4039 4107
4040 if (!pflip_needed) { 4108 if (!pflip_needed || plane->type == DRM_PLANE_TYPE_OVERLAY) {
4041 WARN_ON(!dm_new_plane_state->dc_state); 4109 WARN_ON(!dm_new_plane_state->dc_state);
4042 4110
4043 plane_states_constructed[planes_count] = dm_new_plane_state->dc_state; 4111 plane_states_constructed[planes_count] = dm_new_plane_state->dc_state;
@@ -4079,10 +4147,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
4079 spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); 4147 spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
4080 } 4148 }
4081 4149
4082 if (false == dc_commit_planes_to_stream(dm->dc, 4150
4151 if (false == commit_planes_to_stream(dm->dc,
4083 plane_states_constructed, 4152 plane_states_constructed,
4084 planes_count, 4153 planes_count,
4085 dc_stream_attach, 4154 acrtc_state,
4155 dm_old_crtc_state,
4086 dm_state->context)) 4156 dm_state->context))
4087 dm_error("%s: Failed to attach plane!\n", __func__); 4157 dm_error("%s: Failed to attach plane!\n", __func__);
4088 } else { 4158 } else {
@@ -4307,8 +4377,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
4307 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); 4377 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
4308 struct dc_stream_status *status = NULL; 4378 struct dc_stream_status *status = NULL;
4309 4379
4310 if (acrtc) 4380 if (acrtc) {
4311 new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); 4381 new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
4382 old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
4383 }
4312 4384
4313 /* Skip any modesets/resets */ 4385 /* Skip any modesets/resets */
4314 if (!acrtc || drm_atomic_crtc_needs_modeset(new_crtc_state)) 4386 if (!acrtc || drm_atomic_crtc_needs_modeset(new_crtc_state))
@@ -4331,11 +4403,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
4331 WARN_ON(!status->plane_count); 4403 WARN_ON(!status->plane_count);
4332 4404
4333 /*TODO How it works with MPO ?*/ 4405 /*TODO How it works with MPO ?*/
4334 if (!dc_commit_planes_to_stream( 4406 if (!commit_planes_to_stream(
4335 dm->dc, 4407 dm->dc,
4336 status->plane_states, 4408 status->plane_states,
4337 status->plane_count, 4409 status->plane_count,
4338 dm_new_crtc_state->stream, 4410 dm_new_crtc_state,
4411 to_dm_crtc_state(old_crtc_state),
4339 dm_state->context)) 4412 dm_state->context))
4340 dm_error("%s: Failed to update stream scaling!\n", __func__); 4413 dm_error("%s: Failed to update stream scaling!\n", __func__);
4341 } 4414 }
@@ -4582,7 +4655,6 @@ static int dm_update_crtcs_state(struct dc *dc,
4582 drm_old_conn_state = drm_atomic_get_old_connector_state(state, 4655 drm_old_conn_state = drm_atomic_get_old_connector_state(state,
4583 &aconnector->base); 4656 &aconnector->base);
4584 4657
4585
4586 if (IS_ERR(drm_new_conn_state)) { 4658 if (IS_ERR(drm_new_conn_state)) {
4587 ret = PTR_ERR_OR_ZERO(drm_new_conn_state); 4659 ret = PTR_ERR_OR_ZERO(drm_new_conn_state);
4588 break; 4660 break;
@@ -4769,7 +4841,8 @@ static int dm_update_planes_state(struct dc *dc,
4769 4841
4770 /* Remove any changed/removed planes */ 4842 /* Remove any changed/removed planes */
4771 if (!enable) { 4843 if (!enable) {
4772 if (pflip_needed) 4844 if (pflip_needed &&
4845 plane->type != DRM_PLANE_TYPE_OVERLAY)
4773 continue; 4846 continue;
4774 4847
4775 if (!old_plane_crtc) 4848 if (!old_plane_crtc)
@@ -4816,7 +4889,8 @@ static int dm_update_planes_state(struct dc *dc,
4816 if (!dm_new_crtc_state->stream) 4889 if (!dm_new_crtc_state->stream)
4817 continue; 4890 continue;
4818 4891
4819 if (pflip_needed) 4892 if (pflip_needed &&
4893 plane->type != DRM_PLANE_TYPE_OVERLAY)
4820 continue; 4894 continue;
4821 4895
4822 WARN_ON(dm_new_plane_state->dc_state); 4896 WARN_ON(dm_new_plane_state->dc_state);
@@ -5023,17 +5097,24 @@ void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
5023 struct edid *edid) 5097 struct edid *edid)
5024{ 5098{
5025 int i; 5099 int i;
5026 uint64_t val_capable;
5027 bool edid_check_required; 5100 bool edid_check_required;
5028 struct detailed_timing *timing; 5101 struct detailed_timing *timing;
5029 struct detailed_non_pixel *data; 5102 struct detailed_non_pixel *data;
5030 struct detailed_data_monitor_range *range; 5103 struct detailed_data_monitor_range *range;
5031 struct amdgpu_dm_connector *amdgpu_dm_connector = 5104 struct amdgpu_dm_connector *amdgpu_dm_connector =
5032 to_amdgpu_dm_connector(connector); 5105 to_amdgpu_dm_connector(connector);
5106 struct dm_connector_state *dm_con_state;
5033 5107
5034 struct drm_device *dev = connector->dev; 5108 struct drm_device *dev = connector->dev;
5035 struct amdgpu_device *adev = dev->dev_private; 5109 struct amdgpu_device *adev = dev->dev_private;
5036 5110
5111 if (!connector->state) {
5112 DRM_ERROR("%s - Connector has no state", __func__);
5113 return;
5114 }
5115
5116 dm_con_state = to_dm_connector_state(connector->state);
5117
5037 edid_check_required = false; 5118 edid_check_required = false;
5038 if (!amdgpu_dm_connector->dc_sink) { 5119 if (!amdgpu_dm_connector->dc_sink) {
5039 DRM_ERROR("dc_sink NULL, could not add free_sync module.\n"); 5120 DRM_ERROR("dc_sink NULL, could not add free_sync module.\n");
@@ -5052,7 +5133,7 @@ void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
5052 amdgpu_dm_connector); 5133 amdgpu_dm_connector);
5053 } 5134 }
5054 } 5135 }
5055 val_capable = 0; 5136 dm_con_state->freesync_capable = false;
5056 if (edid_check_required == true && (edid->version > 1 || 5137 if (edid_check_required == true && (edid->version > 1 ||
5057 (edid->version == 1 && edid->revision > 1))) { 5138 (edid->version == 1 && edid->revision > 1))) {
5058 for (i = 0; i < 4; i++) { 5139 for (i = 0; i < 4; i++) {
@@ -5088,7 +5169,7 @@ void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
5088 amdgpu_dm_connector->min_vfreq * 1000000; 5169 amdgpu_dm_connector->min_vfreq * 1000000;
5089 amdgpu_dm_connector->caps.max_refresh_in_micro_hz = 5170 amdgpu_dm_connector->caps.max_refresh_in_micro_hz =
5090 amdgpu_dm_connector->max_vfreq * 1000000; 5171 amdgpu_dm_connector->max_vfreq * 1000000;
5091 val_capable = 1; 5172 dm_con_state->freesync_capable = true;
5092 } 5173 }
5093 } 5174 }
5094 5175
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index b68400c1154b..d5aa89ad5571 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -28,7 +28,6 @@
28 28
29#include <drm/drmP.h> 29#include <drm/drmP.h>
30#include <drm/drm_atomic.h> 30#include <drm/drm_atomic.h>
31#include "dc.h"
32 31
33/* 32/*
34 * This file contains the definition for amdgpu_display_manager 33 * This file contains the definition for amdgpu_display_manager
@@ -53,6 +52,7 @@
53struct amdgpu_device; 52struct amdgpu_device;
54struct drm_device; 53struct drm_device;
55struct amdgpu_dm_irq_handler_data; 54struct amdgpu_dm_irq_handler_data;
55struct dc;
56 56
57struct amdgpu_dm_prev_state { 57struct amdgpu_dm_prev_state {
58 struct drm_framebuffer *fb; 58 struct drm_framebuffer *fb;
@@ -220,6 +220,7 @@ struct dm_connector_state {
220 uint8_t underscan_hborder; 220 uint8_t underscan_hborder;
221 bool underscan_enable; 221 bool underscan_enable;
222 struct mod_freesync_user_enable user_enable; 222 struct mod_freesync_user_enable user_enable;
223 bool freesync_capable;
223}; 224};
224 225
225#define to_dm_connector_state(x)\ 226#define to_dm_connector_state(x)\
@@ -246,7 +247,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
246 struct dc_link *link, 247 struct dc_link *link,
247 int link_index); 248 int link_index);
248 249
249int amdgpu_dm_connector_mode_valid(struct drm_connector *connector, 250enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
250 struct drm_display_mode *mode); 251 struct drm_display_mode *mode);
251 252
252void dm_restore_drm_connector_state(struct drm_device *dev, 253void dm_restore_drm_connector_state(struct drm_device *dev,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 25f064c01038..b329393307e5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -25,6 +25,7 @@
25 25
26#include "amdgpu_mode.h" 26#include "amdgpu_mode.h"
27#include "amdgpu_dm.h" 27#include "amdgpu_dm.h"
28#include "dc.h"
28#include "modules/color/color_gamma.h" 29#include "modules/color/color_gamma.h"
29 30
30#define MAX_DRM_LUT_VALUE 0xFFFF 31#define MAX_DRM_LUT_VALUE 0xFFFF
@@ -87,9 +88,9 @@ static void __drm_lut_to_dc_gamma(struct drm_color_lut *lut,
87 g = drm_color_lut_extract(lut[i].green, 16); 88 g = drm_color_lut_extract(lut[i].green, 16);
88 b = drm_color_lut_extract(lut[i].blue, 16); 89 b = drm_color_lut_extract(lut[i].blue, 16);
89 90
90 gamma->entries.red[i] = dal_fixed31_32_from_int(r); 91 gamma->entries.red[i] = dc_fixpt_from_int(r);
91 gamma->entries.green[i] = dal_fixed31_32_from_int(g); 92 gamma->entries.green[i] = dc_fixpt_from_int(g);
92 gamma->entries.blue[i] = dal_fixed31_32_from_int(b); 93 gamma->entries.blue[i] = dc_fixpt_from_int(b);
93 } 94 }
94 return; 95 return;
95 } 96 }
@@ -100,9 +101,9 @@ static void __drm_lut_to_dc_gamma(struct drm_color_lut *lut,
100 g = drm_color_lut_extract(lut[i].green, 16); 101 g = drm_color_lut_extract(lut[i].green, 16);
101 b = drm_color_lut_extract(lut[i].blue, 16); 102 b = drm_color_lut_extract(lut[i].blue, 16);
102 103
103 gamma->entries.red[i] = dal_fixed31_32_from_fraction(r, MAX_DRM_LUT_VALUE); 104 gamma->entries.red[i] = dc_fixpt_from_fraction(r, MAX_DRM_LUT_VALUE);
104 gamma->entries.green[i] = dal_fixed31_32_from_fraction(g, MAX_DRM_LUT_VALUE); 105 gamma->entries.green[i] = dc_fixpt_from_fraction(g, MAX_DRM_LUT_VALUE);
105 gamma->entries.blue[i] = dal_fixed31_32_from_fraction(b, MAX_DRM_LUT_VALUE); 106 gamma->entries.blue[i] = dc_fixpt_from_fraction(b, MAX_DRM_LUT_VALUE);
106 } 107 }
107} 108}
108 109
@@ -207,7 +208,7 @@ void amdgpu_dm_set_ctm(struct dm_crtc_state *crtc)
207 for (i = 0; i < 12; i++) { 208 for (i = 0; i < 12; i++) {
208 /* Skip 4th element */ 209 /* Skip 4th element */
209 if (i % 4 == 3) { 210 if (i % 4 == 3) {
210 stream->gamut_remap_matrix.matrix[i] = dal_fixed31_32_zero; 211 stream->gamut_remap_matrix.matrix[i] = dc_fixpt_zero;
211 continue; 212 continue;
212 } 213 }
213 214
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index ca0b08bfa2cf..bd449351803f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -330,11 +330,6 @@ bool dm_helpers_dp_mst_send_payload_allocation(
330 return true; 330 return true;
331} 331}
332 332
333bool dm_helpers_dc_conn_log(struct dc_context *ctx, struct log_entry *entry, enum dc_log_type event)
334{
335 return true;
336}
337
338void dm_dtn_log_begin(struct dc_context *ctx) 333void dm_dtn_log_begin(struct dc_context *ctx)
339{} 334{}
340 335
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
index 89342b48be6b..0229c7edb8ad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
@@ -37,8 +37,17 @@
37 37
38unsigned long long dm_get_timestamp(struct dc_context *ctx) 38unsigned long long dm_get_timestamp(struct dc_context *ctx)
39{ 39{
40 /* TODO: return actual timestamp */ 40 struct timespec64 time;
41 return 0; 41
42 getrawmonotonic64(&time);
43 return timespec64_to_ns(&time);
44}
45
46unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx,
47 unsigned long long current_time_stamp,
48 unsigned long long last_time_stamp)
49{
50 return current_time_stamp - last_time_stamp;
42} 51}
43 52
44void dm_perf_trace_timestamp(const char *func_name, unsigned int line) 53void dm_perf_trace_timestamp(const char *func_name, unsigned int line)
diff --git a/drivers/gpu/drm/amd/display/dc/basics/Makefile b/drivers/gpu/drm/amd/display/dc/basics/Makefile
index bca33bd9a0d2..b49ea96b5dae 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/basics/Makefile
@@ -24,7 +24,7 @@
24# It provides the general basic services required by other DAL 24# It provides the general basic services required by other DAL
25# subcomponents. 25# subcomponents.
26 26
27BASICS = conversion.o fixpt31_32.o fixpt32_32.o \ 27BASICS = conversion.o fixpt31_32.o \
28 logger.o log_helpers.o vector.o 28 logger.o log_helpers.o vector.o
29 29
30AMD_DAL_BASICS = $(addprefix $(AMDDALPATH)/dc/basics/,$(BASICS)) 30AMD_DAL_BASICS = $(addprefix $(AMDDALPATH)/dc/basics/,$(BASICS))
diff --git a/drivers/gpu/drm/amd/display/dc/basics/conversion.c b/drivers/gpu/drm/amd/display/dc/basics/conversion.c
index 310964915a83..50b47f11875c 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/conversion.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/conversion.c
@@ -41,22 +41,22 @@ uint16_t fixed_point_to_int_frac(
41 41
42 uint16_t result; 42 uint16_t result;
43 43
44 uint16_t d = (uint16_t)dal_fixed31_32_floor( 44 uint16_t d = (uint16_t)dc_fixpt_floor(
45 dal_fixed31_32_abs( 45 dc_fixpt_abs(
46 arg)); 46 arg));
47 47
48 if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor)) 48 if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
49 numerator = (uint16_t)dal_fixed31_32_round( 49 numerator = (uint16_t)dc_fixpt_round(
50 dal_fixed31_32_mul_int( 50 dc_fixpt_mul_int(
51 arg, 51 arg,
52 divisor)); 52 divisor));
53 else { 53 else {
54 numerator = dal_fixed31_32_floor( 54 numerator = dc_fixpt_floor(
55 dal_fixed31_32_sub( 55 dc_fixpt_sub(
56 dal_fixed31_32_from_int( 56 dc_fixpt_from_int(
57 1LL << integer_bits), 57 1LL << integer_bits),
58 dal_fixed31_32_recip( 58 dc_fixpt_recip(
59 dal_fixed31_32_from_int( 59 dc_fixpt_from_int(
60 divisor)))); 60 divisor))));
61 } 61 }
62 62
@@ -66,8 +66,8 @@ uint16_t fixed_point_to_int_frac(
66 result = (uint16_t)( 66 result = (uint16_t)(
67 (1 << (integer_bits + fractional_bits + 1)) + numerator); 67 (1 << (integer_bits + fractional_bits + 1)) + numerator);
68 68
69 if ((result != 0) && dal_fixed31_32_lt( 69 if ((result != 0) && dc_fixpt_lt(
70 arg, dal_fixed31_32_zero)) 70 arg, dc_fixpt_zero))
71 result |= 1 << (integer_bits + fractional_bits); 71 result |= 1 << (integer_bits + fractional_bits);
72 72
73 return result; 73 return result;
@@ -84,15 +84,15 @@ void convert_float_matrix(
84 uint32_t buffer_size) 84 uint32_t buffer_size)
85{ 85{
86 const struct fixed31_32 min_2_13 = 86 const struct fixed31_32 min_2_13 =
87 dal_fixed31_32_from_fraction(S2D13_MIN, DIVIDER); 87 dc_fixpt_from_fraction(S2D13_MIN, DIVIDER);
88 const struct fixed31_32 max_2_13 = 88 const struct fixed31_32 max_2_13 =
89 dal_fixed31_32_from_fraction(S2D13_MAX, DIVIDER); 89 dc_fixpt_from_fraction(S2D13_MAX, DIVIDER);
90 uint32_t i; 90 uint32_t i;
91 91
92 for (i = 0; i < buffer_size; ++i) { 92 for (i = 0; i < buffer_size; ++i) {
93 uint32_t reg_value = 93 uint32_t reg_value =
94 fixed_point_to_int_frac( 94 fixed_point_to_int_frac(
95 dal_fixed31_32_clamp( 95 dc_fixpt_clamp(
96 flt[i], 96 flt[i],
97 min_2_13, 97 min_2_13,
98 max_2_13), 98 max_2_13),
diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
index 8a9bba879207..e61dd97d0928 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
@@ -26,13 +26,13 @@
26#include "dm_services.h" 26#include "dm_services.h"
27#include "include/fixed31_32.h" 27#include "include/fixed31_32.h"
28 28
29static inline uint64_t abs_i64( 29static inline unsigned long long abs_i64(
30 int64_t arg) 30 long long arg)
31{ 31{
32 if (arg > 0) 32 if (arg > 0)
33 return (uint64_t)arg; 33 return (unsigned long long)arg;
34 else 34 else
35 return (uint64_t)(-arg); 35 return (unsigned long long)(-arg);
36} 36}
37 37
38/* 38/*
@@ -40,12 +40,12 @@ static inline uint64_t abs_i64(
40 * result = dividend / divisor 40 * result = dividend / divisor
41 * *remainder = dividend % divisor 41 * *remainder = dividend % divisor
42 */ 42 */
43static inline uint64_t complete_integer_division_u64( 43static inline unsigned long long complete_integer_division_u64(
44 uint64_t dividend, 44 unsigned long long dividend,
45 uint64_t divisor, 45 unsigned long long divisor,
46 uint64_t *remainder) 46 unsigned long long *remainder)
47{ 47{
48 uint64_t result; 48 unsigned long long result;
49 49
50 ASSERT(divisor); 50 ASSERT(divisor);
51 51
@@ -64,30 +64,28 @@ static inline uint64_t complete_integer_division_u64(
64#define GET_FRACTIONAL_PART(x) \ 64#define GET_FRACTIONAL_PART(x) \
65 (FRACTIONAL_PART_MASK & (x)) 65 (FRACTIONAL_PART_MASK & (x))
66 66
67struct fixed31_32 dal_fixed31_32_from_fraction( 67struct fixed31_32 dc_fixpt_from_fraction(long long numerator, long long denominator)
68 int64_t numerator,
69 int64_t denominator)
70{ 68{
71 struct fixed31_32 res; 69 struct fixed31_32 res;
72 70
73 bool arg1_negative = numerator < 0; 71 bool arg1_negative = numerator < 0;
74 bool arg2_negative = denominator < 0; 72 bool arg2_negative = denominator < 0;
75 73
76 uint64_t arg1_value = arg1_negative ? -numerator : numerator; 74 unsigned long long arg1_value = arg1_negative ? -numerator : numerator;
77 uint64_t arg2_value = arg2_negative ? -denominator : denominator; 75 unsigned long long arg2_value = arg2_negative ? -denominator : denominator;
78 76
79 uint64_t remainder; 77 unsigned long long remainder;
80 78
81 /* determine integer part */ 79 /* determine integer part */
82 80
83 uint64_t res_value = complete_integer_division_u64( 81 unsigned long long res_value = complete_integer_division_u64(
84 arg1_value, arg2_value, &remainder); 82 arg1_value, arg2_value, &remainder);
85 83
86 ASSERT(res_value <= LONG_MAX); 84 ASSERT(res_value <= LONG_MAX);
87 85
88 /* determine fractional part */ 86 /* determine fractional part */
89 { 87 {
90 uint32_t i = FIXED31_32_BITS_PER_FRACTIONAL_PART; 88 unsigned int i = FIXED31_32_BITS_PER_FRACTIONAL_PART;
91 89
92 do { 90 do {
93 remainder <<= 1; 91 remainder <<= 1;
@@ -103,14 +101,14 @@ struct fixed31_32 dal_fixed31_32_from_fraction(
103 101
104 /* round up LSB */ 102 /* round up LSB */
105 { 103 {
106 uint64_t summand = (remainder << 1) >= arg2_value; 104 unsigned long long summand = (remainder << 1) >= arg2_value;
107 105
108 ASSERT(res_value <= LLONG_MAX - summand); 106 ASSERT(res_value <= LLONG_MAX - summand);
109 107
110 res_value += summand; 108 res_value += summand;
111 } 109 }
112 110
113 res.value = (int64_t)res_value; 111 res.value = (long long)res_value;
114 112
115 if (arg1_negative ^ arg2_negative) 113 if (arg1_negative ^ arg2_negative)
116 res.value = -res.value; 114 res.value = -res.value;
@@ -118,79 +116,23 @@ struct fixed31_32 dal_fixed31_32_from_fraction(
118 return res; 116 return res;
119} 117}
120 118
121struct fixed31_32 dal_fixed31_32_from_int_nonconst( 119struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2)
122 int64_t arg)
123{
124 struct fixed31_32 res;
125
126 ASSERT((LONG_MIN <= arg) && (arg <= LONG_MAX));
127
128 res.value = arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
129
130 return res;
131}
132
133struct fixed31_32 dal_fixed31_32_shl(
134 struct fixed31_32 arg,
135 uint8_t shift)
136{
137 struct fixed31_32 res;
138
139 ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
140 ((arg.value < 0) && (arg.value >= LLONG_MIN >> shift)));
141
142 res.value = arg.value << shift;
143
144 return res;
145}
146
147struct fixed31_32 dal_fixed31_32_add(
148 struct fixed31_32 arg1,
149 struct fixed31_32 arg2)
150{
151 struct fixed31_32 res;
152
153 ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
154 ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
155
156 res.value = arg1.value + arg2.value;
157
158 return res;
159}
160
161struct fixed31_32 dal_fixed31_32_sub(
162 struct fixed31_32 arg1,
163 struct fixed31_32 arg2)
164{
165 struct fixed31_32 res;
166
167 ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
168 ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
169
170 res.value = arg1.value - arg2.value;
171
172 return res;
173}
174
175struct fixed31_32 dal_fixed31_32_mul(
176 struct fixed31_32 arg1,
177 struct fixed31_32 arg2)
178{ 120{
179 struct fixed31_32 res; 121 struct fixed31_32 res;
180 122
181 bool arg1_negative = arg1.value < 0; 123 bool arg1_negative = arg1.value < 0;
182 bool arg2_negative = arg2.value < 0; 124 bool arg2_negative = arg2.value < 0;
183 125
184 uint64_t arg1_value = arg1_negative ? -arg1.value : arg1.value; 126 unsigned long long arg1_value = arg1_negative ? -arg1.value : arg1.value;
185 uint64_t arg2_value = arg2_negative ? -arg2.value : arg2.value; 127 unsigned long long arg2_value = arg2_negative ? -arg2.value : arg2.value;
186 128
187 uint64_t arg1_int = GET_INTEGER_PART(arg1_value); 129 unsigned long long arg1_int = GET_INTEGER_PART(arg1_value);
188 uint64_t arg2_int = GET_INTEGER_PART(arg2_value); 130 unsigned long long arg2_int = GET_INTEGER_PART(arg2_value);
189 131
190 uint64_t arg1_fra = GET_FRACTIONAL_PART(arg1_value); 132 unsigned long long arg1_fra = GET_FRACTIONAL_PART(arg1_value);
191 uint64_t arg2_fra = GET_FRACTIONAL_PART(arg2_value); 133 unsigned long long arg2_fra = GET_FRACTIONAL_PART(arg2_value);
192 134
193 uint64_t tmp; 135 unsigned long long tmp;
194 136
195 res.value = arg1_int * arg2_int; 137 res.value = arg1_int * arg2_int;
196 138
@@ -200,22 +142,22 @@ struct fixed31_32 dal_fixed31_32_mul(
200 142
201 tmp = arg1_int * arg2_fra; 143 tmp = arg1_int * arg2_fra;
202 144
203 ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value)); 145 ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
204 146
205 res.value += tmp; 147 res.value += tmp;
206 148
207 tmp = arg2_int * arg1_fra; 149 tmp = arg2_int * arg1_fra;
208 150
209 ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value)); 151 ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
210 152
211 res.value += tmp; 153 res.value += tmp;
212 154
213 tmp = arg1_fra * arg2_fra; 155 tmp = arg1_fra * arg2_fra;
214 156
215 tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) + 157 tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) +
216 (tmp >= (uint64_t)dal_fixed31_32_half.value); 158 (tmp >= (unsigned long long)dc_fixpt_half.value);
217 159
218 ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value)); 160 ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
219 161
220 res.value += tmp; 162 res.value += tmp;
221 163
@@ -225,18 +167,17 @@ struct fixed31_32 dal_fixed31_32_mul(
225 return res; 167 return res;
226} 168}
227 169
228struct fixed31_32 dal_fixed31_32_sqr( 170struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg)
229 struct fixed31_32 arg)
230{ 171{
231 struct fixed31_32 res; 172 struct fixed31_32 res;
232 173
233 uint64_t arg_value = abs_i64(arg.value); 174 unsigned long long arg_value = abs_i64(arg.value);
234 175
235 uint64_t arg_int = GET_INTEGER_PART(arg_value); 176 unsigned long long arg_int = GET_INTEGER_PART(arg_value);
236 177
237 uint64_t arg_fra = GET_FRACTIONAL_PART(arg_value); 178 unsigned long long arg_fra = GET_FRACTIONAL_PART(arg_value);
238 179
239 uint64_t tmp; 180 unsigned long long tmp;
240 181
241 res.value = arg_int * arg_int; 182 res.value = arg_int * arg_int;
242 183
@@ -246,28 +187,27 @@ struct fixed31_32 dal_fixed31_32_sqr(
246 187
247 tmp = arg_int * arg_fra; 188 tmp = arg_int * arg_fra;
248 189
249 ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value)); 190 ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
250 191
251 res.value += tmp; 192 res.value += tmp;
252 193
253 ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value)); 194 ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
254 195
255 res.value += tmp; 196 res.value += tmp;
256 197
257 tmp = arg_fra * arg_fra; 198 tmp = arg_fra * arg_fra;
258 199
259 tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) + 200 tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) +
260 (tmp >= (uint64_t)dal_fixed31_32_half.value); 201 (tmp >= (unsigned long long)dc_fixpt_half.value);
261 202
262 ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value)); 203 ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
263 204
264 res.value += tmp; 205 res.value += tmp;
265 206
266 return res; 207 return res;
267} 208}
268 209
269struct fixed31_32 dal_fixed31_32_recip( 210struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg)
270 struct fixed31_32 arg)
271{ 211{
272 /* 212 /*
273 * @note 213 * @note
@@ -276,41 +216,40 @@ struct fixed31_32 dal_fixed31_32_recip(
276 216
277 ASSERT(arg.value); 217 ASSERT(arg.value);
278 218
279 return dal_fixed31_32_from_fraction( 219 return dc_fixpt_from_fraction(
280 dal_fixed31_32_one.value, 220 dc_fixpt_one.value,
281 arg.value); 221 arg.value);
282} 222}
283 223
284struct fixed31_32 dal_fixed31_32_sinc( 224struct fixed31_32 dc_fixpt_sinc(struct fixed31_32 arg)
285 struct fixed31_32 arg)
286{ 225{
287 struct fixed31_32 square; 226 struct fixed31_32 square;
288 227
289 struct fixed31_32 res = dal_fixed31_32_one; 228 struct fixed31_32 res = dc_fixpt_one;
290 229
291 int32_t n = 27; 230 int n = 27;
292 231
293 struct fixed31_32 arg_norm = arg; 232 struct fixed31_32 arg_norm = arg;
294 233
295 if (dal_fixed31_32_le( 234 if (dc_fixpt_le(
296 dal_fixed31_32_two_pi, 235 dc_fixpt_two_pi,
297 dal_fixed31_32_abs(arg))) { 236 dc_fixpt_abs(arg))) {
298 arg_norm = dal_fixed31_32_sub( 237 arg_norm = dc_fixpt_sub(
299 arg_norm, 238 arg_norm,
300 dal_fixed31_32_mul_int( 239 dc_fixpt_mul_int(
301 dal_fixed31_32_two_pi, 240 dc_fixpt_two_pi,
302 (int32_t)div64_s64( 241 (int)div64_s64(
303 arg_norm.value, 242 arg_norm.value,
304 dal_fixed31_32_two_pi.value))); 243 dc_fixpt_two_pi.value)));
305 } 244 }
306 245
307 square = dal_fixed31_32_sqr(arg_norm); 246 square = dc_fixpt_sqr(arg_norm);
308 247
309 do { 248 do {
310 res = dal_fixed31_32_sub( 249 res = dc_fixpt_sub(
311 dal_fixed31_32_one, 250 dc_fixpt_one,
312 dal_fixed31_32_div_int( 251 dc_fixpt_div_int(
313 dal_fixed31_32_mul( 252 dc_fixpt_mul(
314 square, 253 square,
315 res), 254 res),
316 n * (n - 1))); 255 n * (n - 1)));
@@ -319,37 +258,35 @@ struct fixed31_32 dal_fixed31_32_sinc(
319 } while (n > 2); 258 } while (n > 2);
320 259
321 if (arg.value != arg_norm.value) 260 if (arg.value != arg_norm.value)
322 res = dal_fixed31_32_div( 261 res = dc_fixpt_div(
323 dal_fixed31_32_mul(res, arg_norm), 262 dc_fixpt_mul(res, arg_norm),
324 arg); 263 arg);
325 264
326 return res; 265 return res;
327} 266}
328 267
329struct fixed31_32 dal_fixed31_32_sin( 268struct fixed31_32 dc_fixpt_sin(struct fixed31_32 arg)
330 struct fixed31_32 arg)
331{ 269{
332 return dal_fixed31_32_mul( 270 return dc_fixpt_mul(
333 arg, 271 arg,
334 dal_fixed31_32_sinc(arg)); 272 dc_fixpt_sinc(arg));
335} 273}
336 274
337struct fixed31_32 dal_fixed31_32_cos( 275struct fixed31_32 dc_fixpt_cos(struct fixed31_32 arg)
338 struct fixed31_32 arg)
339{ 276{
340 /* TODO implement argument normalization */ 277 /* TODO implement argument normalization */
341 278
342 const struct fixed31_32 square = dal_fixed31_32_sqr(arg); 279 const struct fixed31_32 square = dc_fixpt_sqr(arg);
343 280
344 struct fixed31_32 res = dal_fixed31_32_one; 281 struct fixed31_32 res = dc_fixpt_one;
345 282
346 int32_t n = 26; 283 int n = 26;
347 284
348 do { 285 do {
349 res = dal_fixed31_32_sub( 286 res = dc_fixpt_sub(
350 dal_fixed31_32_one, 287 dc_fixpt_one,
351 dal_fixed31_32_div_int( 288 dc_fixpt_div_int(
352 dal_fixed31_32_mul( 289 dc_fixpt_mul(
353 square, 290 square,
354 res), 291 res),
355 n * (n - 1))); 292 n * (n - 1)));
@@ -367,37 +304,35 @@ struct fixed31_32 dal_fixed31_32_cos(
367 * 304 *
368 * Calculated as Taylor series. 305 * Calculated as Taylor series.
369 */ 306 */
370static struct fixed31_32 fixed31_32_exp_from_taylor_series( 307static struct fixed31_32 fixed31_32_exp_from_taylor_series(struct fixed31_32 arg)
371 struct fixed31_32 arg)
372{ 308{
373 uint32_t n = 9; 309 unsigned int n = 9;
374 310
375 struct fixed31_32 res = dal_fixed31_32_from_fraction( 311 struct fixed31_32 res = dc_fixpt_from_fraction(
376 n + 2, 312 n + 2,
377 n + 1); 313 n + 1);
378 /* TODO find correct res */ 314 /* TODO find correct res */
379 315
380 ASSERT(dal_fixed31_32_lt(arg, dal_fixed31_32_one)); 316 ASSERT(dc_fixpt_lt(arg, dc_fixpt_one));
381 317
382 do 318 do
383 res = dal_fixed31_32_add( 319 res = dc_fixpt_add(
384 dal_fixed31_32_one, 320 dc_fixpt_one,
385 dal_fixed31_32_div_int( 321 dc_fixpt_div_int(
386 dal_fixed31_32_mul( 322 dc_fixpt_mul(
387 arg, 323 arg,
388 res), 324 res),
389 n)); 325 n));
390 while (--n != 1); 326 while (--n != 1);
391 327
392 return dal_fixed31_32_add( 328 return dc_fixpt_add(
393 dal_fixed31_32_one, 329 dc_fixpt_one,
394 dal_fixed31_32_mul( 330 dc_fixpt_mul(
395 arg, 331 arg,
396 res)); 332 res));
397} 333}
398 334
399struct fixed31_32 dal_fixed31_32_exp( 335struct fixed31_32 dc_fixpt_exp(struct fixed31_32 arg)
400 struct fixed31_32 arg)
401{ 336{
402 /* 337 /*
403 * @brief 338 * @brief
@@ -406,44 +341,43 @@ struct fixed31_32 dal_fixed31_32_exp(
406 * where m = round(x / ln(2)), r = x - m * ln(2) 341 * where m = round(x / ln(2)), r = x - m * ln(2)
407 */ 342 */
408 343
409 if (dal_fixed31_32_le( 344 if (dc_fixpt_le(
410 dal_fixed31_32_ln2_div_2, 345 dc_fixpt_ln2_div_2,
411 dal_fixed31_32_abs(arg))) { 346 dc_fixpt_abs(arg))) {
412 int32_t m = dal_fixed31_32_round( 347 int m = dc_fixpt_round(
413 dal_fixed31_32_div( 348 dc_fixpt_div(
414 arg, 349 arg,
415 dal_fixed31_32_ln2)); 350 dc_fixpt_ln2));
416 351
417 struct fixed31_32 r = dal_fixed31_32_sub( 352 struct fixed31_32 r = dc_fixpt_sub(
418 arg, 353 arg,
419 dal_fixed31_32_mul_int( 354 dc_fixpt_mul_int(
420 dal_fixed31_32_ln2, 355 dc_fixpt_ln2,
421 m)); 356 m));
422 357
423 ASSERT(m != 0); 358 ASSERT(m != 0);
424 359
425 ASSERT(dal_fixed31_32_lt( 360 ASSERT(dc_fixpt_lt(
426 dal_fixed31_32_abs(r), 361 dc_fixpt_abs(r),
427 dal_fixed31_32_one)); 362 dc_fixpt_one));
428 363
429 if (m > 0) 364 if (m > 0)
430 return dal_fixed31_32_shl( 365 return dc_fixpt_shl(
431 fixed31_32_exp_from_taylor_series(r), 366 fixed31_32_exp_from_taylor_series(r),
432 (uint8_t)m); 367 (unsigned char)m);
433 else 368 else
434 return dal_fixed31_32_div_int( 369 return dc_fixpt_div_int(
435 fixed31_32_exp_from_taylor_series(r), 370 fixed31_32_exp_from_taylor_series(r),
436 1LL << -m); 371 1LL << -m);
437 } else if (arg.value != 0) 372 } else if (arg.value != 0)
438 return fixed31_32_exp_from_taylor_series(arg); 373 return fixed31_32_exp_from_taylor_series(arg);
439 else 374 else
440 return dal_fixed31_32_one; 375 return dc_fixpt_one;
441} 376}
442 377
443struct fixed31_32 dal_fixed31_32_log( 378struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg)
444 struct fixed31_32 arg)
445{ 379{
446 struct fixed31_32 res = dal_fixed31_32_neg(dal_fixed31_32_one); 380 struct fixed31_32 res = dc_fixpt_neg(dc_fixpt_one);
447 /* TODO improve 1st estimation */ 381 /* TODO improve 1st estimation */
448 382
449 struct fixed31_32 error; 383 struct fixed31_32 error;
@@ -453,15 +387,15 @@ struct fixed31_32 dal_fixed31_32_log(
453 /* TODO if arg is zero, return -INF */ 387 /* TODO if arg is zero, return -INF */
454 388
455 do { 389 do {
456 struct fixed31_32 res1 = dal_fixed31_32_add( 390 struct fixed31_32 res1 = dc_fixpt_add(
457 dal_fixed31_32_sub( 391 dc_fixpt_sub(
458 res, 392 res,
459 dal_fixed31_32_one), 393 dc_fixpt_one),
460 dal_fixed31_32_div( 394 dc_fixpt_div(
461 arg, 395 arg,
462 dal_fixed31_32_exp(res))); 396 dc_fixpt_exp(res)));
463 397
464 error = dal_fixed31_32_sub( 398 error = dc_fixpt_sub(
465 res, 399 res,
466 res1); 400 res1);
467 401
@@ -472,78 +406,23 @@ struct fixed31_32 dal_fixed31_32_log(
472 return res; 406 return res;
473} 407}
474 408
475struct fixed31_32 dal_fixed31_32_pow(
476 struct fixed31_32 arg1,
477 struct fixed31_32 arg2)
478{
479 return dal_fixed31_32_exp(
480 dal_fixed31_32_mul(
481 dal_fixed31_32_log(arg1),
482 arg2));
483}
484
485int32_t dal_fixed31_32_floor(
486 struct fixed31_32 arg)
487{
488 uint64_t arg_value = abs_i64(arg.value);
489
490 if (arg.value >= 0)
491 return (int32_t)GET_INTEGER_PART(arg_value);
492 else
493 return -(int32_t)GET_INTEGER_PART(arg_value);
494}
495
496int32_t dal_fixed31_32_round(
497 struct fixed31_32 arg)
498{
499 uint64_t arg_value = abs_i64(arg.value);
500
501 const int64_t summand = dal_fixed31_32_half.value;
502
503 ASSERT(LLONG_MAX - (int64_t)arg_value >= summand);
504
505 arg_value += summand;
506
507 if (arg.value >= 0)
508 return (int32_t)GET_INTEGER_PART(arg_value);
509 else
510 return -(int32_t)GET_INTEGER_PART(arg_value);
511}
512
513int32_t dal_fixed31_32_ceil(
514 struct fixed31_32 arg)
515{
516 uint64_t arg_value = abs_i64(arg.value);
517
518 const int64_t summand = dal_fixed31_32_one.value -
519 dal_fixed31_32_epsilon.value;
520
521 ASSERT(LLONG_MAX - (int64_t)arg_value >= summand);
522
523 arg_value += summand;
524
525 if (arg.value >= 0)
526 return (int32_t)GET_INTEGER_PART(arg_value);
527 else
528 return -(int32_t)GET_INTEGER_PART(arg_value);
529}
530 409
531/* this function is a generic helper to translate fixed point value to 410/* this function is a generic helper to translate fixed point value to
532 * specified integer format that will consist of integer_bits integer part and 411 * specified integer format that will consist of integer_bits integer part and
533 * fractional_bits fractional part. For example it is used in 412 * fractional_bits fractional part. For example it is used in
534 * dal_fixed31_32_u2d19 to receive 2 bits integer part and 19 bits fractional 413 * dc_fixpt_u2d19 to receive 2 bits integer part and 19 bits fractional
535 * part in 32 bits. It is used in hw programming (scaler) 414 * part in 32 bits. It is used in hw programming (scaler)
536 */ 415 */
537 416
538static inline uint32_t ux_dy( 417static inline unsigned int ux_dy(
539 int64_t value, 418 long long value,
540 uint32_t integer_bits, 419 unsigned int integer_bits,
541 uint32_t fractional_bits) 420 unsigned int fractional_bits)
542{ 421{
543 /* 1. create mask of integer part */ 422 /* 1. create mask of integer part */
544 uint32_t result = (1 << integer_bits) - 1; 423 unsigned int result = (1 << integer_bits) - 1;
545 /* 2. mask out fractional part */ 424 /* 2. mask out fractional part */
546 uint32_t fractional_part = FRACTIONAL_PART_MASK & value; 425 unsigned int fractional_part = FRACTIONAL_PART_MASK & value;
547 /* 3. shrink fixed point integer part to be of integer_bits width*/ 426 /* 3. shrink fixed point integer part to be of integer_bits width*/
548 result &= GET_INTEGER_PART(value); 427 result &= GET_INTEGER_PART(value);
549 /* 4. make space for fractional part to be filled in after integer */ 428 /* 4. make space for fractional part to be filled in after integer */
@@ -554,13 +433,13 @@ static inline uint32_t ux_dy(
554 return result | fractional_part; 433 return result | fractional_part;
555} 434}
556 435
557static inline uint32_t clamp_ux_dy( 436static inline unsigned int clamp_ux_dy(
558 int64_t value, 437 long long value,
559 uint32_t integer_bits, 438 unsigned int integer_bits,
560 uint32_t fractional_bits, 439 unsigned int fractional_bits,
561 uint32_t min_clamp) 440 unsigned int min_clamp)
562{ 441{
563 uint32_t truncated_val = ux_dy(value, integer_bits, fractional_bits); 442 unsigned int truncated_val = ux_dy(value, integer_bits, fractional_bits);
564 443
565 if (value >= (1LL << (integer_bits + FIXED31_32_BITS_PER_FRACTIONAL_PART))) 444 if (value >= (1LL << (integer_bits + FIXED31_32_BITS_PER_FRACTIONAL_PART)))
566 return (1 << (integer_bits + fractional_bits)) - 1; 445 return (1 << (integer_bits + fractional_bits)) - 1;
@@ -570,35 +449,30 @@ static inline uint32_t clamp_ux_dy(
570 return min_clamp; 449 return min_clamp;
571} 450}
572 451
573uint32_t dal_fixed31_32_u2d19( 452unsigned int dc_fixpt_u2d19(struct fixed31_32 arg)
574 struct fixed31_32 arg)
575{ 453{
576 return ux_dy(arg.value, 2, 19); 454 return ux_dy(arg.value, 2, 19);
577} 455}
578 456
579uint32_t dal_fixed31_32_u0d19( 457unsigned int dc_fixpt_u0d19(struct fixed31_32 arg)
580 struct fixed31_32 arg)
581{ 458{
582 return ux_dy(arg.value, 0, 19); 459 return ux_dy(arg.value, 0, 19);
583} 460}
584 461
585uint32_t dal_fixed31_32_clamp_u0d14( 462unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg)
586 struct fixed31_32 arg)
587{ 463{
588 return clamp_ux_dy(arg.value, 0, 14, 1); 464 return clamp_ux_dy(arg.value, 0, 14, 1);
589} 465}
590 466
591uint32_t dal_fixed31_32_clamp_u0d10( 467unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg)
592 struct fixed31_32 arg)
593{ 468{
594 return clamp_ux_dy(arg.value, 0, 10, 1); 469 return clamp_ux_dy(arg.value, 0, 10, 1);
595} 470}
596 471
597int32_t dal_fixed31_32_s4d19( 472int dc_fixpt_s4d19(struct fixed31_32 arg)
598 struct fixed31_32 arg)
599{ 473{
600 if (arg.value < 0) 474 if (arg.value < 0)
601 return -(int32_t)ux_dy(dal_fixed31_32_abs(arg).value, 4, 19); 475 return -(int)ux_dy(dc_fixpt_abs(arg).value, 4, 19);
602 else 476 else
603 return ux_dy(arg.value, 4, 19); 477 return ux_dy(arg.value, 4, 19);
604} 478}
diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt32_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt32_32.c
deleted file mode 100644
index 4d3aaa82a07b..000000000000
--- a/drivers/gpu/drm/amd/display/dc/basics/fixpt32_32.c
+++ /dev/null
@@ -1,161 +0,0 @@
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#include "dm_services.h"
27#include "include/fixed32_32.h"
28
29static uint64_t u64_div(uint64_t n, uint64_t d)
30{
31 uint32_t i = 0;
32 uint64_t r;
33 uint64_t q = div64_u64_rem(n, d, &r);
34
35 for (i = 0; i < 32; ++i) {
36 uint64_t sbit = q & (1ULL<<63);
37
38 r <<= 1;
39 r |= sbit ? 1 : 0;
40 q <<= 1;
41 if (r >= d) {
42 r -= d;
43 q |= 1;
44 }
45 }
46
47 if (2*r >= d)
48 q += 1;
49 return q;
50}
51
52struct fixed32_32 dal_fixed32_32_from_fraction(uint32_t n, uint32_t d)
53{
54 struct fixed32_32 fx;
55
56 fx.value = u64_div((uint64_t)n << 32, (uint64_t)d << 32);
57 return fx;
58}
59
60struct fixed32_32 dal_fixed32_32_add(
61 struct fixed32_32 lhs,
62 struct fixed32_32 rhs)
63{
64 struct fixed32_32 fx = {lhs.value + rhs.value};
65
66 ASSERT(fx.value >= rhs.value);
67 return fx;
68}
69
70struct fixed32_32 dal_fixed32_32_add_int(struct fixed32_32 lhs, uint32_t rhs)
71{
72 struct fixed32_32 fx = {lhs.value + ((uint64_t)rhs << 32)};
73
74 ASSERT(fx.value >= (uint64_t)rhs << 32);
75 return fx;
76
77}
78struct fixed32_32 dal_fixed32_32_sub(
79 struct fixed32_32 lhs,
80 struct fixed32_32 rhs)
81{
82 struct fixed32_32 fx;
83
84 ASSERT(lhs.value >= rhs.value);
85 fx.value = lhs.value - rhs.value;
86 return fx;
87}
88
89struct fixed32_32 dal_fixed32_32_sub_int(struct fixed32_32 lhs, uint32_t rhs)
90{
91 struct fixed32_32 fx;
92
93 ASSERT(lhs.value >= ((uint64_t)rhs<<32));
94 fx.value = lhs.value - ((uint64_t)rhs<<32);
95 return fx;
96}
97
98struct fixed32_32 dal_fixed32_32_mul(
99 struct fixed32_32 lhs,
100 struct fixed32_32 rhs)
101{
102 struct fixed32_32 fx;
103 uint64_t lhs_int = lhs.value>>32;
104 uint64_t lhs_frac = (uint32_t)lhs.value;
105 uint64_t rhs_int = rhs.value>>32;
106 uint64_t rhs_frac = (uint32_t)rhs.value;
107 uint64_t ahbh = lhs_int * rhs_int;
108 uint64_t ahbl = lhs_int * rhs_frac;
109 uint64_t albh = lhs_frac * rhs_int;
110 uint64_t albl = lhs_frac * rhs_frac;
111
112 ASSERT((ahbh>>32) == 0);
113
114 fx.value = (ahbh<<32) + ahbl + albh + (albl>>32);
115 return fx;
116
117}
118
119struct fixed32_32 dal_fixed32_32_mul_int(struct fixed32_32 lhs, uint32_t rhs)
120{
121 struct fixed32_32 fx;
122 uint64_t lhsi = (lhs.value>>32) * (uint64_t)rhs;
123 uint64_t lhsf;
124
125 ASSERT((lhsi>>32) == 0);
126 lhsf = ((uint32_t)lhs.value) * (uint64_t)rhs;
127 ASSERT((lhsi<<32) + lhsf >= lhsf);
128 fx.value = (lhsi<<32) + lhsf;
129 return fx;
130}
131
132struct fixed32_32 dal_fixed32_32_div(
133 struct fixed32_32 lhs,
134 struct fixed32_32 rhs)
135{
136 struct fixed32_32 fx;
137
138 fx.value = u64_div(lhs.value, rhs.value);
139 return fx;
140}
141
142struct fixed32_32 dal_fixed32_32_div_int(struct fixed32_32 lhs, uint32_t rhs)
143{
144 struct fixed32_32 fx;
145
146 fx.value = u64_div(lhs.value, (uint64_t)rhs << 32);
147 return fx;
148}
149
150uint32_t dal_fixed32_32_ceil(struct fixed32_32 v)
151{
152 ASSERT((uint32_t)v.value ? (v.value >> 32) + 1 >= 1 : true);
153 return (v.value>>32) + ((uint32_t)v.value ? 1 : 0);
154}
155
156uint32_t dal_fixed32_32_round(struct fixed32_32 v)
157{
158 ASSERT(v.value + (1ULL<<31) >= (1ULL<<31));
159 return (v.value + (1ULL<<31))>>32;
160}
161
diff --git a/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c b/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c
index 854678a0c54b..021451549ff7 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c
@@ -94,7 +94,6 @@ void dc_conn_log(struct dc_context *ctx,
94 dm_logger_append(&entry, "%2.2X ", hex_data[i]); 94 dm_logger_append(&entry, "%2.2X ", hex_data[i]);
95 95
96 dm_logger_append(&entry, "^\n"); 96 dm_logger_append(&entry, "^\n");
97 dm_helpers_dc_conn_log(ctx, &entry, event);
98 97
99fail: 98fail:
100 dm_logger_close(&entry); 99 dm_logger_close(&entry);
diff --git a/drivers/gpu/drm/amd/display/dc/basics/logger.c b/drivers/gpu/drm/amd/display/dc/basics/logger.c
index 31bee054f43a..738a818d58d1 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/logger.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/logger.c
@@ -61,7 +61,7 @@ static const struct dc_log_type_info log_type_info_tbl[] = {
61 {LOG_EVENT_UNDERFLOW, "Underflow"}, 61 {LOG_EVENT_UNDERFLOW, "Underflow"},
62 {LOG_IF_TRACE, "InterfaceTrace"}, 62 {LOG_IF_TRACE, "InterfaceTrace"},
63 {LOG_DTN, "DTN"}, 63 {LOG_DTN, "DTN"},
64 {LOG_PROFILING, "Profiling"} 64 {LOG_DISPLAYSTATS, "DisplayStats"}
65}; 65};
66 66
67 67
@@ -402,3 +402,4 @@ cleanup:
402 entry->max_buf_bytes = 0; 402 entry->max_buf_bytes = 0;
403 } 403 }
404} 404}
405
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
index 10a5807a7e8b..b8cef7af3c4a 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -1330,6 +1330,9 @@ static enum bp_result bios_parser_get_firmware_info(
1330 case 2: 1330 case 2:
1331 result = get_firmware_info_v3_2(bp, info); 1331 result = get_firmware_info_v3_2(bp, info);
1332 break; 1332 break;
1333 case 3:
1334 result = get_firmware_info_v3_2(bp, info);
1335 break;
1333 default: 1336 default:
1334 break; 1337 break;
1335 } 1338 }
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
index 4b5fdd577848..651e1fd4622f 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
@@ -24,7 +24,7 @@
24 */ 24 */
25 25
26#include "dm_services.h" 26#include "dm_services.h"
27 27#include "amdgpu.h"
28#include "atom.h" 28#include "atom.h"
29 29
30#include "include/bios_parser_interface.h" 30#include "include/bios_parser_interface.h"
@@ -35,16 +35,16 @@
35#include "bios_parser_types_internal.h" 35#include "bios_parser_types_internal.h"
36 36
37#define EXEC_BIOS_CMD_TABLE(command, params)\ 37#define EXEC_BIOS_CMD_TABLE(command, params)\
38 (cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \ 38 (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
39 GetIndexIntoMasterTable(COMMAND, command), \ 39 GetIndexIntoMasterTable(COMMAND, command), \
40 &params) == 0) 40 (uint32_t *)&params) == 0)
41 41
42#define BIOS_CMD_TABLE_REVISION(command, frev, crev)\ 42#define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
43 cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \ 43 amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
44 GetIndexIntoMasterTable(COMMAND, command), &frev, &crev) 44 GetIndexIntoMasterTable(COMMAND, command), &frev, &crev)
45 45
46#define BIOS_CMD_TABLE_PARA_REVISION(command)\ 46#define BIOS_CMD_TABLE_PARA_REVISION(command)\
47 bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \ 47 bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
48 GetIndexIntoMasterTable(COMMAND, command)) 48 GetIndexIntoMasterTable(COMMAND, command))
49 49
50static void init_dig_encoder_control(struct bios_parser *bp); 50static void init_dig_encoder_control(struct bios_parser *bp);
@@ -82,16 +82,18 @@ void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
82 init_set_dce_clock(bp); 82 init_set_dce_clock(bp);
83} 83}
84 84
85static uint32_t bios_cmd_table_para_revision(void *cgs_device, 85static uint32_t bios_cmd_table_para_revision(void *dev,
86 uint32_t index) 86 uint32_t index)
87{ 87{
88 struct amdgpu_device *adev = dev;
88 uint8_t frev, crev; 89 uint8_t frev, crev;
89 90
90 if (cgs_atom_get_cmd_table_revs(cgs_device, 91 if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context,
91 index, 92 index,
92 &frev, &crev) != 0) 93 &frev, &crev))
94 return crev;
95 else
93 return 0; 96 return 0;
94 return crev;
95} 97}
96 98
97/******************************************************************************* 99/*******************************************************************************
@@ -368,7 +370,7 @@ static void init_transmitter_control(struct bios_parser *bp)
368 uint8_t crev; 370 uint8_t crev;
369 371
370 if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl, 372 if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl,
371 frev, crev) != 0) 373 frev, crev) == false)
372 BREAK_TO_DEBUGGER(); 374 BREAK_TO_DEBUGGER();
373 switch (crev) { 375 switch (crev) {
374 case 2: 376 case 2:
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
index 3f63f712c8a4..752b08a42d3e 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
@@ -26,14 +26,18 @@
26#include "dm_services.h" 26#include "dm_services.h"
27 27
28#include "ObjectID.h" 28#include "ObjectID.h"
29#include "atomfirmware.h"
30 29
30#include "atomfirmware.h"
31#include "atom.h"
31#include "include/bios_parser_interface.h" 32#include "include/bios_parser_interface.h"
32 33
33#include "command_table2.h" 34#include "command_table2.h"
34#include "command_table_helper2.h" 35#include "command_table_helper2.h"
35#include "bios_parser_helper.h" 36#include "bios_parser_helper.h"
36#include "bios_parser_types_internal2.h" 37#include "bios_parser_types_internal2.h"
38#include "amdgpu.h"
39
40
37#define DC_LOGGER \ 41#define DC_LOGGER \
38 bp->base.ctx->logger 42 bp->base.ctx->logger
39 43
@@ -43,16 +47,16 @@
43 ->FieldName)-(char *)0)/sizeof(uint16_t)) 47 ->FieldName)-(char *)0)/sizeof(uint16_t))
44 48
45#define EXEC_BIOS_CMD_TABLE(fname, params)\ 49#define EXEC_BIOS_CMD_TABLE(fname, params)\
46 (cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \ 50 (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
47 GET_INDEX_INTO_MASTER_TABLE(command, fname), \ 51 GET_INDEX_INTO_MASTER_TABLE(command, fname), \
48 &params) == 0) 52 (uint32_t *)&params) == 0)
49 53
50#define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\ 54#define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\
51 cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \ 55 amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
52 GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev) 56 GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev)
53 57
54#define BIOS_CMD_TABLE_PARA_REVISION(fname)\ 58#define BIOS_CMD_TABLE_PARA_REVISION(fname)\
55 bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \ 59 bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
56 GET_INDEX_INTO_MASTER_TABLE(command, fname)) 60 GET_INDEX_INTO_MASTER_TABLE(command, fname))
57 61
58static void init_dig_encoder_control(struct bios_parser *bp); 62static void init_dig_encoder_control(struct bios_parser *bp);
@@ -86,16 +90,18 @@ void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)
86 init_get_smu_clock_info(bp); 90 init_get_smu_clock_info(bp);
87} 91}
88 92
89static uint32_t bios_cmd_table_para_revision(void *cgs_device, 93static uint32_t bios_cmd_table_para_revision(void *dev,
90 uint32_t index) 94 uint32_t index)
91{ 95{
96 struct amdgpu_device *adev = dev;
92 uint8_t frev, crev; 97 uint8_t frev, crev;
93 98
94 if (cgs_atom_get_cmd_table_revs(cgs_device, 99 if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context,
95 index, 100 index,
96 &frev, &crev) != 0) 101 &frev, &crev))
102 return crev;
103 else
97 return 0; 104 return 0;
98 return crev;
99} 105}
100 106
101/****************************************************************************** 107/******************************************************************************
@@ -201,7 +207,7 @@ static void init_transmitter_control(struct bios_parser *bp)
201 uint8_t frev; 207 uint8_t frev;
202 uint8_t crev; 208 uint8_t crev;
203 209
204 if (BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) != 0) 210 if (BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) == false)
205 BREAK_TO_DEBUGGER(); 211 BREAK_TO_DEBUGGER();
206 switch (crev) { 212 switch (crev) {
207 case 6: 213 case 6:
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c
index 2979358c6a55..253bbb1eea60 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c
@@ -51,6 +51,7 @@ bool dal_bios_parser_init_cmd_tbl_helper(
51 return true; 51 return true;
52 52
53 case DCE_VERSION_11_2: 53 case DCE_VERSION_11_2:
54 case DCE_VERSION_11_22:
54 *h = dal_cmd_tbl_helper_dce112_get_table(); 55 *h = dal_cmd_tbl_helper_dce112_get_table();
55 return true; 56 return true;
56 57
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
index 9a4d30dd4969..bbbcef566c55 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
@@ -52,6 +52,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2(
52 return true; 52 return true;
53 53
54 case DCE_VERSION_11_2: 54 case DCE_VERSION_11_2:
55 case DCE_VERSION_11_22:
55 *h = dal_cmd_tbl_helper_dce112_get_table2(); 56 *h = dal_cmd_tbl_helper_dce112_get_table2();
56 return true; 57 return true;
57#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 58#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h b/drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h
new file mode 100644
index 000000000000..fc3f98fb09ea
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h
@@ -0,0 +1,579 @@
1/*
2 * Copyright 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#ifndef _CALCS_CALCS_LOGGER_H_
27#define _CALCS_CALCS_LOGGER_H_
28#define DC_LOGGER \
29 logger
30
31static void print_bw_calcs_dceip(struct dal_logger *logger, const struct bw_calcs_dceip *dceip)
32{
33
34 DC_LOG_BANDWIDTH_CALCS("#####################################################################");
35 DC_LOG_BANDWIDTH_CALCS("struct bw_calcs_dceip");
36 DC_LOG_BANDWIDTH_CALCS("#####################################################################");
37 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_calcs_version version %d", dceip->version);
38 DC_LOG_BANDWIDTH_CALCS(" [bool] large_cursor: %d", dceip->large_cursor);
39 DC_LOG_BANDWIDTH_CALCS(" [bool] dmif_pipe_en_fbc_chunk_tracker: %d", dceip->dmif_pipe_en_fbc_chunk_tracker);
40 DC_LOG_BANDWIDTH_CALCS(" [bool] display_write_back_supported: %d", dceip->display_write_back_supported);
41 DC_LOG_BANDWIDTH_CALCS(" [bool] argb_compression_support: %d", dceip->argb_compression_support);
42 DC_LOG_BANDWIDTH_CALCS(" [bool] pre_downscaler_enabled: %d", dceip->pre_downscaler_enabled);
43 DC_LOG_BANDWIDTH_CALCS(" [bool] underlay_downscale_prefetch_enabled: %d",
44 dceip->underlay_downscale_prefetch_enabled);
45 DC_LOG_BANDWIDTH_CALCS(" [bool] graphics_lb_nodownscaling_multi_line_prefetching: %d",
46 dceip->graphics_lb_nodownscaling_multi_line_prefetching);
47 DC_LOG_BANDWIDTH_CALCS(" [bool] limit_excessive_outstanding_dmif_requests: %d",
48 dceip->limit_excessive_outstanding_dmif_requests);
49 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] cursor_max_outstanding_group_num: %d",
50 dceip->cursor_max_outstanding_group_num);
51 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] lines_interleaved_into_lb: %d", dceip->lines_interleaved_into_lb);
52 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] low_power_tiling_mode: %d", dceip->low_power_tiling_mode);
53 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] chunk_width: %d", dceip->chunk_width);
54 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] number_of_graphics_pipes: %d", dceip->number_of_graphics_pipes);
55 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] number_of_underlay_pipes: %d", dceip->number_of_underlay_pipes);
56 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] max_dmif_buffer_allocated: %d", dceip->max_dmif_buffer_allocated);
57 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] graphics_dmif_size: %d", dceip->graphics_dmif_size);
58 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] underlay_luma_dmif_size: %d", dceip->underlay_luma_dmif_size);
59 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] underlay_chroma_dmif_size: %d", dceip->underlay_chroma_dmif_size);
60 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] scatter_gather_lines_of_pte_prefetching_in_linear_mode: %d",
61 dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode);
62 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] display_write_back420_luma_mcifwr_buffer_size: %d",
63 dceip->display_write_back420_luma_mcifwr_buffer_size);
64 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] display_write_back420_chroma_mcifwr_buffer_size: %d",
65 dceip->display_write_back420_chroma_mcifwr_buffer_size);
66 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] scatter_gather_pte_request_rows_in_tiling_mode: %d",
67 dceip->scatter_gather_pte_request_rows_in_tiling_mode);
68 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] underlay_vscaler_efficiency10_bit_per_component: %d",
69 bw_fixed_to_int(dceip->underlay_vscaler_efficiency10_bit_per_component));
70 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] underlay_vscaler_efficiency12_bit_per_component: %d",
71 bw_fixed_to_int(dceip->underlay_vscaler_efficiency12_bit_per_component));
72 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] graphics_vscaler_efficiency6_bit_per_component: %d",
73 bw_fixed_to_int(dceip->graphics_vscaler_efficiency6_bit_per_component));
74 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] graphics_vscaler_efficiency8_bit_per_component: %d",
75 bw_fixed_to_int(dceip->graphics_vscaler_efficiency8_bit_per_component));
76 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] graphics_vscaler_efficiency10_bit_per_component: %d",
77 bw_fixed_to_int(dceip->graphics_vscaler_efficiency10_bit_per_component));
78 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] graphics_vscaler_efficiency12_bit_per_component: %d",
79 bw_fixed_to_int(dceip->graphics_vscaler_efficiency12_bit_per_component));
80 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] alpha_vscaler_efficiency: %d",
81 bw_fixed_to_int(dceip->alpha_vscaler_efficiency));
82 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] lb_write_pixels_per_dispclk: %d",
83 bw_fixed_to_int(dceip->lb_write_pixels_per_dispclk));
84 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] lb_size_per_component444: %d",
85 bw_fixed_to_int(dceip->lb_size_per_component444));
86 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_and_dram_clock_state_change_gated_before_cursor: %d",
87 bw_fixed_to_int(dceip->stutter_and_dram_clock_state_change_gated_before_cursor));
88 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] underlay420_luma_lb_size_per_component: %d",
89 bw_fixed_to_int(dceip->underlay420_luma_lb_size_per_component));
90 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] underlay420_chroma_lb_size_per_component: %d",
91 bw_fixed_to_int(dceip->underlay420_chroma_lb_size_per_component));
92 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] underlay422_lb_size_per_component: %d",
93 bw_fixed_to_int(dceip->underlay422_lb_size_per_component));
94 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] cursor_chunk_width: %d", bw_fixed_to_int(dceip->cursor_chunk_width));
95 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] cursor_dcp_buffer_lines: %d",
96 bw_fixed_to_int(dceip->cursor_dcp_buffer_lines));
97 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] underlay_maximum_width_efficient_for_tiling: %d",
98 bw_fixed_to_int(dceip->underlay_maximum_width_efficient_for_tiling));
99 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] underlay_maximum_height_efficient_for_tiling: %d",
100 bw_fixed_to_int(dceip->underlay_maximum_height_efficient_for_tiling));
101 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display: %d",
102 bw_fixed_to_int(dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display));
103 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation: %d",
104 bw_fixed_to_int(dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation));
105 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] minimum_outstanding_pte_request_limit: %d",
106 bw_fixed_to_int(dceip->minimum_outstanding_pte_request_limit));
107 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] maximum_total_outstanding_pte_requests_allowed_by_saw: %d",
108 bw_fixed_to_int(dceip->maximum_total_outstanding_pte_requests_allowed_by_saw));
109 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] linear_mode_line_request_alternation_slice: %d",
110 bw_fixed_to_int(dceip->linear_mode_line_request_alternation_slice));
111 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] request_efficiency: %d", bw_fixed_to_int(dceip->request_efficiency));
112 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dispclk_per_request: %d", bw_fixed_to_int(dceip->dispclk_per_request));
113 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dispclk_ramping_factor: %d",
114 bw_fixed_to_int(dceip->dispclk_ramping_factor));
115 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] display_pipe_throughput_factor: %d",
116 bw_fixed_to_int(dceip->display_pipe_throughput_factor));
117 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mcifwr_all_surfaces_burst_time: %d",
118 bw_fixed_to_int(dceip->mcifwr_all_surfaces_burst_time));
119 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmif_request_buffer_size: %d",
120 bw_fixed_to_int(dceip->dmif_request_buffer_size));
121
122
123}
124
125static void print_bw_calcs_vbios(struct dal_logger *logger, const struct bw_calcs_vbios *vbios)
126{
127
128 DC_LOG_BANDWIDTH_CALCS("#####################################################################");
129 DC_LOG_BANDWIDTH_CALCS("struct bw_calcs_vbios vbios");
130 DC_LOG_BANDWIDTH_CALCS("#####################################################################");
131 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines memory_type: %d", vbios->memory_type);
132 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines memory_type: %d", vbios->memory_type);
133 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] dram_channel_width_in_bits: %d", vbios->dram_channel_width_in_bits);
134 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] number_of_dram_channels: %d", vbios->number_of_dram_channels);
135 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] number_of_dram_banks: %d", vbios->number_of_dram_banks);
136 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] low_yclk: %d", bw_fixed_to_int(vbios->low_yclk));
137 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mid_yclk: %d", bw_fixed_to_int(vbios->mid_yclk));
138 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] high_yclk: %d", bw_fixed_to_int(vbios->high_yclk));
139 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] low_sclk: %d", bw_fixed_to_int(vbios->low_sclk));
140 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mid1_sclk: %d", bw_fixed_to_int(vbios->mid1_sclk));
141 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mid2_sclk: %d", bw_fixed_to_int(vbios->mid2_sclk));
142 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mid3_sclk: %d", bw_fixed_to_int(vbios->mid3_sclk));
143 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mid4_sclk: %d", bw_fixed_to_int(vbios->mid4_sclk));
144 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mid5_sclk: %d", bw_fixed_to_int(vbios->mid5_sclk));
145 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mid6_sclk: %d", bw_fixed_to_int(vbios->mid6_sclk));
146 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] high_sclk: %d", bw_fixed_to_int(vbios->high_sclk));
147 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] low_voltage_max_dispclk: %d",
148 bw_fixed_to_int(vbios->low_voltage_max_dispclk));
149 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mid_voltage_max_dispclk;: %d",
150 bw_fixed_to_int(vbios->mid_voltage_max_dispclk));
151 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] high_voltage_max_dispclk;: %d",
152 bw_fixed_to_int(vbios->high_voltage_max_dispclk));
153 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] low_voltage_max_phyclk: %d",
154 bw_fixed_to_int(vbios->low_voltage_max_phyclk));
155 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mid_voltage_max_phyclk: %d",
156 bw_fixed_to_int(vbios->mid_voltage_max_phyclk));
157 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] high_voltage_max_phyclk: %d",
158 bw_fixed_to_int(vbios->high_voltage_max_phyclk));
159 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] data_return_bus_width: %d", bw_fixed_to_int(vbios->data_return_bus_width));
160 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] trc: %d", bw_fixed_to_int(vbios->trc));
161 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmifmc_urgent_latency: %d", bw_fixed_to_int(vbios->dmifmc_urgent_latency));
162 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_self_refresh_exit_latency: %d",
163 bw_fixed_to_int(vbios->stutter_self_refresh_exit_latency));
164 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_self_refresh_entry_latency: %d",
165 bw_fixed_to_int(vbios->stutter_self_refresh_entry_latency));
166 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] nbp_state_change_latency: %d",
167 bw_fixed_to_int(vbios->nbp_state_change_latency));
168 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mcifwrmc_urgent_latency: %d",
169 bw_fixed_to_int(vbios->mcifwrmc_urgent_latency));
170 DC_LOG_BANDWIDTH_CALCS(" [bool] scatter_gather_enable: %d", vbios->scatter_gather_enable);
171 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] down_spread_percentage: %d",
172 bw_fixed_to_int(vbios->down_spread_percentage));
173 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] cursor_width: %d", vbios->cursor_width);
174 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] average_compression_rate: %d", vbios->average_compression_rate);
175 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] number_of_request_slots_gmc_reserves_for_dmif_per_channel: %d",
176 vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel);
177 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] blackout_duration: %d", bw_fixed_to_int(vbios->blackout_duration));
178 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] maximum_blackout_recovery_time: %d",
179 bw_fixed_to_int(vbios->maximum_blackout_recovery_time));
180
181
182}
183
184static void print_bw_calcs_data(struct dal_logger *logger, struct bw_calcs_data *data)
185{
186
187 int i, j, k;
188
189 DC_LOG_BANDWIDTH_CALCS("#####################################################################");
190 DC_LOG_BANDWIDTH_CALCS("struct bw_calcs_data data");
191 DC_LOG_BANDWIDTH_CALCS("#####################################################################");
192 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] number_of_displays: %d", data->number_of_displays);
193 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines underlay_surface_type: %d", data->underlay_surface_type);
194 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines panning_and_bezel_adjustment: %d",
195 data->panning_and_bezel_adjustment);
196 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines graphics_tiling_mode: %d", data->graphics_tiling_mode);
197 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] graphics_lb_bpc: %d", data->graphics_lb_bpc);
198 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] underlay_lb_bpc: %d", data->underlay_lb_bpc);
199 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines underlay_tiling_mode: %d", data->underlay_tiling_mode);
200 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines d0_underlay_mode: %d", data->d0_underlay_mode);
201 DC_LOG_BANDWIDTH_CALCS(" [bool] d1_display_write_back_dwb_enable: %d", data->d1_display_write_back_dwb_enable);
202 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines d1_underlay_mode: %d", data->d1_underlay_mode);
203 DC_LOG_BANDWIDTH_CALCS(" [bool] cpup_state_change_enable: %d", data->cpup_state_change_enable);
204 DC_LOG_BANDWIDTH_CALCS(" [bool] cpuc_state_change_enable: %d", data->cpuc_state_change_enable);
205 DC_LOG_BANDWIDTH_CALCS(" [bool] nbp_state_change_enable: %d", data->nbp_state_change_enable);
206 DC_LOG_BANDWIDTH_CALCS(" [bool] stutter_mode_enable: %d", data->stutter_mode_enable);
207 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] y_clk_level: %d", data->y_clk_level);
208 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] sclk_level: %d", data->sclk_level);
209 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] number_of_underlay_surfaces: %d", data->number_of_underlay_surfaces);
210 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] number_of_dram_wrchannels: %d", data->number_of_dram_wrchannels);
211 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] chunk_request_delay: %d", data->chunk_request_delay);
212 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] number_of_dram_channels: %d", data->number_of_dram_channels);
213 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines underlay_micro_tile_mode: %d", data->underlay_micro_tile_mode);
214 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines graphics_micro_tile_mode: %d", data->graphics_micro_tile_mode);
215 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] max_phyclk: %d", bw_fixed_to_int(data->max_phyclk));
216 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dram_efficiency: %d", bw_fixed_to_int(data->dram_efficiency));
217 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_width_after_surface_type: %d",
218 bw_fixed_to_int(data->src_width_after_surface_type));
219 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_height_after_surface_type: %d",
220 bw_fixed_to_int(data->src_height_after_surface_type));
221 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] hsr_after_surface_type: %d",
222 bw_fixed_to_int(data->hsr_after_surface_type));
223 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] vsr_after_surface_type: %d", bw_fixed_to_int(data->vsr_after_surface_type));
224 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_width_after_rotation: %d",
225 bw_fixed_to_int(data->src_width_after_rotation));
226 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_height_after_rotation: %d",
227 bw_fixed_to_int(data->src_height_after_rotation));
228 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] hsr_after_rotation: %d", bw_fixed_to_int(data->hsr_after_rotation));
229 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] vsr_after_rotation: %d", bw_fixed_to_int(data->vsr_after_rotation));
230 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] source_height_pixels: %d", bw_fixed_to_int(data->source_height_pixels));
231 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] hsr_after_stereo: %d", bw_fixed_to_int(data->hsr_after_stereo));
232 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] vsr_after_stereo: %d", bw_fixed_to_int(data->vsr_after_stereo));
233 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] source_width_in_lb: %d", bw_fixed_to_int(data->source_width_in_lb));
234 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] lb_line_pitch: %d", bw_fixed_to_int(data->lb_line_pitch));
235 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] underlay_maximum_source_efficient_for_tiling: %d",
236 bw_fixed_to_int(data->underlay_maximum_source_efficient_for_tiling));
237 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] num_lines_at_frame_start: %d",
238 bw_fixed_to_int(data->num_lines_at_frame_start));
239 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] min_dmif_size_in_time: %d", bw_fixed_to_int(data->min_dmif_size_in_time));
240 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] min_mcifwr_size_in_time: %d",
241 bw_fixed_to_int(data->min_mcifwr_size_in_time));
242 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_requests_for_dmif_size: %d",
243 bw_fixed_to_int(data->total_requests_for_dmif_size));
244 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] peak_pte_request_to_eviction_ratio_limiting: %d",
245 bw_fixed_to_int(data->peak_pte_request_to_eviction_ratio_limiting));
246 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] useful_pte_per_pte_request: %d",
247 bw_fixed_to_int(data->useful_pte_per_pte_request));
248 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scatter_gather_pte_request_rows: %d",
249 bw_fixed_to_int(data->scatter_gather_pte_request_rows));
250 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scatter_gather_row_height: %d",
251 bw_fixed_to_int(data->scatter_gather_row_height));
252 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scatter_gather_pte_requests_in_vblank: %d",
253 bw_fixed_to_int(data->scatter_gather_pte_requests_in_vblank));
254 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] inefficient_linear_pitch_in_bytes: %d",
255 bw_fixed_to_int(data->inefficient_linear_pitch_in_bytes));
256 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] cursor_total_data: %d", bw_fixed_to_int(data->cursor_total_data));
257 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] cursor_total_request_groups: %d",
258 bw_fixed_to_int(data->cursor_total_request_groups));
259 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scatter_gather_total_pte_requests: %d",
260 bw_fixed_to_int(data->scatter_gather_total_pte_requests));
261 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scatter_gather_total_pte_request_groups: %d",
262 bw_fixed_to_int(data->scatter_gather_total_pte_request_groups));
263 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] tile_width_in_pixels: %d", bw_fixed_to_int(data->tile_width_in_pixels));
264 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmif_total_number_of_data_request_page_close_open: %d",
265 bw_fixed_to_int(data->dmif_total_number_of_data_request_page_close_open));
266 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mcifwr_total_number_of_data_request_page_close_open: %d",
267 bw_fixed_to_int(data->mcifwr_total_number_of_data_request_page_close_open));
268 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] bytes_per_page_close_open: %d",
269 bw_fixed_to_int(data->bytes_per_page_close_open));
270 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mcifwr_total_page_close_open_time: %d",
271 bw_fixed_to_int(data->mcifwr_total_page_close_open_time));
272 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_requests_for_adjusted_dmif_size: %d",
273 bw_fixed_to_int(data->total_requests_for_adjusted_dmif_size));
274 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_dmifmc_urgent_trips: %d",
275 bw_fixed_to_int(data->total_dmifmc_urgent_trips));
276 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_dmifmc_urgent_latency: %d",
277 bw_fixed_to_int(data->total_dmifmc_urgent_latency));
278 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_display_reads_required_data: %d",
279 bw_fixed_to_int(data->total_display_reads_required_data));
280 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_display_reads_required_dram_access_data: %d",
281 bw_fixed_to_int(data->total_display_reads_required_dram_access_data));
282 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_display_writes_required_data: %d",
283 bw_fixed_to_int(data->total_display_writes_required_data));
284 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_display_writes_required_dram_access_data: %d",
285 bw_fixed_to_int(data->total_display_writes_required_dram_access_data));
286 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] display_reads_required_data: %d",
287 bw_fixed_to_int(data->display_reads_required_data));
288 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] display_reads_required_dram_access_data: %d",
289 bw_fixed_to_int(data->display_reads_required_dram_access_data));
290 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmif_total_page_close_open_time: %d",
291 bw_fixed_to_int(data->dmif_total_page_close_open_time));
292 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] min_cursor_memory_interface_buffer_size_in_time: %d",
293 bw_fixed_to_int(data->min_cursor_memory_interface_buffer_size_in_time));
294 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] min_read_buffer_size_in_time: %d",
295 bw_fixed_to_int(data->min_read_buffer_size_in_time));
296 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] display_reads_time_for_data_transfer: %d",
297 bw_fixed_to_int(data->display_reads_time_for_data_transfer));
298 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] display_writes_time_for_data_transfer: %d",
299 bw_fixed_to_int(data->display_writes_time_for_data_transfer));
300 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmif_required_dram_bandwidth: %d",
301 bw_fixed_to_int(data->dmif_required_dram_bandwidth));
302 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mcifwr_required_dram_bandwidth: %d",
303 bw_fixed_to_int(data->mcifwr_required_dram_bandwidth));
304 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] required_dmifmc_urgent_latency_for_page_close_open: %d",
305 bw_fixed_to_int(data->required_dmifmc_urgent_latency_for_page_close_open));
306 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] required_mcifmcwr_urgent_latency: %d",
307 bw_fixed_to_int(data->required_mcifmcwr_urgent_latency));
308 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] required_dram_bandwidth_gbyte_per_second: %d",
309 bw_fixed_to_int(data->required_dram_bandwidth_gbyte_per_second));
310 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dram_bandwidth: %d", bw_fixed_to_int(data->dram_bandwidth));
311 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmif_required_sclk: %d", bw_fixed_to_int(data->dmif_required_sclk));
312 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mcifwr_required_sclk: %d", bw_fixed_to_int(data->mcifwr_required_sclk));
313 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] required_sclk: %d", bw_fixed_to_int(data->required_sclk));
314 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] downspread_factor: %d", bw_fixed_to_int(data->downspread_factor));
315 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] v_scaler_efficiency: %d", bw_fixed_to_int(data->v_scaler_efficiency));
316 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scaler_limits_factor: %d", bw_fixed_to_int(data->scaler_limits_factor));
317 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] display_pipe_pixel_throughput: %d",
318 bw_fixed_to_int(data->display_pipe_pixel_throughput));
319 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_dispclk_required_with_ramping: %d",
320 bw_fixed_to_int(data->total_dispclk_required_with_ramping));
321 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_dispclk_required_without_ramping: %d",
322 bw_fixed_to_int(data->total_dispclk_required_without_ramping));
323 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_read_request_bandwidth: %d",
324 bw_fixed_to_int(data->total_read_request_bandwidth));
325 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_write_request_bandwidth: %d",
326 bw_fixed_to_int(data->total_write_request_bandwidth));
327 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dispclk_required_for_total_read_request_bandwidth: %d",
328 bw_fixed_to_int(data->dispclk_required_for_total_read_request_bandwidth));
329 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_dispclk_required_with_ramping_with_request_bandwidth: %d",
330 bw_fixed_to_int(data->total_dispclk_required_with_ramping_with_request_bandwidth));
331 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_dispclk_required_without_ramping_with_request_bandwidth: %d",
332 bw_fixed_to_int(data->total_dispclk_required_without_ramping_with_request_bandwidth));
333 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dispclk: %d", bw_fixed_to_int(data->dispclk));
334 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] blackout_recovery_time: %d", bw_fixed_to_int(data->blackout_recovery_time));
335 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] min_pixels_per_data_fifo_entry: %d",
336 bw_fixed_to_int(data->min_pixels_per_data_fifo_entry));
337 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] sclk_deep_sleep: %d", bw_fixed_to_int(data->sclk_deep_sleep));
338 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] chunk_request_time: %d", bw_fixed_to_int(data->chunk_request_time));
339 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] cursor_request_time: %d", bw_fixed_to_int(data->cursor_request_time));
340 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] line_source_pixels_transfer_time: %d",
341 bw_fixed_to_int(data->line_source_pixels_transfer_time));
342 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmifdram_access_efficiency: %d",
343 bw_fixed_to_int(data->dmifdram_access_efficiency));
344 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mcifwrdram_access_efficiency: %d",
345 bw_fixed_to_int(data->mcifwrdram_access_efficiency));
346 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_average_bandwidth_no_compression: %d",
347 bw_fixed_to_int(data->total_average_bandwidth_no_compression));
348 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_average_bandwidth: %d",
349 bw_fixed_to_int(data->total_average_bandwidth));
350 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] total_stutter_cycle_duration: %d",
351 bw_fixed_to_int(data->total_stutter_cycle_duration));
352 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_burst_time: %d", bw_fixed_to_int(data->stutter_burst_time));
353 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] time_in_self_refresh: %d", bw_fixed_to_int(data->time_in_self_refresh));
354 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_efficiency: %d", bw_fixed_to_int(data->stutter_efficiency));
355 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] worst_number_of_trips_to_memory: %d",
356 bw_fixed_to_int(data->worst_number_of_trips_to_memory));
357 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] immediate_flip_time: %d", bw_fixed_to_int(data->immediate_flip_time));
358 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] latency_for_non_dmif_clients: %d",
359 bw_fixed_to_int(data->latency_for_non_dmif_clients));
360 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] latency_for_non_mcifwr_clients: %d",
361 bw_fixed_to_int(data->latency_for_non_mcifwr_clients));
362 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmifmc_urgent_latency_supported_in_high_sclk_and_yclk: %d",
363 bw_fixed_to_int(data->dmifmc_urgent_latency_supported_in_high_sclk_and_yclk));
364 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] nbp_state_dram_speed_change_margin: %d",
365 bw_fixed_to_int(data->nbp_state_dram_speed_change_margin));
366 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] display_reads_time_for_data_transfer_and_urgent_latency: %d",
367 bw_fixed_to_int(data->display_reads_time_for_data_transfer_and_urgent_latency));
368 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dram_speed_change_margin: %d",
369 bw_fixed_to_int(data->dram_speed_change_margin));
370 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] min_vblank_dram_speed_change_margin: %d",
371 bw_fixed_to_int(data->min_vblank_dram_speed_change_margin));
372 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] min_stutter_refresh_duration: %d",
373 bw_fixed_to_int(data->min_stutter_refresh_duration));
374 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] total_stutter_dmif_buffer_size: %d", data->total_stutter_dmif_buffer_size);
375 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] total_bytes_requested: %d", data->total_bytes_requested);
376 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] min_stutter_dmif_buffer_size: %d", data->min_stutter_dmif_buffer_size);
377 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] num_stutter_bursts: %d", data->num_stutter_bursts);
378 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] v_blank_nbp_state_dram_speed_change_latency_supported: %d",
379 bw_fixed_to_int(data->v_blank_nbp_state_dram_speed_change_latency_supported));
380 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] nbp_state_dram_speed_change_latency_supported: %d",
381 bw_fixed_to_int(data->nbp_state_dram_speed_change_latency_supported));
382
383 for (i = 0; i < maximum_number_of_surfaces; i++) {
384 DC_LOG_BANDWIDTH_CALCS(" [bool] fbc_en[%d]:%d\n", i, data->fbc_en[i]);
385 DC_LOG_BANDWIDTH_CALCS(" [bool] lpt_en[%d]:%d", i, data->lpt_en[i]);
386 DC_LOG_BANDWIDTH_CALCS(" [bool] displays_match_flag[%d]:%d", i, data->displays_match_flag[i]);
387 DC_LOG_BANDWIDTH_CALCS(" [bool] use_alpha[%d]:%d", i, data->use_alpha[i]);
388 DC_LOG_BANDWIDTH_CALCS(" [bool] orthogonal_rotation[%d]:%d", i, data->orthogonal_rotation[i]);
389 DC_LOG_BANDWIDTH_CALCS(" [bool] enable[%d]:%d", i, data->enable[i]);
390 DC_LOG_BANDWIDTH_CALCS(" [bool] access_one_channel_only[%d]:%d", i, data->access_one_channel_only[i]);
391 DC_LOG_BANDWIDTH_CALCS(" [bool] scatter_gather_enable_for_pipe[%d]:%d",
392 i, data->scatter_gather_enable_for_pipe[i]);
393 DC_LOG_BANDWIDTH_CALCS(" [bool] interlace_mode[%d]:%d",
394 i, data->interlace_mode[i]);
395 DC_LOG_BANDWIDTH_CALCS(" [bool] display_pstate_change_enable[%d]:%d",
396 i, data->display_pstate_change_enable[i]);
397 DC_LOG_BANDWIDTH_CALCS(" [bool] line_buffer_prefetch[%d]:%d", i, data->line_buffer_prefetch[i]);
398 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] bytes_per_pixel[%d]:%d", i, data->bytes_per_pixel[i]);
399 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] max_chunks_non_fbc_mode[%d]:%d",
400 i, data->max_chunks_non_fbc_mode[i]);
401 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] lb_bpc[%d]:%d", i, data->lb_bpc[i]);
402 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] output_bpphdmi[%d]:%d", i, data->output_bpphdmi[i]);
403 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] output_bppdp4_lane_hbr[%d]:%d", i, data->output_bppdp4_lane_hbr[i]);
404 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] output_bppdp4_lane_hbr2[%d]:%d",
405 i, data->output_bppdp4_lane_hbr2[i]);
406 DC_LOG_BANDWIDTH_CALCS(" [uint32_t] output_bppdp4_lane_hbr3[%d]:%d",
407 i, data->output_bppdp4_lane_hbr3[i]);
408 DC_LOG_BANDWIDTH_CALCS(" [enum] bw_defines stereo_mode[%d]:%d", i, data->stereo_mode[i]);
409 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmif_buffer_transfer_time[%d]:%d",
410 i, bw_fixed_to_int(data->dmif_buffer_transfer_time[i]));
411 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] displays_with_same_mode[%d]:%d",
412 i, bw_fixed_to_int(data->displays_with_same_mode[i]));
413 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_dmif_buffer_size[%d]:%d",
414 i, bw_fixed_to_int(data->stutter_dmif_buffer_size[i]));
415 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_refresh_duration[%d]:%d",
416 i, bw_fixed_to_int(data->stutter_refresh_duration[i]));
417 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_exit_watermark[%d]:%d",
418 i, bw_fixed_to_int(data->stutter_exit_watermark[i]));
419 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_entry_watermark[%d]:%d",
420 i, bw_fixed_to_int(data->stutter_entry_watermark[i]));
421 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] h_total[%d]:%d", i, bw_fixed_to_int(data->h_total[i]));
422 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] v_total[%d]:%d", i, bw_fixed_to_int(data->v_total[i]));
423 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] pixel_rate[%d]:%d", i, bw_fixed_to_int(data->pixel_rate[i]));
424 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_width[%d]:%d", i, bw_fixed_to_int(data->src_width[i]));
425 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] pitch_in_pixels[%d]:%d",
426 i, bw_fixed_to_int(data->pitch_in_pixels[i]));
427 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] pitch_in_pixels_after_surface_type[%d]:%d",
428 i, bw_fixed_to_int(data->pitch_in_pixels_after_surface_type[i]));
429 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_height[%d]:%d", i, bw_fixed_to_int(data->src_height[i]));
430 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scale_ratio[%d]:%d", i, bw_fixed_to_int(data->scale_ratio[i]));
431 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] h_taps[%d]:%d", i, bw_fixed_to_int(data->h_taps[i]));
432 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] v_taps[%d]:%d", i, bw_fixed_to_int(data->v_taps[i]));
433 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] h_scale_ratio[%d]:%d", i, bw_fixed_to_int(data->h_scale_ratio[i]));
434 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] v_scale_ratio[%d]:%d", i, bw_fixed_to_int(data->v_scale_ratio[i]));
435 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] rotation_angle[%d]:%d",
436 i, bw_fixed_to_int(data->rotation_angle[i]));
437 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] compression_rate[%d]:%d",
438 i, bw_fixed_to_int(data->compression_rate[i]));
439 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] hsr[%d]:%d", i, bw_fixed_to_int(data->hsr[i]));
440 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] vsr[%d]:%d", i, bw_fixed_to_int(data->vsr[i]));
441 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] source_width_rounded_up_to_chunks[%d]:%d",
442 i, bw_fixed_to_int(data->source_width_rounded_up_to_chunks[i]));
443 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] source_width_pixels[%d]:%d",
444 i, bw_fixed_to_int(data->source_width_pixels[i]));
445 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] source_height_rounded_up_to_chunks[%d]:%d",
446 i, bw_fixed_to_int(data->source_height_rounded_up_to_chunks[i]));
447 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] display_bandwidth[%d]:%d",
448 i, bw_fixed_to_int(data->display_bandwidth[i]));
449 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] request_bandwidth[%d]:%d",
450 i, bw_fixed_to_int(data->request_bandwidth[i]));
451 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] bytes_per_request[%d]:%d",
452 i, bw_fixed_to_int(data->bytes_per_request[i]));
453 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] useful_bytes_per_request[%d]:%d",
454 i, bw_fixed_to_int(data->useful_bytes_per_request[i]));
455 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] lines_interleaved_in_mem_access[%d]:%d",
456 i, bw_fixed_to_int(data->lines_interleaved_in_mem_access[i]));
457 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] latency_hiding_lines[%d]:%d",
458 i, bw_fixed_to_int(data->latency_hiding_lines[i]));
459 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] lb_partitions[%d]:%d",
460 i, bw_fixed_to_int(data->lb_partitions[i]));
461 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] lb_partitions_max[%d]:%d",
462 i, bw_fixed_to_int(data->lb_partitions_max[i]));
463 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dispclk_required_with_ramping[%d]:%d",
464 i, bw_fixed_to_int(data->dispclk_required_with_ramping[i]));
465 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dispclk_required_without_ramping[%d]:%d",
466 i, bw_fixed_to_int(data->dispclk_required_without_ramping[i]));
467 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] data_buffer_size[%d]:%d",
468 i, bw_fixed_to_int(data->data_buffer_size[i]));
469 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] outstanding_chunk_request_limit[%d]:%d",
470 i, bw_fixed_to_int(data->outstanding_chunk_request_limit[i]));
471 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] urgent_watermark[%d]:%d",
472 i, bw_fixed_to_int(data->urgent_watermark[i]));
473 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] nbp_state_change_watermark[%d]:%d",
474 i, bw_fixed_to_int(data->nbp_state_change_watermark[i]));
475 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] v_filter_init[%d]:%d", i, bw_fixed_to_int(data->v_filter_init[i]));
476 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] stutter_cycle_duration[%d]:%d",
477 i, bw_fixed_to_int(data->stutter_cycle_duration[i]));
478 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] average_bandwidth[%d]:%d",
479 i, bw_fixed_to_int(data->average_bandwidth[i]));
480 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] average_bandwidth_no_compression[%d]:%d",
481 i, bw_fixed_to_int(data->average_bandwidth_no_compression[i]));
482 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scatter_gather_pte_request_limit[%d]:%d",
483 i, bw_fixed_to_int(data->scatter_gather_pte_request_limit[i]));
484 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] lb_size_per_component[%d]:%d",
485 i, bw_fixed_to_int(data->lb_size_per_component[i]));
486 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] memory_chunk_size_in_bytes[%d]:%d",
487 i, bw_fixed_to_int(data->memory_chunk_size_in_bytes[i]));
488 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] pipe_chunk_size_in_bytes[%d]:%d",
489 i, bw_fixed_to_int(data->pipe_chunk_size_in_bytes[i]));
490 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] number_of_trips_to_memory_for_getting_apte_row[%d]:%d",
491 i, bw_fixed_to_int(data->number_of_trips_to_memory_for_getting_apte_row[i]));
492 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] adjusted_data_buffer_size[%d]:%d",
493 i, bw_fixed_to_int(data->adjusted_data_buffer_size[i]));
494 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] adjusted_data_buffer_size_in_memory[%d]:%d",
495 i, bw_fixed_to_int(data->adjusted_data_buffer_size_in_memory[i]));
496 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] pixels_per_data_fifo_entry[%d]:%d",
497 i, bw_fixed_to_int(data->pixels_per_data_fifo_entry[i]));
498 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scatter_gather_pte_requests_in_row[%d]:%d",
499 i, bw_fixed_to_int(data->scatter_gather_pte_requests_in_row[i]));
500 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] pte_request_per_chunk[%d]:%d",
501 i, bw_fixed_to_int(data->pte_request_per_chunk[i]));
502 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scatter_gather_page_width[%d]:%d",
503 i, bw_fixed_to_int(data->scatter_gather_page_width[i]));
504 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] scatter_gather_page_height[%d]:%d",
505 i, bw_fixed_to_int(data->scatter_gather_page_height[i]));
506 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] lb_lines_in_per_line_out_in_beginning_of_frame[%d]:%d",
507 i, bw_fixed_to_int(data->lb_lines_in_per_line_out_in_beginning_of_frame[i]));
508 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] lb_lines_in_per_line_out_in_middle_of_frame[%d]:%d",
509 i, bw_fixed_to_int(data->lb_lines_in_per_line_out_in_middle_of_frame[i]));
510 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] cursor_width_pixels[%d]:%d",
511 i, bw_fixed_to_int(data->cursor_width_pixels[i]));
512 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] minimum_latency_hiding[%d]:%d",
513 i, bw_fixed_to_int(data->minimum_latency_hiding[i]));
514 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] maximum_latency_hiding[%d]:%d",
515 i, bw_fixed_to_int(data->maximum_latency_hiding[i]));
516 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] minimum_latency_hiding_with_cursor[%d]:%d",
517 i, bw_fixed_to_int(data->minimum_latency_hiding_with_cursor[i]));
518 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] maximum_latency_hiding_with_cursor[%d]:%d",
519 i, bw_fixed_to_int(data->maximum_latency_hiding_with_cursor[i]));
520 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_pixels_for_first_output_pixel[%d]:%d",
521 i, bw_fixed_to_int(data->src_pixels_for_first_output_pixel[i]));
522 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_pixels_for_last_output_pixel[%d]:%d",
523 i, bw_fixed_to_int(data->src_pixels_for_last_output_pixel[i]));
524 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_data_for_first_output_pixel[%d]:%d",
525 i, bw_fixed_to_int(data->src_data_for_first_output_pixel[i]));
526 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] src_data_for_last_output_pixel[%d]:%d",
527 i, bw_fixed_to_int(data->src_data_for_last_output_pixel[i]));
528 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] active_time[%d]:%d", i, bw_fixed_to_int(data->active_time[i]));
529 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] horizontal_blank_and_chunk_granularity_factor[%d]:%d",
530 i, bw_fixed_to_int(data->horizontal_blank_and_chunk_granularity_factor[i]));
531 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] cursor_latency_hiding[%d]:%d",
532 i, bw_fixed_to_int(data->cursor_latency_hiding[i]));
533 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] v_blank_dram_speed_change_margin[%d]:%d",
534 i, bw_fixed_to_int(data->v_blank_dram_speed_change_margin[i]));
535 }
536
537 for (i = 0; i < maximum_number_of_surfaces; i++) {
538 for (j = 0; j < 3; j++) {
539 for (k = 0; k < 8; k++) {
540
541 DC_LOG_BANDWIDTH_CALCS("\n [bw_fixed] line_source_transfer_time[%d][%d][%d]:%d",
542 i, j, k, bw_fixed_to_int(data->line_source_transfer_time[i][j][k]));
543 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dram_speed_change_line_source_transfer_time[%d][%d][%d]:%d",
544 i, j, k,
545 bw_fixed_to_int(data->dram_speed_change_line_source_transfer_time[i][j][k]));
546 }
547 }
548 }
549
550 for (i = 0; i < 3; i++) {
551 for (j = 0; j < 8; j++) {
552
553 DC_LOG_BANDWIDTH_CALCS("\n [uint32_t] num_displays_with_margin[%d][%d]:%d",
554 i, j, data->num_displays_with_margin[i][j]);
555 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmif_burst_time[%d][%d]:%d",
556 i, j, bw_fixed_to_int(data->dmif_burst_time[i][j]));
557 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] mcifwr_burst_time[%d][%d]:%d",
558 i, j, bw_fixed_to_int(data->mcifwr_burst_time[i][j]));
559 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] min_dram_speed_change_margin[%d][%d]:%d",
560 i, j, bw_fixed_to_int(data->min_dram_speed_change_margin[i][j]));
561 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dispclk_required_for_dram_speed_change[%d][%d]:%d",
562 i, j, bw_fixed_to_int(data->dispclk_required_for_dram_speed_change[i][j]));
563 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] blackout_duration_margin[%d][%d]:%d",
564 i, j, bw_fixed_to_int(data->blackout_duration_margin[i][j]));
565 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dispclk_required_for_blackout_duration[%d][%d]:%d",
566 i, j, bw_fixed_to_int(data->dispclk_required_for_blackout_duration[i][j]));
567 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dispclk_required_for_blackout_recovery[%d][%d]:%d",
568 i, j, bw_fixed_to_int(data->dispclk_required_for_blackout_recovery[i][j]));
569 }
570 }
571
572 for (i = 0; i < 6; i++) {
573 DC_LOG_BANDWIDTH_CALCS(" [bw_fixed] dmif_required_sclk_for_urgent_latency[%d]:%d",
574 i, bw_fixed_to_int(data->dmif_required_sclk_for_urgent_latency[i]));
575 }
576}
577;
578
579#endif /* _CALCS_CALCS_LOGGER_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/custom_float.c b/drivers/gpu/drm/amd/display/dc/calcs/custom_float.c
index 7243c37f569e..31d167bc548f 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/custom_float.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/custom_float.c
@@ -36,41 +36,41 @@ static bool build_custom_float(
36 uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1; 36 uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1;
37 37
38 const struct fixed31_32 mantissa_constant_plus_max_fraction = 38 const struct fixed31_32 mantissa_constant_plus_max_fraction =
39 dal_fixed31_32_from_fraction( 39 dc_fixpt_from_fraction(
40 (1LL << (format->mantissa_bits + 1)) - 1, 40 (1LL << (format->mantissa_bits + 1)) - 1,
41 1LL << format->mantissa_bits); 41 1LL << format->mantissa_bits);
42 42
43 struct fixed31_32 mantiss; 43 struct fixed31_32 mantiss;
44 44
45 if (dal_fixed31_32_eq( 45 if (dc_fixpt_eq(
46 value, 46 value,
47 dal_fixed31_32_zero)) { 47 dc_fixpt_zero)) {
48 *negative = false; 48 *negative = false;
49 *mantissa = 0; 49 *mantissa = 0;
50 *exponenta = 0; 50 *exponenta = 0;
51 return true; 51 return true;
52 } 52 }
53 53
54 if (dal_fixed31_32_lt( 54 if (dc_fixpt_lt(
55 value, 55 value,
56 dal_fixed31_32_zero)) { 56 dc_fixpt_zero)) {
57 *negative = format->sign; 57 *negative = format->sign;
58 value = dal_fixed31_32_neg(value); 58 value = dc_fixpt_neg(value);
59 } else { 59 } else {
60 *negative = false; 60 *negative = false;
61 } 61 }
62 62
63 if (dal_fixed31_32_lt( 63 if (dc_fixpt_lt(
64 value, 64 value,
65 dal_fixed31_32_one)) { 65 dc_fixpt_one)) {
66 uint32_t i = 1; 66 uint32_t i = 1;
67 67
68 do { 68 do {
69 value = dal_fixed31_32_shl(value, 1); 69 value = dc_fixpt_shl(value, 1);
70 ++i; 70 ++i;
71 } while (dal_fixed31_32_lt( 71 } while (dc_fixpt_lt(
72 value, 72 value,
73 dal_fixed31_32_one)); 73 dc_fixpt_one));
74 74
75 --i; 75 --i;
76 76
@@ -81,15 +81,15 @@ static bool build_custom_float(
81 } 81 }
82 82
83 *exponenta = exp_offset - i; 83 *exponenta = exp_offset - i;
84 } else if (dal_fixed31_32_le( 84 } else if (dc_fixpt_le(
85 mantissa_constant_plus_max_fraction, 85 mantissa_constant_plus_max_fraction,
86 value)) { 86 value)) {
87 uint32_t i = 1; 87 uint32_t i = 1;
88 88
89 do { 89 do {
90 value = dal_fixed31_32_shr(value, 1); 90 value = dc_fixpt_shr(value, 1);
91 ++i; 91 ++i;
92 } while (dal_fixed31_32_lt( 92 } while (dc_fixpt_lt(
93 mantissa_constant_plus_max_fraction, 93 mantissa_constant_plus_max_fraction,
94 value)); 94 value));
95 95
@@ -98,23 +98,23 @@ static bool build_custom_float(
98 *exponenta = exp_offset; 98 *exponenta = exp_offset;
99 } 99 }
100 100
101 mantiss = dal_fixed31_32_sub( 101 mantiss = dc_fixpt_sub(
102 value, 102 value,
103 dal_fixed31_32_one); 103 dc_fixpt_one);
104 104
105 if (dal_fixed31_32_lt( 105 if (dc_fixpt_lt(
106 mantiss, 106 mantiss,
107 dal_fixed31_32_zero) || 107 dc_fixpt_zero) ||
108 dal_fixed31_32_lt( 108 dc_fixpt_lt(
109 dal_fixed31_32_one, 109 dc_fixpt_one,
110 mantiss)) 110 mantiss))
111 mantiss = dal_fixed31_32_zero; 111 mantiss = dc_fixpt_zero;
112 else 112 else
113 mantiss = dal_fixed31_32_shl( 113 mantiss = dc_fixpt_shl(
114 mantiss, 114 mantiss,
115 format->mantissa_bits); 115 format->mantissa_bits);
116 116
117 *mantissa = dal_fixed31_32_floor(mantiss); 117 *mantissa = dc_fixpt_floor(mantiss);
118 118
119 return true; 119 return true;
120} 120}
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
index 0cbab81ab304..2c4e8f0cb2dc 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
@@ -28,6 +28,7 @@
28#include "dc.h" 28#include "dc.h"
29#include "core_types.h" 29#include "core_types.h"
30#include "dal_asic_id.h" 30#include "dal_asic_id.h"
31#include "calcs_logger.h"
31 32
32/* 33/*
33 * NOTE: 34 * NOTE:
@@ -52,11 +53,14 @@ static enum bw_calcs_version bw_calcs_version_from_asic_id(struct hw_asic_id asi
52 return BW_CALCS_VERSION_CARRIZO; 53 return BW_CALCS_VERSION_CARRIZO;
53 54
54 case FAMILY_VI: 55 case FAMILY_VI:
56 if (ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev))
57 return BW_CALCS_VERSION_POLARIS12;
55 if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev)) 58 if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev))
56 return BW_CALCS_VERSION_POLARIS10; 59 return BW_CALCS_VERSION_POLARIS10;
57 if (ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev) || 60 if (ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev))
58 ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev))
59 return BW_CALCS_VERSION_POLARIS11; 61 return BW_CALCS_VERSION_POLARIS11;
62 if (ASIC_REV_IS_VEGAM(asic_id.hw_internal_rev))
63 return BW_CALCS_VERSION_VEGAM;
60 return BW_CALCS_VERSION_INVALID; 64 return BW_CALCS_VERSION_INVALID;
61 65
62 case FAMILY_AI: 66 case FAMILY_AI:
@@ -2145,6 +2149,9 @@ void bw_calcs_init(struct bw_calcs_dceip *bw_dceip,
2145 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); /* todo: this is a bug*/ 2149 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); /* todo: this is a bug*/
2146 break; 2150 break;
2147 case BW_CALCS_VERSION_POLARIS10: 2151 case BW_CALCS_VERSION_POLARIS10:
2152 /* TODO: Treat VEGAM the same as P10 for now
2153 * Need to tune the para for VEGAM if needed */
2154 case BW_CALCS_VERSION_VEGAM:
2148 vbios.memory_type = bw_def_gddr5; 2155 vbios.memory_type = bw_def_gddr5;
2149 vbios.dram_channel_width_in_bits = 32; 2156 vbios.dram_channel_width_in_bits = 32;
2150 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits; 2157 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
@@ -2373,6 +2380,122 @@ void bw_calcs_init(struct bw_calcs_dceip *bw_dceip,
2373 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2; 2380 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2374 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); 2381 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2375 break; 2382 break;
2383 case BW_CALCS_VERSION_POLARIS12:
2384 vbios.memory_type = bw_def_gddr5;
2385 vbios.dram_channel_width_in_bits = 32;
2386 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2387 vbios.number_of_dram_banks = 8;
2388 vbios.high_yclk = bw_int_to_fixed(6000);
2389 vbios.mid_yclk = bw_int_to_fixed(3200);
2390 vbios.low_yclk = bw_int_to_fixed(1000);
2391 vbios.low_sclk = bw_int_to_fixed(678);
2392 vbios.mid1_sclk = bw_int_to_fixed(864);
2393 vbios.mid2_sclk = bw_int_to_fixed(900);
2394 vbios.mid3_sclk = bw_int_to_fixed(920);
2395 vbios.mid4_sclk = bw_int_to_fixed(940);
2396 vbios.mid5_sclk = bw_int_to_fixed(960);
2397 vbios.mid6_sclk = bw_int_to_fixed(980);
2398 vbios.high_sclk = bw_int_to_fixed(1049);
2399 vbios.low_voltage_max_dispclk = bw_int_to_fixed(459);
2400 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654);
2401 vbios.high_voltage_max_dispclk = bw_int_to_fixed(1108);
2402 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2403 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2404 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2405 vbios.data_return_bus_width = bw_int_to_fixed(32);
2406 vbios.trc = bw_int_to_fixed(48);
2407 if (vbios.number_of_dram_channels == 2) // 64-bit
2408 vbios.dmifmc_urgent_latency = bw_int_to_fixed(4);
2409 else
2410 vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
2411 vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5);
2412 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2413 vbios.nbp_state_change_latency = bw_int_to_fixed(250);
2414 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2415 vbios.scatter_gather_enable = false;
2416 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2417 vbios.cursor_width = 32;
2418 vbios.average_compression_rate = 4;
2419 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2420 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2421 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2422
2423 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2424 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2425 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2426 dceip.large_cursor = false;
2427 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2428 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2429 dceip.cursor_max_outstanding_group_num = 1;
2430 dceip.lines_interleaved_into_lb = 2;
2431 dceip.chunk_width = 256;
2432 dceip.number_of_graphics_pipes = 5;
2433 dceip.number_of_underlay_pipes = 0;
2434 dceip.low_power_tiling_mode = 0;
2435 dceip.display_write_back_supported = true;
2436 dceip.argb_compression_support = true;
2437 dceip.underlay_vscaler_efficiency6_bit_per_component =
2438 bw_frc_to_fixed(35556, 10000);
2439 dceip.underlay_vscaler_efficiency8_bit_per_component =
2440 bw_frc_to_fixed(34286, 10000);
2441 dceip.underlay_vscaler_efficiency10_bit_per_component =
2442 bw_frc_to_fixed(32, 10);
2443 dceip.underlay_vscaler_efficiency12_bit_per_component =
2444 bw_int_to_fixed(3);
2445 dceip.graphics_vscaler_efficiency6_bit_per_component =
2446 bw_frc_to_fixed(35, 10);
2447 dceip.graphics_vscaler_efficiency8_bit_per_component =
2448 bw_frc_to_fixed(34286, 10000);
2449 dceip.graphics_vscaler_efficiency10_bit_per_component =
2450 bw_frc_to_fixed(32, 10);
2451 dceip.graphics_vscaler_efficiency12_bit_per_component =
2452 bw_int_to_fixed(3);
2453 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2454 dceip.max_dmif_buffer_allocated = 4;
2455 dceip.graphics_dmif_size = 12288;
2456 dceip.underlay_luma_dmif_size = 19456;
2457 dceip.underlay_chroma_dmif_size = 23552;
2458 dceip.pre_downscaler_enabled = true;
2459 dceip.underlay_downscale_prefetch_enabled = true;
2460 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2461 dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
2462 dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
2463 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2464 bw_int_to_fixed(1);
2465 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2466 82176);
2467 dceip.underlay420_chroma_lb_size_per_component =
2468 bw_int_to_fixed(164352);
2469 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2470 82176);
2471 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2472 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2473 dceip.underlay_maximum_width_efficient_for_tiling =
2474 bw_int_to_fixed(1920);
2475 dceip.underlay_maximum_height_efficient_for_tiling =
2476 bw_int_to_fixed(1080);
2477 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2478 bw_frc_to_fixed(3, 10);
2479 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2480 bw_int_to_fixed(25);
2481 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2482 2);
2483 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2484 bw_int_to_fixed(128);
2485 dceip.limit_excessive_outstanding_dmif_requests = true;
2486 dceip.linear_mode_line_request_alternation_slice =
2487 bw_int_to_fixed(64);
2488 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2489 32;
2490 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2491 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2492 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2493 dceip.dispclk_per_request = bw_int_to_fixed(2);
2494 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2495 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2496 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2497 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2498 break;
2376 case BW_CALCS_VERSION_STONEY: 2499 case BW_CALCS_VERSION_STONEY:
2377 vbios.memory_type = bw_def_gddr5; 2500 vbios.memory_type = bw_def_gddr5;
2378 vbios.dram_channel_width_in_bits = 64; 2501 vbios.dram_channel_width_in_bits = 64;
@@ -2815,6 +2938,19 @@ static void populate_initial_data(
2815 data->bytes_per_pixel[num_displays + 4] = 4; 2938 data->bytes_per_pixel[num_displays + 4] = 4;
2816 break; 2939 break;
2817 } 2940 }
2941 } else if (pipe[i].stream->dst.width != 0 &&
2942 pipe[i].stream->dst.height != 0 &&
2943 pipe[i].stream->src.width != 0 &&
2944 pipe[i].stream->src.height != 0) {
2945 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->src.width);
2946 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
2947 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->src.height);
2948 data->h_taps[num_displays + 4] = pipe[i].stream->src.width == pipe[i].stream->dst.width ? bw_int_to_fixed(1) : bw_int_to_fixed(2);
2949 data->v_taps[num_displays + 4] = pipe[i].stream->src.height == pipe[i].stream->dst.height ? bw_int_to_fixed(1) : bw_int_to_fixed(2);
2950 data->h_scale_ratio[num_displays + 4] = bw_frc_to_fixed(pipe[i].stream->src.width, pipe[i].stream->dst.width);
2951 data->v_scale_ratio[num_displays + 4] = bw_frc_to_fixed(pipe[i].stream->src.height, pipe[i].stream->dst.height);
2952 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(0);
2953 data->bytes_per_pixel[num_displays + 4] = 4;
2818 } else { 2954 } else {
2819 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_addressable); 2955 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_addressable);
2820 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4]; 2956 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
@@ -2873,6 +3009,11 @@ bool bw_calcs(struct dc_context *ctx,
2873 struct bw_fixed mid_yclk = vbios->mid_yclk; 3009 struct bw_fixed mid_yclk = vbios->mid_yclk;
2874 struct bw_fixed low_yclk = vbios->low_yclk; 3010 struct bw_fixed low_yclk = vbios->low_yclk;
2875 3011
3012 if (ctx->dc->debug.bandwidth_calcs_trace) {
3013 print_bw_calcs_dceip(ctx->logger, dceip);
3014 print_bw_calcs_vbios(ctx->logger, vbios);
3015 print_bw_calcs_data(ctx->logger, data);
3016 }
2876 calculate_bandwidth(dceip, vbios, data); 3017 calculate_bandwidth(dceip, vbios, data);
2877 3018
2878 yclk_lvl = data->y_clk_level; 3019 yclk_lvl = data->y_clk_level;
@@ -2968,7 +3109,33 @@ bool bw_calcs(struct dc_context *ctx,
2968 bw_fixed_to_int(bw_mul(data-> 3109 bw_fixed_to_int(bw_mul(data->
2969 stutter_exit_watermark[9], bw_int_to_fixed(1000))); 3110 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
2970 3111
2971 3112 calcs_output->stutter_entry_wm_ns[0].a_mark =
3113 bw_fixed_to_int(bw_mul(data->
3114 stutter_entry_watermark[4], bw_int_to_fixed(1000)));
3115 calcs_output->stutter_entry_wm_ns[1].a_mark =
3116 bw_fixed_to_int(bw_mul(data->
3117 stutter_entry_watermark[5], bw_int_to_fixed(1000)));
3118 calcs_output->stutter_entry_wm_ns[2].a_mark =
3119 bw_fixed_to_int(bw_mul(data->
3120 stutter_entry_watermark[6], bw_int_to_fixed(1000)));
3121 if (ctx->dc->caps.max_slave_planes) {
3122 calcs_output->stutter_entry_wm_ns[3].a_mark =
3123 bw_fixed_to_int(bw_mul(data->
3124 stutter_entry_watermark[0], bw_int_to_fixed(1000)));
3125 calcs_output->stutter_entry_wm_ns[4].a_mark =
3126 bw_fixed_to_int(bw_mul(data->
3127 stutter_entry_watermark[1], bw_int_to_fixed(1000)));
3128 } else {
3129 calcs_output->stutter_entry_wm_ns[3].a_mark =
3130 bw_fixed_to_int(bw_mul(data->
3131 stutter_entry_watermark[7], bw_int_to_fixed(1000)));
3132 calcs_output->stutter_entry_wm_ns[4].a_mark =
3133 bw_fixed_to_int(bw_mul(data->
3134 stutter_entry_watermark[8], bw_int_to_fixed(1000)));
3135 }
3136 calcs_output->stutter_entry_wm_ns[5].a_mark =
3137 bw_fixed_to_int(bw_mul(data->
3138 stutter_entry_watermark[9], bw_int_to_fixed(1000)));
2972 3139
2973 calcs_output->urgent_wm_ns[0].a_mark = 3140 calcs_output->urgent_wm_ns[0].a_mark =
2974 bw_fixed_to_int(bw_mul(data-> 3141 bw_fixed_to_int(bw_mul(data->
@@ -3063,7 +3230,33 @@ bool bw_calcs(struct dc_context *ctx,
3063 bw_fixed_to_int(bw_mul(data-> 3230 bw_fixed_to_int(bw_mul(data->
3064 stutter_exit_watermark[9], bw_int_to_fixed(1000))); 3231 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3065 3232
3066 3233 calcs_output->stutter_entry_wm_ns[0].b_mark =
3234 bw_fixed_to_int(bw_mul(data->
3235 stutter_entry_watermark[4], bw_int_to_fixed(1000)));
3236 calcs_output->stutter_entry_wm_ns[1].b_mark =
3237 bw_fixed_to_int(bw_mul(data->
3238 stutter_entry_watermark[5], bw_int_to_fixed(1000)));
3239 calcs_output->stutter_entry_wm_ns[2].b_mark =
3240 bw_fixed_to_int(bw_mul(data->
3241 stutter_entry_watermark[6], bw_int_to_fixed(1000)));
3242 if (ctx->dc->caps.max_slave_planes) {
3243 calcs_output->stutter_entry_wm_ns[3].b_mark =
3244 bw_fixed_to_int(bw_mul(data->
3245 stutter_entry_watermark[0], bw_int_to_fixed(1000)));
3246 calcs_output->stutter_entry_wm_ns[4].b_mark =
3247 bw_fixed_to_int(bw_mul(data->
3248 stutter_entry_watermark[1], bw_int_to_fixed(1000)));
3249 } else {
3250 calcs_output->stutter_entry_wm_ns[3].b_mark =
3251 bw_fixed_to_int(bw_mul(data->
3252 stutter_entry_watermark[7], bw_int_to_fixed(1000)));
3253 calcs_output->stutter_entry_wm_ns[4].b_mark =
3254 bw_fixed_to_int(bw_mul(data->
3255 stutter_entry_watermark[8], bw_int_to_fixed(1000)));
3256 }
3257 calcs_output->stutter_entry_wm_ns[5].b_mark =
3258 bw_fixed_to_int(bw_mul(data->
3259 stutter_entry_watermark[9], bw_int_to_fixed(1000)));
3067 3260
3068 calcs_output->urgent_wm_ns[0].b_mark = 3261 calcs_output->urgent_wm_ns[0].b_mark =
3069 bw_fixed_to_int(bw_mul(data-> 3262 bw_fixed_to_int(bw_mul(data->
@@ -3156,6 +3349,34 @@ bool bw_calcs(struct dc_context *ctx,
3156 bw_fixed_to_int(bw_mul(data-> 3349 bw_fixed_to_int(bw_mul(data->
3157 stutter_exit_watermark[9], bw_int_to_fixed(1000))); 3350 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3158 3351
3352 calcs_output->stutter_entry_wm_ns[0].c_mark =
3353 bw_fixed_to_int(bw_mul(data->
3354 stutter_entry_watermark[4], bw_int_to_fixed(1000)));
3355 calcs_output->stutter_entry_wm_ns[1].c_mark =
3356 bw_fixed_to_int(bw_mul(data->
3357 stutter_entry_watermark[5], bw_int_to_fixed(1000)));
3358 calcs_output->stutter_entry_wm_ns[2].c_mark =
3359 bw_fixed_to_int(bw_mul(data->
3360 stutter_entry_watermark[6], bw_int_to_fixed(1000)));
3361 if (ctx->dc->caps.max_slave_planes) {
3362 calcs_output->stutter_entry_wm_ns[3].c_mark =
3363 bw_fixed_to_int(bw_mul(data->
3364 stutter_entry_watermark[0], bw_int_to_fixed(1000)));
3365 calcs_output->stutter_entry_wm_ns[4].c_mark =
3366 bw_fixed_to_int(bw_mul(data->
3367 stutter_entry_watermark[1], bw_int_to_fixed(1000)));
3368 } else {
3369 calcs_output->stutter_entry_wm_ns[3].c_mark =
3370 bw_fixed_to_int(bw_mul(data->
3371 stutter_entry_watermark[7], bw_int_to_fixed(1000)));
3372 calcs_output->stutter_entry_wm_ns[4].c_mark =
3373 bw_fixed_to_int(bw_mul(data->
3374 stutter_entry_watermark[8], bw_int_to_fixed(1000)));
3375 }
3376 calcs_output->stutter_entry_wm_ns[5].c_mark =
3377 bw_fixed_to_int(bw_mul(data->
3378 stutter_entry_watermark[9], bw_int_to_fixed(1000)));
3379
3159 calcs_output->urgent_wm_ns[0].c_mark = 3380 calcs_output->urgent_wm_ns[0].c_mark =
3160 bw_fixed_to_int(bw_mul(data-> 3381 bw_fixed_to_int(bw_mul(data->
3161 urgent_watermark[4], bw_int_to_fixed(1000))); 3382 urgent_watermark[4], bw_int_to_fixed(1000)));
@@ -3260,6 +3481,33 @@ bool bw_calcs(struct dc_context *ctx,
3260 bw_fixed_to_int(bw_mul(data-> 3481 bw_fixed_to_int(bw_mul(data->
3261 stutter_exit_watermark[9], bw_int_to_fixed(1000))); 3482 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3262 3483
3484 calcs_output->stutter_entry_wm_ns[0].d_mark =
3485 bw_fixed_to_int(bw_mul(data->
3486 stutter_entry_watermark[4], bw_int_to_fixed(1000)));
3487 calcs_output->stutter_entry_wm_ns[1].d_mark =
3488 bw_fixed_to_int(bw_mul(data->
3489 stutter_entry_watermark[5], bw_int_to_fixed(1000)));
3490 calcs_output->stutter_entry_wm_ns[2].d_mark =
3491 bw_fixed_to_int(bw_mul(data->
3492 stutter_entry_watermark[6], bw_int_to_fixed(1000)));
3493 if (ctx->dc->caps.max_slave_planes) {
3494 calcs_output->stutter_entry_wm_ns[3].d_mark =
3495 bw_fixed_to_int(bw_mul(data->
3496 stutter_entry_watermark[0], bw_int_to_fixed(1000)));
3497 calcs_output->stutter_entry_wm_ns[4].d_mark =
3498 bw_fixed_to_int(bw_mul(data->
3499 stutter_entry_watermark[1], bw_int_to_fixed(1000)));
3500 } else {
3501 calcs_output->stutter_entry_wm_ns[3].d_mark =
3502 bw_fixed_to_int(bw_mul(data->
3503 stutter_entry_watermark[7], bw_int_to_fixed(1000)));
3504 calcs_output->stutter_entry_wm_ns[4].d_mark =
3505 bw_fixed_to_int(bw_mul(data->
3506 stutter_entry_watermark[8], bw_int_to_fixed(1000)));
3507 }
3508 calcs_output->stutter_entry_wm_ns[5].d_mark =
3509 bw_fixed_to_int(bw_mul(data->
3510 stutter_entry_watermark[9], bw_int_to_fixed(1000)));
3263 3511
3264 calcs_output->urgent_wm_ns[0].d_mark = 3512 calcs_output->urgent_wm_ns[0].d_mark =
3265 bw_fixed_to_int(bw_mul(data-> 3513 bw_fixed_to_int(bw_mul(data->
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
index 4bb43a371292..49a4ea45466d 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
@@ -873,14 +873,14 @@ bool dcn_validate_bandwidth(
873 } 873 }
874 874
875 if (pipe->plane_state->rotation % 2 == 0) { 875 if (pipe->plane_state->rotation % 2 == 0) {
876 ASSERT(pipe->plane_res.scl_data.ratios.horz.value != dal_fixed31_32_one.value 876 ASSERT(pipe->plane_res.scl_data.ratios.horz.value != dc_fixpt_one.value
877 || v->scaler_rec_out_width[input_idx] == v->viewport_width[input_idx]); 877 || v->scaler_rec_out_width[input_idx] == v->viewport_width[input_idx]);
878 ASSERT(pipe->plane_res.scl_data.ratios.vert.value != dal_fixed31_32_one.value 878 ASSERT(pipe->plane_res.scl_data.ratios.vert.value != dc_fixpt_one.value
879 || v->scaler_recout_height[input_idx] == v->viewport_height[input_idx]); 879 || v->scaler_recout_height[input_idx] == v->viewport_height[input_idx]);
880 } else { 880 } else {
881 ASSERT(pipe->plane_res.scl_data.ratios.horz.value != dal_fixed31_32_one.value 881 ASSERT(pipe->plane_res.scl_data.ratios.horz.value != dc_fixpt_one.value
882 || v->scaler_recout_height[input_idx] == v->viewport_width[input_idx]); 882 || v->scaler_recout_height[input_idx] == v->viewport_width[input_idx]);
883 ASSERT(pipe->plane_res.scl_data.ratios.vert.value != dal_fixed31_32_one.value 883 ASSERT(pipe->plane_res.scl_data.ratios.vert.value != dc_fixpt_one.value
884 || v->scaler_rec_out_width[input_idx] == v->viewport_height[input_idx]); 884 || v->scaler_rec_out_width[input_idx] == v->viewport_height[input_idx]);
885 } 885 }
886 v->dcc_enable[input_idx] = pipe->plane_state->dcc.enable ? dcn_bw_yes : dcn_bw_no; 886 v->dcc_enable[input_idx] = pipe->plane_state->dcc.enable ? dcn_bw_yes : dcn_bw_no;
@@ -1459,39 +1459,39 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
1459void dcn_bw_sync_calcs_and_dml(struct dc *dc) 1459void dcn_bw_sync_calcs_and_dml(struct dc *dc)
1460{ 1460{
1461 kernel_fpu_begin(); 1461 kernel_fpu_begin();
1462 DC_LOG_BANDWIDTH_CALCS("sr_exit_time: %d ns\n" 1462 DC_LOG_BANDWIDTH_CALCS("sr_exit_time: %f ns\n"
1463 "sr_enter_plus_exit_time: %d ns\n" 1463 "sr_enter_plus_exit_time: %f ns\n"
1464 "urgent_latency: %d ns\n" 1464 "urgent_latency: %f ns\n"
1465 "write_back_latency: %d ns\n" 1465 "write_back_latency: %f ns\n"
1466 "percent_of_ideal_drambw_received_after_urg_latency: %d %\n" 1466 "percent_of_ideal_drambw_received_after_urg_latency: %f %%\n"
1467 "max_request_size: %d bytes\n" 1467 "max_request_size: %d bytes\n"
1468 "dcfclkv_max0p9: %d kHz\n" 1468 "dcfclkv_max0p9: %f kHz\n"
1469 "dcfclkv_nom0p8: %d kHz\n" 1469 "dcfclkv_nom0p8: %f kHz\n"
1470 "dcfclkv_mid0p72: %d kHz\n" 1470 "dcfclkv_mid0p72: %f kHz\n"
1471 "dcfclkv_min0p65: %d kHz\n" 1471 "dcfclkv_min0p65: %f kHz\n"
1472 "max_dispclk_vmax0p9: %d kHz\n" 1472 "max_dispclk_vmax0p9: %f kHz\n"
1473 "max_dispclk_vnom0p8: %d kHz\n" 1473 "max_dispclk_vnom0p8: %f kHz\n"
1474 "max_dispclk_vmid0p72: %d kHz\n" 1474 "max_dispclk_vmid0p72: %f kHz\n"
1475 "max_dispclk_vmin0p65: %d kHz\n" 1475 "max_dispclk_vmin0p65: %f kHz\n"
1476 "max_dppclk_vmax0p9: %d kHz\n" 1476 "max_dppclk_vmax0p9: %f kHz\n"
1477 "max_dppclk_vnom0p8: %d kHz\n" 1477 "max_dppclk_vnom0p8: %f kHz\n"
1478 "max_dppclk_vmid0p72: %d kHz\n" 1478 "max_dppclk_vmid0p72: %f kHz\n"
1479 "max_dppclk_vmin0p65: %d kHz\n" 1479 "max_dppclk_vmin0p65: %f kHz\n"
1480 "socclk: %d kHz\n" 1480 "socclk: %f kHz\n"
1481 "fabric_and_dram_bandwidth_vmax0p9: %d MB/s\n" 1481 "fabric_and_dram_bandwidth_vmax0p9: %f MB/s\n"
1482 "fabric_and_dram_bandwidth_vnom0p8: %d MB/s\n" 1482 "fabric_and_dram_bandwidth_vnom0p8: %f MB/s\n"
1483 "fabric_and_dram_bandwidth_vmid0p72: %d MB/s\n" 1483 "fabric_and_dram_bandwidth_vmid0p72: %f MB/s\n"
1484 "fabric_and_dram_bandwidth_vmin0p65: %d MB/s\n" 1484 "fabric_and_dram_bandwidth_vmin0p65: %f MB/s\n"
1485 "phyclkv_max0p9: %d kHz\n" 1485 "phyclkv_max0p9: %f kHz\n"
1486 "phyclkv_nom0p8: %d kHz\n" 1486 "phyclkv_nom0p8: %f kHz\n"
1487 "phyclkv_mid0p72: %d kHz\n" 1487 "phyclkv_mid0p72: %f kHz\n"
1488 "phyclkv_min0p65: %d kHz\n" 1488 "phyclkv_min0p65: %f kHz\n"
1489 "downspreading: %d %\n" 1489 "downspreading: %f %%\n"
1490 "round_trip_ping_latency_cycles: %d DCFCLK Cycles\n" 1490 "round_trip_ping_latency_cycles: %d DCFCLK Cycles\n"
1491 "urgent_out_of_order_return_per_channel: %d Bytes\n" 1491 "urgent_out_of_order_return_per_channel: %d Bytes\n"
1492 "number_of_channels: %d\n" 1492 "number_of_channels: %d\n"
1493 "vmm_page_size: %d Bytes\n" 1493 "vmm_page_size: %d Bytes\n"
1494 "dram_clock_change_latency: %d ns\n" 1494 "dram_clock_change_latency: %f ns\n"
1495 "return_bus_width: %d Bytes\n", 1495 "return_bus_width: %d Bytes\n",
1496 dc->dcn_soc->sr_exit_time * 1000, 1496 dc->dcn_soc->sr_exit_time * 1000,
1497 dc->dcn_soc->sr_enter_plus_exit_time * 1000, 1497 dc->dcn_soc->sr_enter_plus_exit_time * 1000,
@@ -1527,11 +1527,11 @@ void dcn_bw_sync_calcs_and_dml(struct dc *dc)
1527 dc->dcn_soc->vmm_page_size, 1527 dc->dcn_soc->vmm_page_size,
1528 dc->dcn_soc->dram_clock_change_latency * 1000, 1528 dc->dcn_soc->dram_clock_change_latency * 1000,
1529 dc->dcn_soc->return_bus_width); 1529 dc->dcn_soc->return_bus_width);
1530 DC_LOG_BANDWIDTH_CALCS("rob_buffer_size_in_kbyte: %d\n" 1530 DC_LOG_BANDWIDTH_CALCS("rob_buffer_size_in_kbyte: %f\n"
1531 "det_buffer_size_in_kbyte: %d\n" 1531 "det_buffer_size_in_kbyte: %f\n"
1532 "dpp_output_buffer_pixels: %d\n" 1532 "dpp_output_buffer_pixels: %f\n"
1533 "opp_output_buffer_lines: %d\n" 1533 "opp_output_buffer_lines: %f\n"
1534 "pixel_chunk_size_in_kbyte: %d\n" 1534 "pixel_chunk_size_in_kbyte: %f\n"
1535 "pte_enable: %d\n" 1535 "pte_enable: %d\n"
1536 "pte_chunk_size: %d kbytes\n" 1536 "pte_chunk_size: %d kbytes\n"
1537 "meta_chunk_size: %d kbytes\n" 1537 "meta_chunk_size: %d kbytes\n"
@@ -1550,13 +1550,13 @@ void dcn_bw_sync_calcs_and_dml(struct dc *dc)
1550 "max_pscl_tolb_throughput: %d pixels/dppclk\n" 1550 "max_pscl_tolb_throughput: %d pixels/dppclk\n"
1551 "max_lb_tovscl_throughput: %d pixels/dppclk\n" 1551 "max_lb_tovscl_throughput: %d pixels/dppclk\n"
1552 "max_vscl_tohscl_throughput: %d pixels/dppclk\n" 1552 "max_vscl_tohscl_throughput: %d pixels/dppclk\n"
1553 "max_hscl_ratio: %d\n" 1553 "max_hscl_ratio: %f\n"
1554 "max_vscl_ratio: %d\n" 1554 "max_vscl_ratio: %f\n"
1555 "max_hscl_taps: %d\n" 1555 "max_hscl_taps: %d\n"
1556 "max_vscl_taps: %d\n" 1556 "max_vscl_taps: %d\n"
1557 "pte_buffer_size_in_requests: %d\n" 1557 "pte_buffer_size_in_requests: %d\n"
1558 "dispclk_ramping_margin: %d %\n" 1558 "dispclk_ramping_margin: %f %%\n"
1559 "under_scan_factor: %d %\n" 1559 "under_scan_factor: %f %%\n"
1560 "max_inter_dcn_tile_repeaters: %d\n" 1560 "max_inter_dcn_tile_repeaters: %d\n"
1561 "can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one: %d\n" 1561 "can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one: %d\n"
1562 "bug_forcing_luma_and_chroma_request_to_same_size_fixed: %d\n" 1562 "bug_forcing_luma_and_chroma_request_to_same_size_fixed: %d\n"
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 9cd3566def8d..644b2187507b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -936,95 +936,6 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
936 return true; 936 return true;
937} 937}
938 938
939/*
940 * TODO this whole function needs to go
941 *
942 * dc_surface_update is needlessly complex. See if we can just replace this
943 * with a dc_plane_state and follow the atomic model a bit more closely here.
944 */
945bool dc_commit_planes_to_stream(
946 struct dc *dc,
947 struct dc_plane_state **plane_states,
948 uint8_t new_plane_count,
949 struct dc_stream_state *dc_stream,
950 struct dc_state *state)
951{
952 /* no need to dynamically allocate this. it's pretty small */
953 struct dc_surface_update updates[MAX_SURFACES];
954 struct dc_flip_addrs *flip_addr;
955 struct dc_plane_info *plane_info;
956 struct dc_scaling_info *scaling_info;
957 int i;
958 struct dc_stream_update *stream_update =
959 kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL);
960
961 if (!stream_update) {
962 BREAK_TO_DEBUGGER();
963 return false;
964 }
965
966 flip_addr = kcalloc(MAX_SURFACES, sizeof(struct dc_flip_addrs),
967 GFP_KERNEL);
968 plane_info = kcalloc(MAX_SURFACES, sizeof(struct dc_plane_info),
969 GFP_KERNEL);
970 scaling_info = kcalloc(MAX_SURFACES, sizeof(struct dc_scaling_info),
971 GFP_KERNEL);
972
973 if (!flip_addr || !plane_info || !scaling_info) {
974 kfree(flip_addr);
975 kfree(plane_info);
976 kfree(scaling_info);
977 kfree(stream_update);
978 return false;
979 }
980
981 memset(updates, 0, sizeof(updates));
982
983 stream_update->src = dc_stream->src;
984 stream_update->dst = dc_stream->dst;
985 stream_update->out_transfer_func = dc_stream->out_transfer_func;
986
987 for (i = 0; i < new_plane_count; i++) {
988 updates[i].surface = plane_states[i];
989 updates[i].gamma =
990 (struct dc_gamma *)plane_states[i]->gamma_correction;
991 updates[i].in_transfer_func = plane_states[i]->in_transfer_func;
992 flip_addr[i].address = plane_states[i]->address;
993 flip_addr[i].flip_immediate = plane_states[i]->flip_immediate;
994 plane_info[i].color_space = plane_states[i]->color_space;
995 plane_info[i].input_tf = plane_states[i]->input_tf;
996 plane_info[i].format = plane_states[i]->format;
997 plane_info[i].plane_size = plane_states[i]->plane_size;
998 plane_info[i].rotation = plane_states[i]->rotation;
999 plane_info[i].horizontal_mirror = plane_states[i]->horizontal_mirror;
1000 plane_info[i].stereo_format = plane_states[i]->stereo_format;
1001 plane_info[i].tiling_info = plane_states[i]->tiling_info;
1002 plane_info[i].visible = plane_states[i]->visible;
1003 plane_info[i].per_pixel_alpha = plane_states[i]->per_pixel_alpha;
1004 plane_info[i].dcc = plane_states[i]->dcc;
1005 scaling_info[i].scaling_quality = plane_states[i]->scaling_quality;
1006 scaling_info[i].src_rect = plane_states[i]->src_rect;
1007 scaling_info[i].dst_rect = plane_states[i]->dst_rect;
1008 scaling_info[i].clip_rect = plane_states[i]->clip_rect;
1009
1010 updates[i].flip_addr = &flip_addr[i];
1011 updates[i].plane_info = &plane_info[i];
1012 updates[i].scaling_info = &scaling_info[i];
1013 }
1014
1015 dc_commit_updates_for_stream(
1016 dc,
1017 updates,
1018 new_plane_count,
1019 dc_stream, stream_update, plane_states, state);
1020
1021 kfree(flip_addr);
1022 kfree(plane_info);
1023 kfree(scaling_info);
1024 kfree(stream_update);
1025 return true;
1026}
1027
1028struct dc_state *dc_create_state(void) 939struct dc_state *dc_create_state(void)
1029{ 940{
1030 struct dc_state *context = kzalloc(sizeof(struct dc_state), 941 struct dc_state *context = kzalloc(sizeof(struct dc_state),
@@ -1107,9 +1018,6 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
1107 if (u->plane_info->color_space != u->surface->color_space) 1018 if (u->plane_info->color_space != u->surface->color_space)
1108 update_flags->bits.color_space_change = 1; 1019 update_flags->bits.color_space_change = 1;
1109 1020
1110 if (u->plane_info->input_tf != u->surface->input_tf)
1111 update_flags->bits.input_tf_change = 1;
1112
1113 if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror) 1021 if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror)
1114 update_flags->bits.horizontal_mirror_change = 1; 1022 update_flags->bits.horizontal_mirror_change = 1;
1115 1023
@@ -1243,12 +1151,20 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
1243 if (u->input_csc_color_matrix) 1151 if (u->input_csc_color_matrix)
1244 update_flags->bits.input_csc_change = 1; 1152 update_flags->bits.input_csc_change = 1;
1245 1153
1246 if (update_flags->bits.in_transfer_func_change 1154 if (u->coeff_reduction_factor)
1247 || update_flags->bits.input_csc_change) { 1155 update_flags->bits.coeff_reduction_change = 1;
1156
1157 if (update_flags->bits.in_transfer_func_change) {
1248 type = UPDATE_TYPE_MED; 1158 type = UPDATE_TYPE_MED;
1249 elevate_update_type(&overall_type, type); 1159 elevate_update_type(&overall_type, type);
1250 } 1160 }
1251 1161
1162 if (update_flags->bits.input_csc_change
1163 || update_flags->bits.coeff_reduction_change) {
1164 type = UPDATE_TYPE_FULL;
1165 elevate_update_type(&overall_type, type);
1166 }
1167
1252 return overall_type; 1168 return overall_type;
1253} 1169}
1254 1170
@@ -1297,7 +1213,7 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
1297 type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status); 1213 type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status);
1298 if (type == UPDATE_TYPE_FULL) 1214 if (type == UPDATE_TYPE_FULL)
1299 for (i = 0; i < surface_count; i++) 1215 for (i = 0; i < surface_count; i++)
1300 updates[i].surface->update_flags.bits.full_update = 1; 1216 updates[i].surface->update_flags.raw = 0xFFFFFFFF;
1301 1217
1302 return type; 1218 return type;
1303} 1219}
@@ -1375,6 +1291,12 @@ static void commit_planes_for_stream(struct dc *dc,
1375 pipe_ctx->stream_res.abm->funcs->set_abm_level( 1291 pipe_ctx->stream_res.abm->funcs->set_abm_level(
1376 pipe_ctx->stream_res.abm, stream->abm_level); 1292 pipe_ctx->stream_res.abm, stream->abm_level);
1377 } 1293 }
1294
1295 if (stream_update && stream_update->periodic_fn_vsync_delta &&
1296 pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
1297 pipe_ctx->stream_res.tg->funcs->program_vline_interrupt(
1298 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing,
1299 pipe_ctx->stream->periodic_fn_vsync_delta);
1378 } 1300 }
1379 } 1301 }
1380 1302
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
index 5a552cb3f8a7..267c76766dea 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
@@ -36,8 +36,9 @@
36#include "hw_sequencer.h" 36#include "hw_sequencer.h"
37 37
38#include "resource.h" 38#include "resource.h"
39#define DC_LOGGER \ 39
40 logger 40#define DC_LOGGER_INIT(logger)
41
41 42
42#define SURFACE_TRACE(...) do {\ 43#define SURFACE_TRACE(...) do {\
43 if (dc->debug.surface_trace) \ 44 if (dc->debug.surface_trace) \
@@ -60,8 +61,7 @@ void pre_surface_trace(
60 int surface_count) 61 int surface_count)
61{ 62{
62 int i; 63 int i;
63 struct dc *core_dc = dc; 64 DC_LOGGER_INIT(dc->ctx->logger);
64 struct dal_logger *logger = core_dc->ctx->logger;
65 65
66 for (i = 0; i < surface_count; i++) { 66 for (i = 0; i < surface_count; i++) {
67 const struct dc_plane_state *plane_state = plane_states[i]; 67 const struct dc_plane_state *plane_state = plane_states[i];
@@ -72,8 +72,8 @@ void pre_surface_trace(
72 "plane_state->visible = %d;\n" 72 "plane_state->visible = %d;\n"
73 "plane_state->flip_immediate = %d;\n" 73 "plane_state->flip_immediate = %d;\n"
74 "plane_state->address.type = %d;\n" 74 "plane_state->address.type = %d;\n"
75 "plane_state->address.grph.addr.quad_part = 0x%X;\n" 75 "plane_state->address.grph.addr.quad_part = 0x%llX;\n"
76 "plane_state->address.grph.meta_addr.quad_part = 0x%X;\n" 76 "plane_state->address.grph.meta_addr.quad_part = 0x%llX;\n"
77 "plane_state->scaling_quality.h_taps = %d;\n" 77 "plane_state->scaling_quality.h_taps = %d;\n"
78 "plane_state->scaling_quality.v_taps = %d;\n" 78 "plane_state->scaling_quality.v_taps = %d;\n"
79 "plane_state->scaling_quality.h_taps_c = %d;\n" 79 "plane_state->scaling_quality.h_taps_c = %d;\n"
@@ -155,7 +155,6 @@ void pre_surface_trace(
155 "plane_state->tiling_info.gfx8.pipe_config = %d;\n" 155 "plane_state->tiling_info.gfx8.pipe_config = %d;\n"
156 "plane_state->tiling_info.gfx8.array_mode = %d;\n" 156 "plane_state->tiling_info.gfx8.array_mode = %d;\n"
157 "plane_state->color_space = %d;\n" 157 "plane_state->color_space = %d;\n"
158 "plane_state->input_tf = %d;\n"
159 "plane_state->dcc.enable = %d;\n" 158 "plane_state->dcc.enable = %d;\n"
160 "plane_state->format = %d;\n" 159 "plane_state->format = %d;\n"
161 "plane_state->rotation = %d;\n" 160 "plane_state->rotation = %d;\n"
@@ -163,7 +162,6 @@ void pre_surface_trace(
163 plane_state->tiling_info.gfx8.pipe_config, 162 plane_state->tiling_info.gfx8.pipe_config,
164 plane_state->tiling_info.gfx8.array_mode, 163 plane_state->tiling_info.gfx8.array_mode,
165 plane_state->color_space, 164 plane_state->color_space,
166 plane_state->input_tf,
167 plane_state->dcc.enable, 165 plane_state->dcc.enable,
168 plane_state->format, 166 plane_state->format,
169 plane_state->rotation, 167 plane_state->rotation,
@@ -183,8 +181,7 @@ void update_surface_trace(
183 int surface_count) 181 int surface_count)
184{ 182{
185 int i; 183 int i;
186 struct dc *core_dc = dc; 184 DC_LOGGER_INIT(dc->ctx->logger);
187 struct dal_logger *logger = core_dc->ctx->logger;
188 185
189 for (i = 0; i < surface_count; i++) { 186 for (i = 0; i < surface_count; i++) {
190 const struct dc_surface_update *update = &updates[i]; 187 const struct dc_surface_update *update = &updates[i];
@@ -192,8 +189,8 @@ void update_surface_trace(
192 SURFACE_TRACE("Update %d\n", i); 189 SURFACE_TRACE("Update %d\n", i);
193 if (update->flip_addr) { 190 if (update->flip_addr) {
194 SURFACE_TRACE("flip_addr->address.type = %d;\n" 191 SURFACE_TRACE("flip_addr->address.type = %d;\n"
195 "flip_addr->address.grph.addr.quad_part = 0x%X;\n" 192 "flip_addr->address.grph.addr.quad_part = 0x%llX;\n"
196 "flip_addr->address.grph.meta_addr.quad_part = 0x%X;\n" 193 "flip_addr->address.grph.meta_addr.quad_part = 0x%llX;\n"
197 "flip_addr->flip_immediate = %d;\n", 194 "flip_addr->flip_immediate = %d;\n",
198 update->flip_addr->address.type, 195 update->flip_addr->address.type,
199 update->flip_addr->address.grph.addr.quad_part, 196 update->flip_addr->address.grph.addr.quad_part,
@@ -204,16 +201,15 @@ void update_surface_trace(
204 if (update->plane_info) { 201 if (update->plane_info) {
205 SURFACE_TRACE( 202 SURFACE_TRACE(
206 "plane_info->color_space = %d;\n" 203 "plane_info->color_space = %d;\n"
207 "plane_info->input_tf = %d;\n"
208 "plane_info->format = %d;\n" 204 "plane_info->format = %d;\n"
209 "plane_info->plane_size.grph.surface_pitch = %d;\n" 205 "plane_info->plane_size.grph.surface_pitch = %d;\n"
210 "plane_info->plane_size.grph.surface_size.height = %d;\n" 206 "plane_info->plane_size.grph.surface_size.height = %d;\n"
211 "plane_info->plane_size.grph.surface_size.width = %d;\n" 207 "plane_info->plane_size.grph.surface_size.width = %d;\n"
212 "plane_info->plane_size.grph.surface_size.x = %d;\n" 208 "plane_info->plane_size.grph.surface_size.x = %d;\n"
213 "plane_info->plane_size.grph.surface_size.y = %d;\n" 209 "plane_info->plane_size.grph.surface_size.y = %d;\n"
214 "plane_info->rotation = %d;\n", 210 "plane_info->rotation = %d;\n"
211 "plane_info->stereo_format = %d;\n",
215 update->plane_info->color_space, 212 update->plane_info->color_space,
216 update->plane_info->input_tf,
217 update->plane_info->format, 213 update->plane_info->format,
218 update->plane_info->plane_size.grph.surface_pitch, 214 update->plane_info->plane_size.grph.surface_pitch,
219 update->plane_info->plane_size.grph.surface_size.height, 215 update->plane_info->plane_size.grph.surface_size.height,
@@ -303,8 +299,7 @@ void update_surface_trace(
303 299
304void post_surface_trace(struct dc *dc) 300void post_surface_trace(struct dc *dc)
305{ 301{
306 struct dc *core_dc = dc; 302 DC_LOGGER_INIT(dc->ctx->logger);
307 struct dal_logger *logger = core_dc->ctx->logger;
308 303
309 SURFACE_TRACE("post surface process.\n"); 304 SURFACE_TRACE("post surface process.\n");
310 305
@@ -316,10 +311,10 @@ void context_timing_trace(
316{ 311{
317 int i; 312 int i;
318 struct dc *core_dc = dc; 313 struct dc *core_dc = dc;
319 struct dal_logger *logger = core_dc->ctx->logger;
320 int h_pos[MAX_PIPES], v_pos[MAX_PIPES]; 314 int h_pos[MAX_PIPES], v_pos[MAX_PIPES];
321 struct crtc_position position; 315 struct crtc_position position;
322 unsigned int underlay_idx = core_dc->res_pool->underlay_pipe_index; 316 unsigned int underlay_idx = core_dc->res_pool->underlay_pipe_index;
317 DC_LOGGER_INIT(dc->ctx->logger);
323 318
324 319
325 for (i = 0; i < core_dc->res_pool->pipe_count; i++) { 320 for (i = 0; i < core_dc->res_pool->pipe_count; i++) {
@@ -354,9 +349,7 @@ void context_clock_trace(
354 struct dc_state *context) 349 struct dc_state *context)
355{ 350{
356#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 351#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
357 struct dc *core_dc = dc; 352 DC_LOGGER_INIT(dc->ctx->logger);
358 struct dal_logger *logger = core_dc->ctx->logger;
359
360 CLOCK_TRACE("Current: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n" 353 CLOCK_TRACE("Current: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n"
361 "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n", 354 "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n",
362 context->bw.dcn.calc_clk.dispclk_khz, 355 context->bw.dcn.calc_clk.dispclk_khz,
@@ -371,6 +364,7 @@ void context_clock_trace(
371 context->bw.dcn.calc_clk.dppclk_khz, 364 context->bw.dcn.calc_clk.dppclk_khz,
372 context->bw.dcn.calc_clk.dcfclk_khz, 365 context->bw.dcn.calc_clk.dcfclk_khz,
373 context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz, 366 context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz,
374 context->bw.dcn.calc_clk.fclk_khz); 367 context->bw.dcn.calc_clk.fclk_khz,
368 context->bw.dcn.calc_clk.socclk_khz);
375#endif 369#endif
376} 370}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index ebc96b720083..83d121510ef5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -208,6 +208,7 @@ void color_space_to_black_color(
208 case COLOR_SPACE_YCBCR709: 208 case COLOR_SPACE_YCBCR709:
209 case COLOR_SPACE_YCBCR601_LIMITED: 209 case COLOR_SPACE_YCBCR601_LIMITED:
210 case COLOR_SPACE_YCBCR709_LIMITED: 210 case COLOR_SPACE_YCBCR709_LIMITED:
211 case COLOR_SPACE_2020_YCBCR:
211 *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV]; 212 *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV];
212 break; 213 break;
213 214
@@ -216,7 +217,25 @@ void color_space_to_black_color(
216 black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED]; 217 black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED];
217 break; 218 break;
218 219
219 default: 220 /**
221 * Remove default and add case for all color space
222 * so when we forget to add new color space
223 * compiler will give a warning
224 */
225 case COLOR_SPACE_UNKNOWN:
226 case COLOR_SPACE_SRGB:
227 case COLOR_SPACE_XR_RGB:
228 case COLOR_SPACE_MSREF_SCRGB:
229 case COLOR_SPACE_XV_YCC_709:
230 case COLOR_SPACE_XV_YCC_601:
231 case COLOR_SPACE_2020_RGB_FULLRANGE:
232 case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
233 case COLOR_SPACE_ADOBERGB:
234 case COLOR_SPACE_DCIP3:
235 case COLOR_SPACE_DISPLAYNATIVE:
236 case COLOR_SPACE_DOLBYVISION:
237 case COLOR_SPACE_APPCTRL:
238 case COLOR_SPACE_CUSTOMPOINTS:
220 /* fefault is sRGB black (full range). */ 239 /* fefault is sRGB black (full range). */
221 *black_color = 240 *black_color =
222 black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE]; 241 black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE];
@@ -230,6 +249,9 @@ bool hwss_wait_for_blank_complete(
230{ 249{
231 int counter; 250 int counter;
232 251
252 /* Not applicable if the pipe is not primary, save 300ms of boot time */
253 if (!tg->funcs->is_blanked)
254 return true;
233 for (counter = 0; counter < 100; counter++) { 255 for (counter = 0; counter < 100; counter++) {
234 if (tg->funcs->is_blanked(tg)) 256 if (tg->funcs->is_blanked(tg))
235 break; 257 break;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 6d1c4981a185..2fa521812d23 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -45,8 +45,9 @@
45#include "dce/dce_11_0_d.h" 45#include "dce/dce_11_0_d.h"
46#include "dce/dce_11_0_enum.h" 46#include "dce/dce_11_0_enum.h"
47#include "dce/dce_11_0_sh_mask.h" 47#include "dce/dce_11_0_sh_mask.h"
48#define DC_LOGGER \ 48
49 dc_ctx->logger 49#define DC_LOGGER_INIT(logger)
50
50 51
51#define LINK_INFO(...) \ 52#define LINK_INFO(...) \
52 DC_LOG_HW_HOTPLUG( \ 53 DC_LOG_HW_HOTPLUG( \
@@ -468,6 +469,13 @@ static void link_disconnect_sink(struct dc_link *link)
468 link->dpcd_sink_count = 0; 469 link->dpcd_sink_count = 0;
469} 470}
470 471
472static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *link)
473{
474 dc_sink_release(link->local_sink);
475 link->local_sink = prev_sink;
476}
477
478
471static bool detect_dp( 479static bool detect_dp(
472 struct dc_link *link, 480 struct dc_link *link,
473 struct display_sink_capability *sink_caps, 481 struct display_sink_capability *sink_caps,
@@ -550,6 +558,17 @@ static bool detect_dp(
550 return true; 558 return true;
551} 559}
552 560
561static bool is_same_edid(struct dc_edid *old_edid, struct dc_edid *new_edid)
562{
563 if (old_edid->length != new_edid->length)
564 return false;
565
566 if (new_edid->length == 0)
567 return false;
568
569 return (memcmp(old_edid->raw_edid, new_edid->raw_edid, new_edid->length) == 0);
570}
571
553bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) 572bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
554{ 573{
555 struct dc_sink_init_data sink_init_data = { 0 }; 574 struct dc_sink_init_data sink_init_data = { 0 };
@@ -557,11 +576,15 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
557 uint8_t i; 576 uint8_t i;
558 bool converter_disable_audio = false; 577 bool converter_disable_audio = false;
559 struct audio_support *aud_support = &link->dc->res_pool->audio_support; 578 struct audio_support *aud_support = &link->dc->res_pool->audio_support;
579 bool same_edid = false;
560 enum dc_edid_status edid_status; 580 enum dc_edid_status edid_status;
561 struct dc_context *dc_ctx = link->ctx; 581 struct dc_context *dc_ctx = link->ctx;
562 struct dc_sink *sink = NULL; 582 struct dc_sink *sink = NULL;
583 struct dc_sink *prev_sink = NULL;
584 struct dpcd_caps prev_dpcd_caps;
585 bool same_dpcd = true;
563 enum dc_connection_type new_connection_type = dc_connection_none; 586 enum dc_connection_type new_connection_type = dc_connection_none;
564 587 DC_LOGGER_INIT(link->ctx->logger);
565 if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) 588 if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
566 return false; 589 return false;
567 590
@@ -574,6 +597,11 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
574 link->local_sink) 597 link->local_sink)
575 return true; 598 return true;
576 599
600 prev_sink = link->local_sink;
601 if (prev_sink != NULL) {
602 dc_sink_retain(prev_sink);
603 memcpy(&prev_dpcd_caps, &link->dpcd_caps, sizeof(struct dpcd_caps));
604 }
577 link_disconnect_sink(link); 605 link_disconnect_sink(link);
578 606
579 if (new_connection_type != dc_connection_none) { 607 if (new_connection_type != dc_connection_none) {
@@ -615,14 +643,25 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
615 link, 643 link,
616 &sink_caps, 644 &sink_caps,
617 &converter_disable_audio, 645 &converter_disable_audio,
618 aud_support, reason)) 646 aud_support, reason)) {
647 if (prev_sink != NULL)
648 dc_sink_release(prev_sink);
619 return false; 649 return false;
650 }
620 651
652 // Check if dpcp block is the same
653 if (prev_sink != NULL) {
654 if (memcmp(&link->dpcd_caps, &prev_dpcd_caps, sizeof(struct dpcd_caps)))
655 same_dpcd = false;
656 }
621 /* Active dongle downstream unplug */ 657 /* Active dongle downstream unplug */
622 if (link->type == dc_connection_active_dongle 658 if (link->type == dc_connection_active_dongle
623 && link->dpcd_caps.sink_count. 659 && link->dpcd_caps.sink_count.
624 bits.SINK_COUNT == 0) 660 bits.SINK_COUNT == 0) {
661 if (prev_sink != NULL)
662 dc_sink_release(prev_sink);
625 return true; 663 return true;
664 }
626 665
627 if (link->type == dc_connection_mst_branch) { 666 if (link->type == dc_connection_mst_branch) {
628 LINK_INFO("link=%d, mst branch is now Connected\n", 667 LINK_INFO("link=%d, mst branch is now Connected\n",
@@ -630,9 +669,11 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
630 /* Need to setup mst link_cap struct here 669 /* Need to setup mst link_cap struct here
631 * otherwise dc_link_detect() will leave mst link_cap 670 * otherwise dc_link_detect() will leave mst link_cap
632 * empty which leads to allocate_mst_payload() has "0" 671 * empty which leads to allocate_mst_payload() has "0"
633 * pbn_per_slot value leading to exception on dal_fixed31_32_div() 672 * pbn_per_slot value leading to exception on dc_fixpt_div()
634 */ 673 */
635 link->verified_link_cap = link->reported_link_cap; 674 link->verified_link_cap = link->reported_link_cap;
675 if (prev_sink != NULL)
676 dc_sink_release(prev_sink);
636 return false; 677 return false;
637 } 678 }
638 679
@@ -642,6 +683,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
642 default: 683 default:
643 DC_ERROR("Invalid connector type! signal:%d\n", 684 DC_ERROR("Invalid connector type! signal:%d\n",
644 link->connector_signal); 685 link->connector_signal);
686 if (prev_sink != NULL)
687 dc_sink_release(prev_sink);
645 return false; 688 return false;
646 } /* switch() */ 689 } /* switch() */
647 690
@@ -664,6 +707,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
664 sink = dc_sink_create(&sink_init_data); 707 sink = dc_sink_create(&sink_init_data);
665 if (!sink) { 708 if (!sink) {
666 DC_ERROR("Failed to create sink!\n"); 709 DC_ERROR("Failed to create sink!\n");
710 if (prev_sink != NULL)
711 dc_sink_release(prev_sink);
667 return false; 712 return false;
668 } 713 }
669 714
@@ -687,22 +732,33 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
687 break; 732 break;
688 } 733 }
689 734
690 if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT && 735 // Check if edid is the same
691 sink_caps.transaction_type == 736 if ((prev_sink != NULL) && ((edid_status == EDID_THE_SAME) || (edid_status == EDID_OK)))
692 DDC_TRANSACTION_TYPE_I2C_OVER_AUX) { 737 same_edid = is_same_edid(&prev_sink->dc_edid, &sink->dc_edid);
693 /*
694 * TODO debug why Dell 2413 doesn't like
695 * two link trainings
696 */
697 738
698 /* deal with non-mst cases */ 739 // If both edid and dpcd are the same, then discard new sink and revert back to original sink
699 dp_hbr_verify_link_cap(link, &link->reported_link_cap); 740 if ((same_edid) && (same_dpcd)) {
700 } 741 link_disconnect_remap(prev_sink, link);
742 sink = prev_sink;
743 prev_sink = NULL;
744 } else {
745 if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
746 sink_caps.transaction_type ==
747 DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
748 /*
749 * TODO debug why Dell 2413 doesn't like
750 * two link trainings
751 */
701 752
702 /* HDMI-DVI Dongle */ 753 /* deal with non-mst cases */
703 if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A && 754 dp_hbr_verify_link_cap(link, &link->reported_link_cap);
704 !sink->edid_caps.edid_hdmi) 755 }
705 sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK; 756
757 /* HDMI-DVI Dongle */
758 if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
759 !sink->edid_caps.edid_hdmi)
760 sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
761 }
706 762
707 /* Connectivity log: detection */ 763 /* Connectivity log: detection */
708 for (i = 0; i < sink->dc_edid.length / EDID_BLOCK_SIZE; i++) { 764 for (i = 0; i < sink->dc_edid.length / EDID_BLOCK_SIZE; i++) {
@@ -761,10 +817,14 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
761 sink_caps.signal = SIGNAL_TYPE_NONE; 817 sink_caps.signal = SIGNAL_TYPE_NONE;
762 } 818 }
763 819
764 LINK_INFO("link=%d, dc_sink_in=%p is now %s\n", 820 LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p dpcd same=%d edid same=%d\n",
765 link->link_index, sink, 821 link->link_index, sink,
766 (sink_caps.signal == SIGNAL_TYPE_NONE ? 822 (sink_caps.signal == SIGNAL_TYPE_NONE ?
767 "Disconnected":"Connected")); 823 "Disconnected":"Connected"), prev_sink,
824 same_dpcd, same_edid);
825
826 if (prev_sink != NULL)
827 dc_sink_release(prev_sink);
768 828
769 return true; 829 return true;
770} 830}
@@ -927,6 +987,7 @@ static bool construct(
927 struct integrated_info info = {{{ 0 }}}; 987 struct integrated_info info = {{{ 0 }}};
928 struct dc_bios *bios = init_params->dc->ctx->dc_bios; 988 struct dc_bios *bios = init_params->dc->ctx->dc_bios;
929 const struct dc_vbios_funcs *bp_funcs = bios->funcs; 989 const struct dc_vbios_funcs *bp_funcs = bios->funcs;
990 DC_LOGGER_INIT(dc_ctx->logger);
930 991
931 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; 992 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
932 link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID; 993 link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
@@ -1135,7 +1196,8 @@ static void dpcd_configure_panel_mode(
1135{ 1196{
1136 union dpcd_edp_config edp_config_set; 1197 union dpcd_edp_config edp_config_set;
1137 bool panel_mode_edp = false; 1198 bool panel_mode_edp = false;
1138 struct dc_context *dc_ctx = link->ctx; 1199 DC_LOGGER_INIT(link->ctx->logger);
1200
1139 memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config)); 1201 memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
1140 1202
1141 if (DP_PANEL_MODE_DEFAULT != panel_mode) { 1203 if (DP_PANEL_MODE_DEFAULT != panel_mode) {
@@ -1183,16 +1245,21 @@ static void enable_stream_features(struct pipe_ctx *pipe_ctx)
1183{ 1245{
1184 struct dc_stream_state *stream = pipe_ctx->stream; 1246 struct dc_stream_state *stream = pipe_ctx->stream;
1185 struct dc_link *link = stream->sink->link; 1247 struct dc_link *link = stream->sink->link;
1186 union down_spread_ctrl downspread; 1248 union down_spread_ctrl old_downspread;
1249 union down_spread_ctrl new_downspread;
1187 1250
1188 core_link_read_dpcd(link, DP_DOWNSPREAD_CTRL, 1251 core_link_read_dpcd(link, DP_DOWNSPREAD_CTRL,
1189 &downspread.raw, sizeof(downspread)); 1252 &old_downspread.raw, sizeof(old_downspread));
1190 1253
1191 downspread.bits.IGNORE_MSA_TIMING_PARAM = 1254 new_downspread.raw = old_downspread.raw;
1255
1256 new_downspread.bits.IGNORE_MSA_TIMING_PARAM =
1192 (stream->ignore_msa_timing_param) ? 1 : 0; 1257 (stream->ignore_msa_timing_param) ? 1 : 0;
1193 1258
1194 core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL, 1259 if (new_downspread.raw != old_downspread.raw) {
1195 &downspread.raw, sizeof(downspread)); 1260 core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
1261 &new_downspread.raw, sizeof(new_downspread));
1262 }
1196} 1263}
1197 1264
1198static enum dc_status enable_link_dp( 1265static enum dc_status enable_link_dp(
@@ -1843,9 +1910,22 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
1843 1910
1844static bool dp_active_dongle_validate_timing( 1911static bool dp_active_dongle_validate_timing(
1845 const struct dc_crtc_timing *timing, 1912 const struct dc_crtc_timing *timing,
1846 const struct dc_dongle_caps *dongle_caps) 1913 const struct dpcd_caps *dpcd_caps)
1847{ 1914{
1848 unsigned int required_pix_clk = timing->pix_clk_khz; 1915 unsigned int required_pix_clk = timing->pix_clk_khz;
1916 const struct dc_dongle_caps *dongle_caps = &dpcd_caps->dongle_caps;
1917
1918 switch (dpcd_caps->dongle_type) {
1919 case DISPLAY_DONGLE_DP_VGA_CONVERTER:
1920 case DISPLAY_DONGLE_DP_DVI_CONVERTER:
1921 case DISPLAY_DONGLE_DP_DVI_DONGLE:
1922 if (timing->pixel_encoding == PIXEL_ENCODING_RGB)
1923 return true;
1924 else
1925 return false;
1926 default:
1927 break;
1928 }
1849 1929
1850 if (dongle_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER || 1930 if (dongle_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER ||
1851 dongle_caps->extendedCapValid == false) 1931 dongle_caps->extendedCapValid == false)
@@ -1911,7 +1991,7 @@ enum dc_status dc_link_validate_mode_timing(
1911 const struct dc_crtc_timing *timing) 1991 const struct dc_crtc_timing *timing)
1912{ 1992{
1913 uint32_t max_pix_clk = stream->sink->dongle_max_pix_clk; 1993 uint32_t max_pix_clk = stream->sink->dongle_max_pix_clk;
1914 struct dc_dongle_caps *dongle_caps = &link->dpcd_caps.dongle_caps; 1994 struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
1915 1995
1916 /* A hack to avoid failing any modes for EDID override feature on 1996 /* A hack to avoid failing any modes for EDID override feature on
1917 * topology change such as lower quality cable for DP or different dongle 1997 * topology change such as lower quality cable for DP or different dongle
@@ -1924,7 +2004,7 @@ enum dc_status dc_link_validate_mode_timing(
1924 return DC_EXCEED_DONGLE_CAP; 2004 return DC_EXCEED_DONGLE_CAP;
1925 2005
1926 /* Active Dongle*/ 2006 /* Active Dongle*/
1927 if (!dp_active_dongle_validate_timing(timing, dongle_caps)) 2007 if (!dp_active_dongle_validate_timing(timing, dpcd_caps))
1928 return DC_EXCEED_DONGLE_CAP; 2008 return DC_EXCEED_DONGLE_CAP;
1929 2009
1930 switch (stream->signal) { 2010 switch (stream->signal) {
@@ -1950,10 +2030,10 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
1950 struct dc *core_dc = link->ctx->dc; 2030 struct dc *core_dc = link->ctx->dc;
1951 struct abm *abm = core_dc->res_pool->abm; 2031 struct abm *abm = core_dc->res_pool->abm;
1952 struct dmcu *dmcu = core_dc->res_pool->dmcu; 2032 struct dmcu *dmcu = core_dc->res_pool->dmcu;
1953 struct dc_context *dc_ctx = link->ctx;
1954 unsigned int controller_id = 0; 2033 unsigned int controller_id = 0;
1955 bool use_smooth_brightness = true; 2034 bool use_smooth_brightness = true;
1956 int i; 2035 int i;
2036 DC_LOGGER_INIT(link->ctx->logger);
1957 2037
1958 if ((dmcu == NULL) || 2038 if ((dmcu == NULL) ||
1959 (abm == NULL) || 2039 (abm == NULL) ||
@@ -1961,7 +2041,7 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
1961 return false; 2041 return false;
1962 2042
1963 if (stream) { 2043 if (stream) {
1964 if (stream->bl_pwm_level == 0) 2044 if (stream->bl_pwm_level == EDP_BACKLIGHT_RAMP_DISABLE_LEVEL)
1965 frame_ramp = 0; 2045 frame_ramp = 0;
1966 2046
1967 ((struct dc_stream_state *)stream)->bl_pwm_level = level; 2047 ((struct dc_stream_state *)stream)->bl_pwm_level = level;
@@ -2038,10 +2118,10 @@ static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream)
2038 &stream->sink->link->cur_link_settings; 2118 &stream->sink->link->cur_link_settings;
2039 uint32_t link_rate_in_mbps = 2119 uint32_t link_rate_in_mbps =
2040 link_settings->link_rate * LINK_RATE_REF_FREQ_IN_MHZ; 2120 link_settings->link_rate * LINK_RATE_REF_FREQ_IN_MHZ;
2041 struct fixed31_32 mbps = dal_fixed31_32_from_int( 2121 struct fixed31_32 mbps = dc_fixpt_from_int(
2042 link_rate_in_mbps * link_settings->lane_count); 2122 link_rate_in_mbps * link_settings->lane_count);
2043 2123
2044 return dal_fixed31_32_div_int(mbps, 54); 2124 return dc_fixpt_div_int(mbps, 54);
2045} 2125}
2046 2126
2047static int get_color_depth(enum dc_color_depth color_depth) 2127static int get_color_depth(enum dc_color_depth color_depth)
@@ -2082,7 +2162,7 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
2082 numerator = 64 * PEAK_FACTOR_X1000; 2162 numerator = 64 * PEAK_FACTOR_X1000;
2083 denominator = 54 * 8 * 1000 * 1000; 2163 denominator = 54 * 8 * 1000 * 1000;
2084 kbps *= numerator; 2164 kbps *= numerator;
2085 peak_kbps = dal_fixed31_32_from_fraction(kbps, denominator); 2165 peak_kbps = dc_fixpt_from_fraction(kbps, denominator);
2086 2166
2087 return peak_kbps; 2167 return peak_kbps;
2088} 2168}
@@ -2149,8 +2229,8 @@ static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx)
2149 struct fixed31_32 avg_time_slots_per_mtp; 2229 struct fixed31_32 avg_time_slots_per_mtp;
2150 struct fixed31_32 pbn; 2230 struct fixed31_32 pbn;
2151 struct fixed31_32 pbn_per_slot; 2231 struct fixed31_32 pbn_per_slot;
2152 struct dc_context *dc_ctx = link->ctx;
2153 uint8_t i; 2232 uint8_t i;
2233 DC_LOGGER_INIT(link->ctx->logger);
2154 2234
2155 /* enable_link_dp_mst already check link->enabled_stream_count 2235 /* enable_link_dp_mst already check link->enabled_stream_count
2156 * and stream is in link->stream[]. This is called during set mode, 2236 * and stream is in link->stream[]. This is called during set mode,
@@ -2178,11 +2258,11 @@ static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx)
2178 link->mst_stream_alloc_table.stream_count); 2258 link->mst_stream_alloc_table.stream_count);
2179 2259
2180 for (i = 0; i < MAX_CONTROLLER_NUM; i++) { 2260 for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
2181 DC_LOG_MST("stream_enc[%d]: 0x%x " 2261 DC_LOG_MST("stream_enc[%d]: %p "
2182 "stream[%d].vcp_id: %d " 2262 "stream[%d].vcp_id: %d "
2183 "stream[%d].slot_count: %d\n", 2263 "stream[%d].slot_count: %d\n",
2184 i, 2264 i,
2185 link->mst_stream_alloc_table.stream_allocations[i].stream_enc, 2265 (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
2186 i, 2266 i,
2187 link->mst_stream_alloc_table.stream_allocations[i].vcp_id, 2267 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
2188 i, 2268 i,
@@ -2209,7 +2289,7 @@ static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx)
2209 /* slot X.Y for only current stream */ 2289 /* slot X.Y for only current stream */
2210 pbn_per_slot = get_pbn_per_slot(stream); 2290 pbn_per_slot = get_pbn_per_slot(stream);
2211 pbn = get_pbn_from_timing(pipe_ctx); 2291 pbn = get_pbn_from_timing(pipe_ctx);
2212 avg_time_slots_per_mtp = dal_fixed31_32_div(pbn, pbn_per_slot); 2292 avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
2213 2293
2214 stream_encoder->funcs->set_mst_bandwidth( 2294 stream_encoder->funcs->set_mst_bandwidth(
2215 stream_encoder, 2295 stream_encoder,
@@ -2226,10 +2306,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
2226 struct link_encoder *link_encoder = link->link_enc; 2306 struct link_encoder *link_encoder = link->link_enc;
2227 struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc; 2307 struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
2228 struct dp_mst_stream_allocation_table proposed_table = {0}; 2308 struct dp_mst_stream_allocation_table proposed_table = {0};
2229 struct fixed31_32 avg_time_slots_per_mtp = dal_fixed31_32_from_int(0); 2309 struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
2230 uint8_t i; 2310 uint8_t i;
2231 bool mst_mode = (link->type == dc_connection_mst_branch); 2311 bool mst_mode = (link->type == dc_connection_mst_branch);
2232 struct dc_context *dc_ctx = link->ctx; 2312 DC_LOGGER_INIT(link->ctx->logger);
2233 2313
2234 /* deallocate_mst_payload is called before disable link. When mode or 2314 /* deallocate_mst_payload is called before disable link. When mode or
2235 * disable/enable monitor, new stream is created which is not in link 2315 * disable/enable monitor, new stream is created which is not in link
@@ -2268,11 +2348,11 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
2268 link->mst_stream_alloc_table.stream_count); 2348 link->mst_stream_alloc_table.stream_count);
2269 2349
2270 for (i = 0; i < MAX_CONTROLLER_NUM; i++) { 2350 for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
2271 DC_LOG_MST("stream_enc[%d]: 0x%x " 2351 DC_LOG_MST("stream_enc[%d]: %p "
2272 "stream[%d].vcp_id: %d " 2352 "stream[%d].vcp_id: %d "
2273 "stream[%d].slot_count: %d\n", 2353 "stream[%d].slot_count: %d\n",
2274 i, 2354 i,
2275 link->mst_stream_alloc_table.stream_allocations[i].stream_enc, 2355 (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
2276 i, 2356 i,
2277 link->mst_stream_alloc_table.stream_allocations[i].vcp_id, 2357 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
2278 i, 2358 i,
@@ -2302,8 +2382,8 @@ void core_link_enable_stream(
2302 struct pipe_ctx *pipe_ctx) 2382 struct pipe_ctx *pipe_ctx)
2303{ 2383{
2304 struct dc *core_dc = pipe_ctx->stream->ctx->dc; 2384 struct dc *core_dc = pipe_ctx->stream->ctx->dc;
2305 struct dc_context *dc_ctx = pipe_ctx->stream->ctx;
2306 enum dc_status status; 2385 enum dc_status status;
2386 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
2307 2387
2308 /* eDP lit up by bios already, no need to enable again. */ 2388 /* eDP lit up by bios already, no need to enable again. */
2309 if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP && 2389 if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 3b5053570229..7d609c71394b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1378,8 +1378,8 @@ static uint32_t bandwidth_in_kbps_from_timing(
1378{ 1378{
1379 uint32_t bits_per_channel = 0; 1379 uint32_t bits_per_channel = 0;
1380 uint32_t kbps; 1380 uint32_t kbps;
1381 switch (timing->display_color_depth) {
1382 1381
1382 switch (timing->display_color_depth) {
1383 case COLOR_DEPTH_666: 1383 case COLOR_DEPTH_666:
1384 bits_per_channel = 6; 1384 bits_per_channel = 6;
1385 break; 1385 break;
@@ -1401,14 +1401,20 @@ static uint32_t bandwidth_in_kbps_from_timing(
1401 default: 1401 default:
1402 break; 1402 break;
1403 } 1403 }
1404
1404 ASSERT(bits_per_channel != 0); 1405 ASSERT(bits_per_channel != 0);
1405 1406
1406 kbps = timing->pix_clk_khz; 1407 kbps = timing->pix_clk_khz;
1407 kbps *= bits_per_channel; 1408 kbps *= bits_per_channel;
1408 1409
1409 if (timing->flags.Y_ONLY != 1) 1410 if (timing->flags.Y_ONLY != 1) {
1410 /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/ 1411 /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
1411 kbps *= 3; 1412 kbps *= 3;
1413 if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
1414 kbps /= 2;
1415 else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
1416 kbps = kbps * 2 / 3;
1417 }
1412 1418
1413 return kbps; 1419 return kbps;
1414 1420
@@ -2278,6 +2284,8 @@ static bool retrieve_link_cap(struct dc_link *link)
2278 union edp_configuration_cap edp_config_cap; 2284 union edp_configuration_cap edp_config_cap;
2279 union dp_downstream_port_present ds_port = { 0 }; 2285 union dp_downstream_port_present ds_port = { 0 };
2280 enum dc_status status = DC_ERROR_UNEXPECTED; 2286 enum dc_status status = DC_ERROR_UNEXPECTED;
2287 uint32_t read_dpcd_retry_cnt = 3;
2288 int i;
2281 2289
2282 memset(dpcd_data, '\0', sizeof(dpcd_data)); 2290 memset(dpcd_data, '\0', sizeof(dpcd_data));
2283 memset(&down_strm_port_count, 2291 memset(&down_strm_port_count,
@@ -2285,11 +2293,15 @@ static bool retrieve_link_cap(struct dc_link *link)
2285 memset(&edp_config_cap, '\0', 2293 memset(&edp_config_cap, '\0',
2286 sizeof(union edp_configuration_cap)); 2294 sizeof(union edp_configuration_cap));
2287 2295
2288 status = core_link_read_dpcd( 2296 for (i = 0; i < read_dpcd_retry_cnt; i++) {
2289 link, 2297 status = core_link_read_dpcd(
2290 DP_DPCD_REV, 2298 link,
2291 dpcd_data, 2299 DP_DPCD_REV,
2292 sizeof(dpcd_data)); 2300 dpcd_data,
2301 sizeof(dpcd_data));
2302 if (status == DC_OK)
2303 break;
2304 }
2293 2305
2294 if (status != DC_OK) { 2306 if (status != DC_OK) {
2295 dm_error("%s: Read dpcd data failed.\n", __func__); 2307 dm_error("%s: Read dpcd data failed.\n", __func__);
@@ -2376,6 +2388,10 @@ bool detect_dp_sink_caps(struct dc_link *link)
2376void detect_edp_sink_caps(struct dc_link *link) 2388void detect_edp_sink_caps(struct dc_link *link)
2377{ 2389{
2378 retrieve_link_cap(link); 2390 retrieve_link_cap(link);
2391
2392 if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
2393 link->reported_link_cap.link_rate = LINK_RATE_HIGH2;
2394
2379 link->verified_link_cap = link->reported_link_cap; 2395 link->verified_link_cap = link->reported_link_cap;
2380} 2396}
2381 2397
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index 7c866a7d5e77..82cd1d6e6e59 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -11,8 +11,6 @@
11#include "dc_link_dp.h" 11#include "dc_link_dp.h"
12#include "dc_link_ddc.h" 12#include "dc_link_ddc.h"
13#include "dm_helpers.h" 13#include "dm_helpers.h"
14#include "dce/dce_link_encoder.h"
15#include "dce/dce_stream_encoder.h"
16#include "dpcd_defs.h" 14#include "dpcd_defs.h"
17 15
18enum dc_status core_link_read_dpcd( 16enum dc_status core_link_read_dpcd(
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index ba3487e97361..751f3ac9d921 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -45,8 +45,9 @@
45#include "dcn10/dcn10_resource.h" 45#include "dcn10/dcn10_resource.h"
46#endif 46#endif
47#include "dce120/dce120_resource.h" 47#include "dce120/dce120_resource.h"
48#define DC_LOGGER \ 48
49 ctx->logger 49#define DC_LOGGER_INIT(logger)
50
50enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) 51enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
51{ 52{
52 enum dce_version dc_version = DCE_VERSION_UNKNOWN; 53 enum dce_version dc_version = DCE_VERSION_UNKNOWN;
@@ -78,6 +79,8 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
78 ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev)) { 79 ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev)) {
79 dc_version = DCE_VERSION_11_2; 80 dc_version = DCE_VERSION_11_2;
80 } 81 }
82 if (ASIC_REV_IS_VEGAM(asic_id.hw_internal_rev))
83 dc_version = DCE_VERSION_11_22;
81 break; 84 break;
82 case FAMILY_AI: 85 case FAMILY_AI:
83 dc_version = DCE_VERSION_12_0; 86 dc_version = DCE_VERSION_12_0;
@@ -124,6 +127,7 @@ struct resource_pool *dc_create_resource_pool(
124 num_virtual_links, dc, asic_id); 127 num_virtual_links, dc, asic_id);
125 break; 128 break;
126 case DCE_VERSION_11_2: 129 case DCE_VERSION_11_2:
130 case DCE_VERSION_11_22:
127 res_pool = dce112_create_resource_pool( 131 res_pool = dce112_create_resource_pool(
128 num_virtual_links, dc); 132 num_virtual_links, dc);
129 break; 133 break;
@@ -492,9 +496,9 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
492 data->viewport_c.x = data->viewport.x / vpc_div; 496 data->viewport_c.x = data->viewport.x / vpc_div;
493 data->viewport_c.y = data->viewport.y / vpc_div; 497 data->viewport_c.y = data->viewport.y / vpc_div;
494 data->inits.h_c = (data->viewport.x % vpc_div) != 0 ? 498 data->inits.h_c = (data->viewport.x % vpc_div) != 0 ?
495 dal_fixed31_32_half : dal_fixed31_32_zero; 499 dc_fixpt_half : dc_fixpt_zero;
496 data->inits.v_c = (data->viewport.y % vpc_div) != 0 ? 500 data->inits.v_c = (data->viewport.y % vpc_div) != 0 ?
497 dal_fixed31_32_half : dal_fixed31_32_zero; 501 dc_fixpt_half : dc_fixpt_zero;
498 /* Round up, assume original video size always even dimensions */ 502 /* Round up, assume original video size always even dimensions */
499 data->viewport_c.width = (data->viewport.width + vpc_div - 1) / vpc_div; 503 data->viewport_c.width = (data->viewport.width + vpc_div - 1) / vpc_div;
500 data->viewport_c.height = (data->viewport.height + vpc_div - 1) / vpc_div; 504 data->viewport_c.height = (data->viewport.height + vpc_div - 1) / vpc_div;
@@ -623,10 +627,10 @@ static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx)
623 pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) 627 pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
624 rect_swap_helper(&surf_src); 628 rect_swap_helper(&surf_src);
625 629
626 pipe_ctx->plane_res.scl_data.ratios.horz = dal_fixed31_32_from_fraction( 630 pipe_ctx->plane_res.scl_data.ratios.horz = dc_fixpt_from_fraction(
627 surf_src.width, 631 surf_src.width,
628 plane_state->dst_rect.width); 632 plane_state->dst_rect.width);
629 pipe_ctx->plane_res.scl_data.ratios.vert = dal_fixed31_32_from_fraction( 633 pipe_ctx->plane_res.scl_data.ratios.vert = dc_fixpt_from_fraction(
630 surf_src.height, 634 surf_src.height,
631 plane_state->dst_rect.height); 635 plane_state->dst_rect.height);
632 636
@@ -648,6 +652,14 @@ static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx)
648 pipe_ctx->plane_res.scl_data.ratios.horz_c.value /= 2; 652 pipe_ctx->plane_res.scl_data.ratios.horz_c.value /= 2;
649 pipe_ctx->plane_res.scl_data.ratios.vert_c.value /= 2; 653 pipe_ctx->plane_res.scl_data.ratios.vert_c.value /= 2;
650 } 654 }
655 pipe_ctx->plane_res.scl_data.ratios.horz = dc_fixpt_truncate(
656 pipe_ctx->plane_res.scl_data.ratios.horz, 19);
657 pipe_ctx->plane_res.scl_data.ratios.vert = dc_fixpt_truncate(
658 pipe_ctx->plane_res.scl_data.ratios.vert, 19);
659 pipe_ctx->plane_res.scl_data.ratios.horz_c = dc_fixpt_truncate(
660 pipe_ctx->plane_res.scl_data.ratios.horz_c, 19);
661 pipe_ctx->plane_res.scl_data.ratios.vert_c = dc_fixpt_truncate(
662 pipe_ctx->plane_res.scl_data.ratios.vert_c, 19);
651} 663}
652 664
653static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *recout_skip) 665static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *recout_skip)
@@ -684,32 +696,33 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
684 * init_bot = init + scaling_ratio 696 * init_bot = init + scaling_ratio
685 * init_c = init + truncated_vp_c_offset(from calculate viewport) 697 * init_c = init + truncated_vp_c_offset(from calculate viewport)
686 */ 698 */
687 data->inits.h = dal_fixed31_32_div_int( 699 data->inits.h = dc_fixpt_truncate(dc_fixpt_div_int(
688 dal_fixed31_32_add_int(data->ratios.horz, data->taps.h_taps + 1), 2); 700 dc_fixpt_add_int(data->ratios.horz, data->taps.h_taps + 1), 2), 19);
689 701
690 data->inits.h_c = dal_fixed31_32_add(data->inits.h_c, dal_fixed31_32_div_int( 702 data->inits.h_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.h_c, dc_fixpt_div_int(
691 dal_fixed31_32_add_int(data->ratios.horz_c, data->taps.h_taps_c + 1), 2)); 703 dc_fixpt_add_int(data->ratios.horz_c, data->taps.h_taps_c + 1), 2)), 19);
692 704
693 data->inits.v = dal_fixed31_32_div_int( 705 data->inits.v = dc_fixpt_truncate(dc_fixpt_div_int(
694 dal_fixed31_32_add_int(data->ratios.vert, data->taps.v_taps + 1), 2); 706 dc_fixpt_add_int(data->ratios.vert, data->taps.v_taps + 1), 2), 19);
707
708 data->inits.v_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.v_c, dc_fixpt_div_int(
709 dc_fixpt_add_int(data->ratios.vert_c, data->taps.v_taps_c + 1), 2)), 19);
695 710
696 data->inits.v_c = dal_fixed31_32_add(data->inits.v_c, dal_fixed31_32_div_int(
697 dal_fixed31_32_add_int(data->ratios.vert_c, data->taps.v_taps_c + 1), 2));
698 711
699 712
700 /* Adjust for viewport end clip-off */ 713 /* Adjust for viewport end clip-off */
701 if ((data->viewport.x + data->viewport.width) < (src.x + src.width) && !flip_horz_scan_dir) { 714 if ((data->viewport.x + data->viewport.width) < (src.x + src.width) && !flip_horz_scan_dir) {
702 int vp_clip = src.x + src.width - data->viewport.width - data->viewport.x; 715 int vp_clip = src.x + src.width - data->viewport.width - data->viewport.x;
703 int int_part = dal_fixed31_32_floor( 716 int int_part = dc_fixpt_floor(
704 dal_fixed31_32_sub(data->inits.h, data->ratios.horz)); 717 dc_fixpt_sub(data->inits.h, data->ratios.horz));
705 718
706 int_part = int_part > 0 ? int_part : 0; 719 int_part = int_part > 0 ? int_part : 0;
707 data->viewport.width += int_part < vp_clip ? int_part : vp_clip; 720 data->viewport.width += int_part < vp_clip ? int_part : vp_clip;
708 } 721 }
709 if ((data->viewport.y + data->viewport.height) < (src.y + src.height) && !flip_vert_scan_dir) { 722 if ((data->viewport.y + data->viewport.height) < (src.y + src.height) && !flip_vert_scan_dir) {
710 int vp_clip = src.y + src.height - data->viewport.height - data->viewport.y; 723 int vp_clip = src.y + src.height - data->viewport.height - data->viewport.y;
711 int int_part = dal_fixed31_32_floor( 724 int int_part = dc_fixpt_floor(
712 dal_fixed31_32_sub(data->inits.v, data->ratios.vert)); 725 dc_fixpt_sub(data->inits.v, data->ratios.vert));
713 726
714 int_part = int_part > 0 ? int_part : 0; 727 int_part = int_part > 0 ? int_part : 0;
715 data->viewport.height += int_part < vp_clip ? int_part : vp_clip; 728 data->viewport.height += int_part < vp_clip ? int_part : vp_clip;
@@ -717,8 +730,8 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
717 if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div && !flip_horz_scan_dir) { 730 if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div && !flip_horz_scan_dir) {
718 int vp_clip = (src.x + src.width) / vpc_div - 731 int vp_clip = (src.x + src.width) / vpc_div -
719 data->viewport_c.width - data->viewport_c.x; 732 data->viewport_c.width - data->viewport_c.x;
720 int int_part = dal_fixed31_32_floor( 733 int int_part = dc_fixpt_floor(
721 dal_fixed31_32_sub(data->inits.h_c, data->ratios.horz_c)); 734 dc_fixpt_sub(data->inits.h_c, data->ratios.horz_c));
722 735
723 int_part = int_part > 0 ? int_part : 0; 736 int_part = int_part > 0 ? int_part : 0;
724 data->viewport_c.width += int_part < vp_clip ? int_part : vp_clip; 737 data->viewport_c.width += int_part < vp_clip ? int_part : vp_clip;
@@ -726,8 +739,8 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
726 if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div && !flip_vert_scan_dir) { 739 if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div && !flip_vert_scan_dir) {
727 int vp_clip = (src.y + src.height) / vpc_div - 740 int vp_clip = (src.y + src.height) / vpc_div -
728 data->viewport_c.height - data->viewport_c.y; 741 data->viewport_c.height - data->viewport_c.y;
729 int int_part = dal_fixed31_32_floor( 742 int int_part = dc_fixpt_floor(
730 dal_fixed31_32_sub(data->inits.v_c, data->ratios.vert_c)); 743 dc_fixpt_sub(data->inits.v_c, data->ratios.vert_c));
731 744
732 int_part = int_part > 0 ? int_part : 0; 745 int_part = int_part > 0 ? int_part : 0;
733 data->viewport_c.height += int_part < vp_clip ? int_part : vp_clip; 746 data->viewport_c.height += int_part < vp_clip ? int_part : vp_clip;
@@ -737,9 +750,9 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
737 if (data->viewport.x && !flip_horz_scan_dir) { 750 if (data->viewport.x && !flip_horz_scan_dir) {
738 int int_part; 751 int int_part;
739 752
740 data->inits.h = dal_fixed31_32_add(data->inits.h, dal_fixed31_32_mul_int( 753 data->inits.h = dc_fixpt_add(data->inits.h, dc_fixpt_mul_int(
741 data->ratios.horz, recout_skip->width)); 754 data->ratios.horz, recout_skip->width));
742 int_part = dal_fixed31_32_floor(data->inits.h) - data->viewport.x; 755 int_part = dc_fixpt_floor(data->inits.h) - data->viewport.x;
743 if (int_part < data->taps.h_taps) { 756 if (int_part < data->taps.h_taps) {
744 int int_adj = data->viewport.x >= (data->taps.h_taps - int_part) ? 757 int int_adj = data->viewport.x >= (data->taps.h_taps - int_part) ?
745 (data->taps.h_taps - int_part) : data->viewport.x; 758 (data->taps.h_taps - int_part) : data->viewport.x;
@@ -752,15 +765,15 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
752 int_part = data->taps.h_taps; 765 int_part = data->taps.h_taps;
753 } 766 }
754 data->inits.h.value &= 0xffffffff; 767 data->inits.h.value &= 0xffffffff;
755 data->inits.h = dal_fixed31_32_add_int(data->inits.h, int_part); 768 data->inits.h = dc_fixpt_add_int(data->inits.h, int_part);
756 } 769 }
757 770
758 if (data->viewport_c.x && !flip_horz_scan_dir) { 771 if (data->viewport_c.x && !flip_horz_scan_dir) {
759 int int_part; 772 int int_part;
760 773
761 data->inits.h_c = dal_fixed31_32_add(data->inits.h_c, dal_fixed31_32_mul_int( 774 data->inits.h_c = dc_fixpt_add(data->inits.h_c, dc_fixpt_mul_int(
762 data->ratios.horz_c, recout_skip->width)); 775 data->ratios.horz_c, recout_skip->width));
763 int_part = dal_fixed31_32_floor(data->inits.h_c) - data->viewport_c.x; 776 int_part = dc_fixpt_floor(data->inits.h_c) - data->viewport_c.x;
764 if (int_part < data->taps.h_taps_c) { 777 if (int_part < data->taps.h_taps_c) {
765 int int_adj = data->viewport_c.x >= (data->taps.h_taps_c - int_part) ? 778 int int_adj = data->viewport_c.x >= (data->taps.h_taps_c - int_part) ?
766 (data->taps.h_taps_c - int_part) : data->viewport_c.x; 779 (data->taps.h_taps_c - int_part) : data->viewport_c.x;
@@ -773,15 +786,15 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
773 int_part = data->taps.h_taps_c; 786 int_part = data->taps.h_taps_c;
774 } 787 }
775 data->inits.h_c.value &= 0xffffffff; 788 data->inits.h_c.value &= 0xffffffff;
776 data->inits.h_c = dal_fixed31_32_add_int(data->inits.h_c, int_part); 789 data->inits.h_c = dc_fixpt_add_int(data->inits.h_c, int_part);
777 } 790 }
778 791
779 if (data->viewport.y && !flip_vert_scan_dir) { 792 if (data->viewport.y && !flip_vert_scan_dir) {
780 int int_part; 793 int int_part;
781 794
782 data->inits.v = dal_fixed31_32_add(data->inits.v, dal_fixed31_32_mul_int( 795 data->inits.v = dc_fixpt_add(data->inits.v, dc_fixpt_mul_int(
783 data->ratios.vert, recout_skip->height)); 796 data->ratios.vert, recout_skip->height));
784 int_part = dal_fixed31_32_floor(data->inits.v) - data->viewport.y; 797 int_part = dc_fixpt_floor(data->inits.v) - data->viewport.y;
785 if (int_part < data->taps.v_taps) { 798 if (int_part < data->taps.v_taps) {
786 int int_adj = data->viewport.y >= (data->taps.v_taps - int_part) ? 799 int int_adj = data->viewport.y >= (data->taps.v_taps - int_part) ?
787 (data->taps.v_taps - int_part) : data->viewport.y; 800 (data->taps.v_taps - int_part) : data->viewport.y;
@@ -794,15 +807,15 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
794 int_part = data->taps.v_taps; 807 int_part = data->taps.v_taps;
795 } 808 }
796 data->inits.v.value &= 0xffffffff; 809 data->inits.v.value &= 0xffffffff;
797 data->inits.v = dal_fixed31_32_add_int(data->inits.v, int_part); 810 data->inits.v = dc_fixpt_add_int(data->inits.v, int_part);
798 } 811 }
799 812
800 if (data->viewport_c.y && !flip_vert_scan_dir) { 813 if (data->viewport_c.y && !flip_vert_scan_dir) {
801 int int_part; 814 int int_part;
802 815
803 data->inits.v_c = dal_fixed31_32_add(data->inits.v_c, dal_fixed31_32_mul_int( 816 data->inits.v_c = dc_fixpt_add(data->inits.v_c, dc_fixpt_mul_int(
804 data->ratios.vert_c, recout_skip->height)); 817 data->ratios.vert_c, recout_skip->height));
805 int_part = dal_fixed31_32_floor(data->inits.v_c) - data->viewport_c.y; 818 int_part = dc_fixpt_floor(data->inits.v_c) - data->viewport_c.y;
806 if (int_part < data->taps.v_taps_c) { 819 if (int_part < data->taps.v_taps_c) {
807 int int_adj = data->viewport_c.y >= (data->taps.v_taps_c - int_part) ? 820 int int_adj = data->viewport_c.y >= (data->taps.v_taps_c - int_part) ?
808 (data->taps.v_taps_c - int_part) : data->viewport_c.y; 821 (data->taps.v_taps_c - int_part) : data->viewport_c.y;
@@ -815,12 +828,12 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
815 int_part = data->taps.v_taps_c; 828 int_part = data->taps.v_taps_c;
816 } 829 }
817 data->inits.v_c.value &= 0xffffffff; 830 data->inits.v_c.value &= 0xffffffff;
818 data->inits.v_c = dal_fixed31_32_add_int(data->inits.v_c, int_part); 831 data->inits.v_c = dc_fixpt_add_int(data->inits.v_c, int_part);
819 } 832 }
820 833
821 /* Interlaced inits based on final vert inits */ 834 /* Interlaced inits based on final vert inits */
822 data->inits.v_bot = dal_fixed31_32_add(data->inits.v, data->ratios.vert); 835 data->inits.v_bot = dc_fixpt_add(data->inits.v, data->ratios.vert);
823 data->inits.v_c_bot = dal_fixed31_32_add(data->inits.v_c, data->ratios.vert_c); 836 data->inits.v_c_bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
824 837
825 if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 || 838 if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
826 pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) { 839 pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) {
@@ -835,7 +848,7 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
835 struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; 848 struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
836 struct view recout_skip = { 0 }; 849 struct view recout_skip = { 0 };
837 bool res = false; 850 bool res = false;
838 struct dc_context *ctx = pipe_ctx->stream->ctx; 851 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
839 /* Important: scaling ratio calculation requires pixel format, 852 /* Important: scaling ratio calculation requires pixel format,
840 * lb depth calculation requires recout and taps require scaling ratios. 853 * lb depth calculation requires recout and taps require scaling ratios.
841 * Inits require viewport, taps, ratios and recout of split pipe 854 * Inits require viewport, taps, ratios and recout of split pipe
@@ -843,6 +856,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
843 pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface( 856 pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface(
844 pipe_ctx->plane_state->format); 857 pipe_ctx->plane_state->format);
845 858
859 if (pipe_ctx->stream->timing.flags.INTERLACE)
860 pipe_ctx->stream->dst.height *= 2;
861
846 calculate_scaling_ratios(pipe_ctx); 862 calculate_scaling_ratios(pipe_ctx);
847 863
848 calculate_viewport(pipe_ctx); 864 calculate_viewport(pipe_ctx);
@@ -863,6 +879,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
863 879
864 pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right; 880 pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right;
865 pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; 881 pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
882 if (pipe_ctx->stream->timing.flags.INTERLACE)
883 pipe_ctx->plane_res.scl_data.v_active *= 2;
866 884
867 885
868 /* Taps calculations */ 886 /* Taps calculations */
@@ -908,6 +926,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
908 plane_state->dst_rect.x, 926 plane_state->dst_rect.x,
909 plane_state->dst_rect.y); 927 plane_state->dst_rect.y);
910 928
929 if (pipe_ctx->stream->timing.flags.INTERLACE)
930 pipe_ctx->stream->dst.height /= 2;
931
911 return res; 932 return res;
912} 933}
913 934
@@ -1294,6 +1315,19 @@ bool dc_add_all_planes_for_stream(
1294} 1315}
1295 1316
1296 1317
1318static bool is_hdr_static_meta_changed(struct dc_stream_state *cur_stream,
1319 struct dc_stream_state *new_stream)
1320{
1321 if (cur_stream == NULL)
1322 return true;
1323
1324 if (memcmp(&cur_stream->hdr_static_metadata,
1325 &new_stream->hdr_static_metadata,
1326 sizeof(struct dc_info_packet)) != 0)
1327 return true;
1328
1329 return false;
1330}
1297 1331
1298static bool is_timing_changed(struct dc_stream_state *cur_stream, 1332static bool is_timing_changed(struct dc_stream_state *cur_stream,
1299 struct dc_stream_state *new_stream) 1333 struct dc_stream_state *new_stream)
@@ -1329,6 +1363,9 @@ static bool are_stream_backends_same(
1329 if (is_timing_changed(stream_a, stream_b)) 1363 if (is_timing_changed(stream_a, stream_b))
1330 return false; 1364 return false;
1331 1365
1366 if (is_hdr_static_meta_changed(stream_a, stream_b))
1367 return false;
1368
1332 return true; 1369 return true;
1333} 1370}
1334 1371
@@ -1599,18 +1636,6 @@ enum dc_status dc_remove_stream_from_ctx(
1599 return DC_OK; 1636 return DC_OK;
1600} 1637}
1601 1638
1602static void copy_pipe_ctx(
1603 const struct pipe_ctx *from_pipe_ctx, struct pipe_ctx *to_pipe_ctx)
1604{
1605 struct dc_plane_state *plane_state = to_pipe_ctx->plane_state;
1606 struct dc_stream_state *stream = to_pipe_ctx->stream;
1607
1608 *to_pipe_ctx = *from_pipe_ctx;
1609 to_pipe_ctx->stream = stream;
1610 if (plane_state != NULL)
1611 to_pipe_ctx->plane_state = plane_state;
1612}
1613
1614static struct dc_stream_state *find_pll_sharable_stream( 1639static struct dc_stream_state *find_pll_sharable_stream(
1615 struct dc_stream_state *stream_needs_pll, 1640 struct dc_stream_state *stream_needs_pll,
1616 struct dc_state *context) 1641 struct dc_state *context)
@@ -1703,7 +1728,7 @@ enum dc_status resource_map_pool_resources(
1703 pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream); 1728 pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
1704#endif 1729#endif
1705 1730
1706 if (pipe_idx < 0) 1731 if (pipe_idx < 0 || context->res_ctx.pipe_ctx[pipe_idx].stream_res.tg == NULL)
1707 return DC_NO_CONTROLLER_RESOURCE; 1732 return DC_NO_CONTROLLER_RESOURCE;
1708 1733
1709 pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; 1734 pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
@@ -1752,26 +1777,6 @@ enum dc_status resource_map_pool_resources(
1752 return DC_ERROR_UNEXPECTED; 1777 return DC_ERROR_UNEXPECTED;
1753} 1778}
1754 1779
1755/* first stream in the context is used to populate the rest */
1756void validate_guaranteed_copy_streams(
1757 struct dc_state *context,
1758 int max_streams)
1759{
1760 int i;
1761
1762 for (i = 1; i < max_streams; i++) {
1763 context->streams[i] = context->streams[0];
1764
1765 copy_pipe_ctx(&context->res_ctx.pipe_ctx[0],
1766 &context->res_ctx.pipe_ctx[i]);
1767 context->res_ctx.pipe_ctx[i].stream =
1768 context->res_ctx.pipe_ctx[0].stream;
1769
1770 dc_stream_retain(context->streams[i]);
1771 context->stream_count++;
1772 }
1773}
1774
1775void dc_resource_state_copy_construct_current( 1780void dc_resource_state_copy_construct_current(
1776 const struct dc *dc, 1781 const struct dc *dc,
1777 struct dc_state *dst_ctx) 1782 struct dc_state *dst_ctx)
@@ -1798,9 +1803,9 @@ enum dc_status dc_validate_global_state(
1798 return DC_ERROR_UNEXPECTED; 1803 return DC_ERROR_UNEXPECTED;
1799 1804
1800 if (dc->res_pool->funcs->validate_global) { 1805 if (dc->res_pool->funcs->validate_global) {
1801 result = dc->res_pool->funcs->validate_global(dc, new_ctx); 1806 result = dc->res_pool->funcs->validate_global(dc, new_ctx);
1802 if (result != DC_OK) 1807 if (result != DC_OK)
1803 return result; 1808 return result;
1804 } 1809 }
1805 1810
1806 for (i = 0; i < new_ctx->stream_count; i++) { 1811 for (i = 0; i < new_ctx->stream_count; i++) {
@@ -1843,7 +1848,7 @@ enum dc_status dc_validate_global_state(
1843} 1848}
1844 1849
1845static void patch_gamut_packet_checksum( 1850static void patch_gamut_packet_checksum(
1846 struct encoder_info_packet *gamut_packet) 1851 struct dc_info_packet *gamut_packet)
1847{ 1852{
1848 /* For gamut we recalc checksum */ 1853 /* For gamut we recalc checksum */
1849 if (gamut_packet->valid) { 1854 if (gamut_packet->valid) {
@@ -1862,12 +1867,11 @@ static void patch_gamut_packet_checksum(
1862} 1867}
1863 1868
1864static void set_avi_info_frame( 1869static void set_avi_info_frame(
1865 struct encoder_info_packet *info_packet, 1870 struct dc_info_packet *info_packet,
1866 struct pipe_ctx *pipe_ctx) 1871 struct pipe_ctx *pipe_ctx)
1867{ 1872{
1868 struct dc_stream_state *stream = pipe_ctx->stream; 1873 struct dc_stream_state *stream = pipe_ctx->stream;
1869 enum dc_color_space color_space = COLOR_SPACE_UNKNOWN; 1874 enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
1870 struct info_frame info_frame = { {0} };
1871 uint32_t pixel_encoding = 0; 1875 uint32_t pixel_encoding = 0;
1872 enum scanning_type scan_type = SCANNING_TYPE_NODATA; 1876 enum scanning_type scan_type = SCANNING_TYPE_NODATA;
1873 enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA; 1877 enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA;
@@ -1877,22 +1881,24 @@ static void set_avi_info_frame(
1877 unsigned int cn0_cn1_value = 0; 1881 unsigned int cn0_cn1_value = 0;
1878 uint8_t *check_sum = NULL; 1882 uint8_t *check_sum = NULL;
1879 uint8_t byte_index = 0; 1883 uint8_t byte_index = 0;
1880 union hdmi_info_packet *hdmi_info = &info_frame.avi_info_packet.info_packet_hdmi; 1884 union hdmi_info_packet hdmi_info;
1881 union display_content_support support = {0}; 1885 union display_content_support support = {0};
1882 unsigned int vic = pipe_ctx->stream->timing.vic; 1886 unsigned int vic = pipe_ctx->stream->timing.vic;
1883 enum dc_timing_3d_format format; 1887 enum dc_timing_3d_format format;
1884 1888
1889 memset(&hdmi_info, 0, sizeof(union hdmi_info_packet));
1890
1885 color_space = pipe_ctx->stream->output_color_space; 1891 color_space = pipe_ctx->stream->output_color_space;
1886 if (color_space == COLOR_SPACE_UNKNOWN) 1892 if (color_space == COLOR_SPACE_UNKNOWN)
1887 color_space = (stream->timing.pixel_encoding == PIXEL_ENCODING_RGB) ? 1893 color_space = (stream->timing.pixel_encoding == PIXEL_ENCODING_RGB) ?
1888 COLOR_SPACE_SRGB:COLOR_SPACE_YCBCR709; 1894 COLOR_SPACE_SRGB:COLOR_SPACE_YCBCR709;
1889 1895
1890 /* Initialize header */ 1896 /* Initialize header */
1891 hdmi_info->bits.header.info_frame_type = HDMI_INFOFRAME_TYPE_AVI; 1897 hdmi_info.bits.header.info_frame_type = HDMI_INFOFRAME_TYPE_AVI;
1892 /* InfoFrameVersion_3 is defined by CEA861F (Section 6.4), but shall 1898 /* InfoFrameVersion_3 is defined by CEA861F (Section 6.4), but shall
1893 * not be used in HDMI 2.0 (Section 10.1) */ 1899 * not be used in HDMI 2.0 (Section 10.1) */
1894 hdmi_info->bits.header.version = 2; 1900 hdmi_info.bits.header.version = 2;
1895 hdmi_info->bits.header.length = HDMI_AVI_INFOFRAME_SIZE; 1901 hdmi_info.bits.header.length = HDMI_AVI_INFOFRAME_SIZE;
1896 1902
1897 /* 1903 /*
1898 * IDO-defined (Y2,Y1,Y0 = 1,1,1) shall not be used by devices built 1904 * IDO-defined (Y2,Y1,Y0 = 1,1,1) shall not be used by devices built
@@ -1918,39 +1924,39 @@ static void set_avi_info_frame(
1918 1924
1919 /* Y0_Y1_Y2 : The pixel encoding */ 1925 /* Y0_Y1_Y2 : The pixel encoding */
1920 /* H14b AVI InfoFrame has extension on Y-field from 2 bits to 3 bits */ 1926 /* H14b AVI InfoFrame has extension on Y-field from 2 bits to 3 bits */
1921 hdmi_info->bits.Y0_Y1_Y2 = pixel_encoding; 1927 hdmi_info.bits.Y0_Y1_Y2 = pixel_encoding;
1922 1928
1923 /* A0 = 1 Active Format Information valid */ 1929 /* A0 = 1 Active Format Information valid */
1924 hdmi_info->bits.A0 = ACTIVE_FORMAT_VALID; 1930 hdmi_info.bits.A0 = ACTIVE_FORMAT_VALID;
1925 1931
1926 /* B0, B1 = 3; Bar info data is valid */ 1932 /* B0, B1 = 3; Bar info data is valid */
1927 hdmi_info->bits.B0_B1 = BAR_INFO_BOTH_VALID; 1933 hdmi_info.bits.B0_B1 = BAR_INFO_BOTH_VALID;
1928 1934
1929 hdmi_info->bits.SC0_SC1 = PICTURE_SCALING_UNIFORM; 1935 hdmi_info.bits.SC0_SC1 = PICTURE_SCALING_UNIFORM;
1930 1936
1931 /* S0, S1 : Underscan / Overscan */ 1937 /* S0, S1 : Underscan / Overscan */
1932 /* TODO: un-hardcode scan type */ 1938 /* TODO: un-hardcode scan type */
1933 scan_type = SCANNING_TYPE_UNDERSCAN; 1939 scan_type = SCANNING_TYPE_UNDERSCAN;
1934 hdmi_info->bits.S0_S1 = scan_type; 1940 hdmi_info.bits.S0_S1 = scan_type;
1935 1941
1936 /* C0, C1 : Colorimetry */ 1942 /* C0, C1 : Colorimetry */
1937 if (color_space == COLOR_SPACE_YCBCR709 || 1943 if (color_space == COLOR_SPACE_YCBCR709 ||
1938 color_space == COLOR_SPACE_YCBCR709_LIMITED) 1944 color_space == COLOR_SPACE_YCBCR709_LIMITED)
1939 hdmi_info->bits.C0_C1 = COLORIMETRY_ITU709; 1945 hdmi_info.bits.C0_C1 = COLORIMETRY_ITU709;
1940 else if (color_space == COLOR_SPACE_YCBCR601 || 1946 else if (color_space == COLOR_SPACE_YCBCR601 ||
1941 color_space == COLOR_SPACE_YCBCR601_LIMITED) 1947 color_space == COLOR_SPACE_YCBCR601_LIMITED)
1942 hdmi_info->bits.C0_C1 = COLORIMETRY_ITU601; 1948 hdmi_info.bits.C0_C1 = COLORIMETRY_ITU601;
1943 else { 1949 else {
1944 hdmi_info->bits.C0_C1 = COLORIMETRY_NO_DATA; 1950 hdmi_info.bits.C0_C1 = COLORIMETRY_NO_DATA;
1945 } 1951 }
1946 if (color_space == COLOR_SPACE_2020_RGB_FULLRANGE || 1952 if (color_space == COLOR_SPACE_2020_RGB_FULLRANGE ||
1947 color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE || 1953 color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE ||
1948 color_space == COLOR_SPACE_2020_YCBCR) { 1954 color_space == COLOR_SPACE_2020_YCBCR) {
1949 hdmi_info->bits.EC0_EC2 = COLORIMETRYEX_BT2020RGBYCBCR; 1955 hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_BT2020RGBYCBCR;
1950 hdmi_info->bits.C0_C1 = COLORIMETRY_EXTENDED; 1956 hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED;
1951 } else if (color_space == COLOR_SPACE_ADOBERGB) { 1957 } else if (color_space == COLOR_SPACE_ADOBERGB) {
1952 hdmi_info->bits.EC0_EC2 = COLORIMETRYEX_ADOBERGB; 1958 hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_ADOBERGB;
1953 hdmi_info->bits.C0_C1 = COLORIMETRY_EXTENDED; 1959 hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED;
1954 } 1960 }
1955 1961
1956 /* TODO: un-hardcode aspect ratio */ 1962 /* TODO: un-hardcode aspect ratio */
@@ -1959,18 +1965,18 @@ static void set_avi_info_frame(
1959 switch (aspect) { 1965 switch (aspect) {
1960 case ASPECT_RATIO_4_3: 1966 case ASPECT_RATIO_4_3:
1961 case ASPECT_RATIO_16_9: 1967 case ASPECT_RATIO_16_9:
1962 hdmi_info->bits.M0_M1 = aspect; 1968 hdmi_info.bits.M0_M1 = aspect;
1963 break; 1969 break;
1964 1970
1965 case ASPECT_RATIO_NO_DATA: 1971 case ASPECT_RATIO_NO_DATA:
1966 case ASPECT_RATIO_64_27: 1972 case ASPECT_RATIO_64_27:
1967 case ASPECT_RATIO_256_135: 1973 case ASPECT_RATIO_256_135:
1968 default: 1974 default:
1969 hdmi_info->bits.M0_M1 = 0; 1975 hdmi_info.bits.M0_M1 = 0;
1970 } 1976 }
1971 1977
1972 /* Active Format Aspect ratio - same as Picture Aspect Ratio. */ 1978 /* Active Format Aspect ratio - same as Picture Aspect Ratio. */
1973 hdmi_info->bits.R0_R3 = ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE; 1979 hdmi_info.bits.R0_R3 = ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE;
1974 1980
1975 /* TODO: un-hardcode cn0_cn1 and itc */ 1981 /* TODO: un-hardcode cn0_cn1 and itc */
1976 1982
@@ -2013,8 +2019,8 @@ static void set_avi_info_frame(
2013 } 2019 }
2014 } 2020 }
2015 } 2021 }
2016 hdmi_info->bits.CN0_CN1 = cn0_cn1_value; 2022 hdmi_info.bits.CN0_CN1 = cn0_cn1_value;
2017 hdmi_info->bits.ITC = itc_value; 2023 hdmi_info.bits.ITC = itc_value;
2018 } 2024 }
2019 2025
2020 /* TODO : We should handle YCC quantization */ 2026 /* TODO : We should handle YCC quantization */
@@ -2023,19 +2029,19 @@ static void set_avi_info_frame(
2023 stream->sink->edid_caps.qy_bit == 1) { 2029 stream->sink->edid_caps.qy_bit == 1) {
2024 if (color_space == COLOR_SPACE_SRGB || 2030 if (color_space == COLOR_SPACE_SRGB ||
2025 color_space == COLOR_SPACE_2020_RGB_FULLRANGE) { 2031 color_space == COLOR_SPACE_2020_RGB_FULLRANGE) {
2026 hdmi_info->bits.Q0_Q1 = RGB_QUANTIZATION_FULL_RANGE; 2032 hdmi_info.bits.Q0_Q1 = RGB_QUANTIZATION_FULL_RANGE;
2027 hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_FULL_RANGE; 2033 hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_FULL_RANGE;
2028 } else if (color_space == COLOR_SPACE_SRGB_LIMITED || 2034 } else if (color_space == COLOR_SPACE_SRGB_LIMITED ||
2029 color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE) { 2035 color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE) {
2030 hdmi_info->bits.Q0_Q1 = RGB_QUANTIZATION_LIMITED_RANGE; 2036 hdmi_info.bits.Q0_Q1 = RGB_QUANTIZATION_LIMITED_RANGE;
2031 hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE; 2037 hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
2032 } else { 2038 } else {
2033 hdmi_info->bits.Q0_Q1 = RGB_QUANTIZATION_DEFAULT_RANGE; 2039 hdmi_info.bits.Q0_Q1 = RGB_QUANTIZATION_DEFAULT_RANGE;
2034 hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE; 2040 hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
2035 } 2041 }
2036 } else { 2042 } else {
2037 hdmi_info->bits.Q0_Q1 = RGB_QUANTIZATION_DEFAULT_RANGE; 2043 hdmi_info.bits.Q0_Q1 = RGB_QUANTIZATION_DEFAULT_RANGE;
2038 hdmi_info->bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE; 2044 hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
2039 } 2045 }
2040 2046
2041 ///VIC 2047 ///VIC
@@ -2060,51 +2066,49 @@ static void set_avi_info_frame(
2060 break; 2066 break;
2061 } 2067 }
2062 } 2068 }
2063 hdmi_info->bits.VIC0_VIC7 = vic; 2069 hdmi_info.bits.VIC0_VIC7 = vic;
2064 2070
2065 /* pixel repetition 2071 /* pixel repetition
2066 * PR0 - PR3 start from 0 whereas pHwPathMode->mode.timing.flags.pixel 2072 * PR0 - PR3 start from 0 whereas pHwPathMode->mode.timing.flags.pixel
2067 * repetition start from 1 */ 2073 * repetition start from 1 */
2068 hdmi_info->bits.PR0_PR3 = 0; 2074 hdmi_info.bits.PR0_PR3 = 0;
2069 2075
2070 /* Bar Info 2076 /* Bar Info
2071 * barTop: Line Number of End of Top Bar. 2077 * barTop: Line Number of End of Top Bar.
2072 * barBottom: Line Number of Start of Bottom Bar. 2078 * barBottom: Line Number of Start of Bottom Bar.
2073 * barLeft: Pixel Number of End of Left Bar. 2079 * barLeft: Pixel Number of End of Left Bar.
2074 * barRight: Pixel Number of Start of Right Bar. */ 2080 * barRight: Pixel Number of Start of Right Bar. */
2075 hdmi_info->bits.bar_top = stream->timing.v_border_top; 2081 hdmi_info.bits.bar_top = stream->timing.v_border_top;
2076 hdmi_info->bits.bar_bottom = (stream->timing.v_total 2082 hdmi_info.bits.bar_bottom = (stream->timing.v_total
2077 - stream->timing.v_border_bottom + 1); 2083 - stream->timing.v_border_bottom + 1);
2078 hdmi_info->bits.bar_left = stream->timing.h_border_left; 2084 hdmi_info.bits.bar_left = stream->timing.h_border_left;
2079 hdmi_info->bits.bar_right = (stream->timing.h_total 2085 hdmi_info.bits.bar_right = (stream->timing.h_total
2080 - stream->timing.h_border_right + 1); 2086 - stream->timing.h_border_right + 1);
2081 2087
2082 /* check_sum - Calculate AFMT_AVI_INFO0 ~ AFMT_AVI_INFO3 */ 2088 /* check_sum - Calculate AFMT_AVI_INFO0 ~ AFMT_AVI_INFO3 */
2083 check_sum = &info_frame.avi_info_packet.info_packet_hdmi.packet_raw_data.sb[0]; 2089 check_sum = &hdmi_info.packet_raw_data.sb[0];
2084 2090
2085 *check_sum = HDMI_INFOFRAME_TYPE_AVI + HDMI_AVI_INFOFRAME_SIZE + 2; 2091 *check_sum = HDMI_INFOFRAME_TYPE_AVI + HDMI_AVI_INFOFRAME_SIZE + 2;
2086 2092
2087 for (byte_index = 1; byte_index <= HDMI_AVI_INFOFRAME_SIZE; byte_index++) 2093 for (byte_index = 1; byte_index <= HDMI_AVI_INFOFRAME_SIZE; byte_index++)
2088 *check_sum += hdmi_info->packet_raw_data.sb[byte_index]; 2094 *check_sum += hdmi_info.packet_raw_data.sb[byte_index];
2089 2095
2090 /* one byte complement */ 2096 /* one byte complement */
2091 *check_sum = (uint8_t) (0x100 - *check_sum); 2097 *check_sum = (uint8_t) (0x100 - *check_sum);
2092 2098
2093 /* Store in hw_path_mode */ 2099 /* Store in hw_path_mode */
2094 info_packet->hb0 = hdmi_info->packet_raw_data.hb0; 2100 info_packet->hb0 = hdmi_info.packet_raw_data.hb0;
2095 info_packet->hb1 = hdmi_info->packet_raw_data.hb1; 2101 info_packet->hb1 = hdmi_info.packet_raw_data.hb1;
2096 info_packet->hb2 = hdmi_info->packet_raw_data.hb2; 2102 info_packet->hb2 = hdmi_info.packet_raw_data.hb2;
2097 2103
2098 for (byte_index = 0; byte_index < sizeof(info_frame.avi_info_packet. 2104 for (byte_index = 0; byte_index < sizeof(hdmi_info.packet_raw_data.sb); byte_index++)
2099 info_packet_hdmi.packet_raw_data.sb); byte_index++) 2105 info_packet->sb[byte_index] = hdmi_info.packet_raw_data.sb[byte_index];
2100 info_packet->sb[byte_index] = info_frame.avi_info_packet.
2101 info_packet_hdmi.packet_raw_data.sb[byte_index];
2102 2106
2103 info_packet->valid = true; 2107 info_packet->valid = true;
2104} 2108}
2105 2109
2106static void set_vendor_info_packet( 2110static void set_vendor_info_packet(
2107 struct encoder_info_packet *info_packet, 2111 struct dc_info_packet *info_packet,
2108 struct dc_stream_state *stream) 2112 struct dc_stream_state *stream)
2109{ 2113{
2110 uint32_t length = 0; 2114 uint32_t length = 0;
@@ -2217,7 +2221,7 @@ static void set_vendor_info_packet(
2217} 2221}
2218 2222
2219static void set_spd_info_packet( 2223static void set_spd_info_packet(
2220 struct encoder_info_packet *info_packet, 2224 struct dc_info_packet *info_packet,
2221 struct dc_stream_state *stream) 2225 struct dc_stream_state *stream)
2222{ 2226{
2223 /* SPD info packet for FreeSync */ 2227 /* SPD info packet for FreeSync */
@@ -2338,104 +2342,19 @@ static void set_spd_info_packet(
2338} 2342}
2339 2343
2340static void set_hdr_static_info_packet( 2344static void set_hdr_static_info_packet(
2341 struct encoder_info_packet *info_packet, 2345 struct dc_info_packet *info_packet,
2342 struct dc_stream_state *stream) 2346 struct dc_stream_state *stream)
2343{ 2347{
2344 uint16_t i = 0; 2348 /* HDR Static Metadata info packet for HDR10 */
2345 enum signal_type signal = stream->signal;
2346 uint32_t data;
2347 2349
2348 if (!stream->hdr_static_metadata.hdr_supported) 2350 if (!stream->hdr_static_metadata.valid)
2349 return; 2351 return;
2350 2352
2351 if (dc_is_hdmi_signal(signal)) { 2353 *info_packet = stream->hdr_static_metadata;
2352 info_packet->valid = true;
2353
2354 info_packet->hb0 = 0x87;
2355 info_packet->hb1 = 0x01;
2356 info_packet->hb2 = 0x1A;
2357 i = 1;
2358 } else if (dc_is_dp_signal(signal)) {
2359 info_packet->valid = true;
2360
2361 info_packet->hb0 = 0x00;
2362 info_packet->hb1 = 0x87;
2363 info_packet->hb2 = 0x1D;
2364 info_packet->hb3 = (0x13 << 2);
2365 i = 2;
2366 }
2367
2368 data = stream->hdr_static_metadata.is_hdr;
2369 info_packet->sb[i++] = data ? 0x02 : 0x00;
2370 info_packet->sb[i++] = 0x00;
2371
2372 data = stream->hdr_static_metadata.chromaticity_green_x / 2;
2373 info_packet->sb[i++] = data & 0xFF;
2374 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2375
2376 data = stream->hdr_static_metadata.chromaticity_green_y / 2;
2377 info_packet->sb[i++] = data & 0xFF;
2378 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2379
2380 data = stream->hdr_static_metadata.chromaticity_blue_x / 2;
2381 info_packet->sb[i++] = data & 0xFF;
2382 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2383
2384 data = stream->hdr_static_metadata.chromaticity_blue_y / 2;
2385 info_packet->sb[i++] = data & 0xFF;
2386 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2387
2388 data = stream->hdr_static_metadata.chromaticity_red_x / 2;
2389 info_packet->sb[i++] = data & 0xFF;
2390 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2391
2392 data = stream->hdr_static_metadata.chromaticity_red_y / 2;
2393 info_packet->sb[i++] = data & 0xFF;
2394 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2395
2396 data = stream->hdr_static_metadata.chromaticity_white_point_x / 2;
2397 info_packet->sb[i++] = data & 0xFF;
2398 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2399
2400 data = stream->hdr_static_metadata.chromaticity_white_point_y / 2;
2401 info_packet->sb[i++] = data & 0xFF;
2402 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2403
2404 data = stream->hdr_static_metadata.max_luminance;
2405 info_packet->sb[i++] = data & 0xFF;
2406 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2407
2408 data = stream->hdr_static_metadata.min_luminance;
2409 info_packet->sb[i++] = data & 0xFF;
2410 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2411
2412 data = stream->hdr_static_metadata.maximum_content_light_level;
2413 info_packet->sb[i++] = data & 0xFF;
2414 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2415
2416 data = stream->hdr_static_metadata.maximum_frame_average_light_level;
2417 info_packet->sb[i++] = data & 0xFF;
2418 info_packet->sb[i++] = (data & 0xFF00) >> 8;
2419
2420 if (dc_is_hdmi_signal(signal)) {
2421 uint32_t checksum = 0;
2422
2423 checksum += info_packet->hb0;
2424 checksum += info_packet->hb1;
2425 checksum += info_packet->hb2;
2426
2427 for (i = 1; i <= info_packet->hb2; i++)
2428 checksum += info_packet->sb[i];
2429
2430 info_packet->sb[0] = 0x100 - checksum;
2431 } else if (dc_is_dp_signal(signal)) {
2432 info_packet->sb[0] = 0x01;
2433 info_packet->sb[1] = 0x1A;
2434 }
2435} 2354}
2436 2355
2437static void set_vsc_info_packet( 2356static void set_vsc_info_packet(
2438 struct encoder_info_packet *info_packet, 2357 struct dc_info_packet *info_packet,
2439 struct dc_stream_state *stream) 2358 struct dc_stream_state *stream)
2440{ 2359{
2441 unsigned int vscPacketRevision = 0; 2360 unsigned int vscPacketRevision = 0;
@@ -2650,6 +2569,8 @@ bool pipe_need_reprogram(
2650 if (is_timing_changed(pipe_ctx_old->stream, pipe_ctx->stream)) 2569 if (is_timing_changed(pipe_ctx_old->stream, pipe_ctx->stream))
2651 return true; 2570 return true;
2652 2571
2572 if (is_hdr_static_meta_changed(pipe_ctx_old->stream, pipe_ctx->stream))
2573 return true;
2653 2574
2654 return false; 2575 return false;
2655} 2576}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index ce0747ed0f00..3732a1de9d6c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -101,14 +101,16 @@ static void construct(struct dc_stream_state *stream,
101 stream->status.link = stream->sink->link; 101 stream->status.link = stream->sink->link;
102 102
103 update_stream_signal(stream); 103 update_stream_signal(stream);
104
105 stream->out_transfer_func = dc_create_transfer_func();
106 stream->out_transfer_func->type = TF_TYPE_BYPASS;
104} 107}
105 108
106static void destruct(struct dc_stream_state *stream) 109static void destruct(struct dc_stream_state *stream)
107{ 110{
108 dc_sink_release(stream->sink); 111 dc_sink_release(stream->sink);
109 if (stream->out_transfer_func != NULL) { 112 if (stream->out_transfer_func != NULL) {
110 dc_transfer_func_release( 113 dc_transfer_func_release(stream->out_transfer_func);
111 stream->out_transfer_func);
112 stream->out_transfer_func = NULL; 114 stream->out_transfer_func = NULL;
113 } 115 }
114} 116}
@@ -176,6 +178,7 @@ bool dc_stream_set_cursor_attributes(
176 int i; 178 int i;
177 struct dc *core_dc; 179 struct dc *core_dc;
178 struct resource_context *res_ctx; 180 struct resource_context *res_ctx;
181 struct pipe_ctx *pipe_to_program = NULL;
179 182
180 if (NULL == stream) { 183 if (NULL == stream) {
181 dm_error("DC: dc_stream is NULL!\n"); 184 dm_error("DC: dc_stream is NULL!\n");
@@ -203,9 +206,17 @@ bool dc_stream_set_cursor_attributes(
203 if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) 206 if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
204 continue; 207 continue;
205 208
209 if (!pipe_to_program) {
210 pipe_to_program = pipe_ctx;
211 core_dc->hwss.pipe_control_lock(core_dc, pipe_to_program, true);
212 }
206 213
207 core_dc->hwss.set_cursor_attribute(pipe_ctx); 214 core_dc->hwss.set_cursor_attribute(pipe_ctx);
208 } 215 }
216
217 if (pipe_to_program)
218 core_dc->hwss.pipe_control_lock(core_dc, pipe_to_program, false);
219
209 return true; 220 return true;
210} 221}
211 222
@@ -216,6 +227,7 @@ bool dc_stream_set_cursor_position(
216 int i; 227 int i;
217 struct dc *core_dc; 228 struct dc *core_dc;
218 struct resource_context *res_ctx; 229 struct resource_context *res_ctx;
230 struct pipe_ctx *pipe_to_program = NULL;
219 231
220 if (NULL == stream) { 232 if (NULL == stream) {
221 dm_error("DC: dc_stream is NULL!\n"); 233 dm_error("DC: dc_stream is NULL!\n");
@@ -241,9 +253,17 @@ bool dc_stream_set_cursor_position(
241 !pipe_ctx->plane_res.ipp) 253 !pipe_ctx->plane_res.ipp)
242 continue; 254 continue;
243 255
256 if (!pipe_to_program) {
257 pipe_to_program = pipe_ctx;
258 core_dc->hwss.pipe_control_lock(core_dc, pipe_to_program, true);
259 }
260
244 core_dc->hwss.set_cursor_position(pipe_ctx); 261 core_dc->hwss.set_cursor_position(pipe_ctx);
245 } 262 }
246 263
264 if (pipe_to_program)
265 core_dc->hwss.pipe_control_lock(core_dc, pipe_to_program, false);
266
247 return true; 267 return true;
248} 268}
249 269
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
index 132eef3826e2..68a71adeb12e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -38,6 +38,12 @@
38static void construct(struct dc_context *ctx, struct dc_plane_state *plane_state) 38static void construct(struct dc_context *ctx, struct dc_plane_state *plane_state)
39{ 39{
40 plane_state->ctx = ctx; 40 plane_state->ctx = ctx;
41
42 plane_state->gamma_correction = dc_create_gamma();
43 plane_state->gamma_correction->is_identity = true;
44
45 plane_state->in_transfer_func = dc_create_transfer_func();
46 plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
41} 47}
42 48
43static void destruct(struct dc_plane_state *plane_state) 49static void destruct(struct dc_plane_state *plane_state)
@@ -175,7 +181,7 @@ void dc_transfer_func_release(struct dc_transfer_func *tf)
175 kref_put(&tf->refcount, dc_transfer_func_free); 181 kref_put(&tf->refcount, dc_transfer_func_free);
176} 182}
177 183
178struct dc_transfer_func *dc_create_transfer_func(void) 184struct dc_transfer_func *dc_create_transfer_func()
179{ 185{
180 struct dc_transfer_func *tf = kvzalloc(sizeof(*tf), GFP_KERNEL); 186 struct dc_transfer_func *tf = kvzalloc(sizeof(*tf), GFP_KERNEL);
181 187
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index fa4b3c8b3bb7..9cfde0ccf4e9 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -38,7 +38,7 @@
38#include "inc/compressor.h" 38#include "inc/compressor.h"
39#include "dml/display_mode_lib.h" 39#include "dml/display_mode_lib.h"
40 40
41#define DC_VER "3.1.38" 41#define DC_VER "3.1.44"
42 42
43#define MAX_SURFACES 3 43#define MAX_SURFACES 3
44#define MAX_STREAMS 6 44#define MAX_STREAMS 6
@@ -75,6 +75,7 @@ struct dc_caps {
75 bool dynamic_audio; 75 bool dynamic_audio;
76 bool is_apu; 76 bool is_apu;
77 bool dual_link_dvi; 77 bool dual_link_dvi;
78 bool post_blend_color_processing;
78}; 79};
79 80
80struct dc_dcc_surface_param { 81struct dc_dcc_surface_param {
@@ -202,6 +203,8 @@ struct dc_debug {
202 bool timing_trace; 203 bool timing_trace;
203 bool clock_trace; 204 bool clock_trace;
204 bool validation_trace; 205 bool validation_trace;
206 bool bandwidth_calcs_trace;
207 int max_downscale_src_width;
205 208
206 /* stutter efficiency related */ 209 /* stutter efficiency related */
207 bool disable_stutter; 210 bool disable_stutter;
@@ -238,6 +241,8 @@ struct dc_debug {
238 bool az_endpoint_mute_only; 241 bool az_endpoint_mute_only;
239 bool always_use_regamma; 242 bool always_use_regamma;
240 bool p010_mpo_support; 243 bool p010_mpo_support;
244 bool recovery_enabled;
245
241}; 246};
242struct dc_state; 247struct dc_state;
243struct resource_pool; 248struct resource_pool;
@@ -332,20 +337,6 @@ enum {
332 TRANSFER_FUNC_POINTS = 1025 337 TRANSFER_FUNC_POINTS = 1025
333}; 338};
334 339
335// Moved here from color module for linux
336enum color_transfer_func {
337 transfer_func_unknown,
338 transfer_func_srgb,
339 transfer_func_bt709,
340 transfer_func_pq2084,
341 transfer_func_pq2084_interim,
342 transfer_func_linear_0_1,
343 transfer_func_linear_0_125,
344 transfer_func_dolbyvision,
345 transfer_func_gamma_22,
346 transfer_func_gamma_26
347};
348
349struct dc_hdr_static_metadata { 340struct dc_hdr_static_metadata {
350 /* display chromaticities and white point in units of 0.00001 */ 341 /* display chromaticities and white point in units of 0.00001 */
351 unsigned int chromaticity_green_x; 342 unsigned int chromaticity_green_x;
@@ -361,9 +352,6 @@ struct dc_hdr_static_metadata {
361 uint32_t max_luminance; 352 uint32_t max_luminance;
362 uint32_t maximum_content_light_level; 353 uint32_t maximum_content_light_level;
363 uint32_t maximum_frame_average_light_level; 354 uint32_t maximum_frame_average_light_level;
364
365 bool hdr_supported;
366 bool is_hdr;
367}; 355};
368 356
369enum dc_transfer_func_type { 357enum dc_transfer_func_type {
@@ -419,7 +407,6 @@ union surface_update_flags {
419 /* Medium updates */ 407 /* Medium updates */
420 uint32_t dcc_change:1; 408 uint32_t dcc_change:1;
421 uint32_t color_space_change:1; 409 uint32_t color_space_change:1;
422 uint32_t input_tf_change:1;
423 uint32_t horizontal_mirror_change:1; 410 uint32_t horizontal_mirror_change:1;
424 uint32_t per_pixel_alpha_change:1; 411 uint32_t per_pixel_alpha_change:1;
425 uint32_t rotation_change:1; 412 uint32_t rotation_change:1;
@@ -428,6 +415,7 @@ union surface_update_flags {
428 uint32_t position_change:1; 415 uint32_t position_change:1;
429 uint32_t in_transfer_func_change:1; 416 uint32_t in_transfer_func_change:1;
430 uint32_t input_csc_change:1; 417 uint32_t input_csc_change:1;
418 uint32_t coeff_reduction_change:1;
431 uint32_t output_tf_change:1; 419 uint32_t output_tf_change:1;
432 uint32_t pixel_format_change:1; 420 uint32_t pixel_format_change:1;
433 421
@@ -460,7 +448,7 @@ struct dc_plane_state {
460 struct dc_gamma *gamma_correction; 448 struct dc_gamma *gamma_correction;
461 struct dc_transfer_func *in_transfer_func; 449 struct dc_transfer_func *in_transfer_func;
462 struct dc_bias_and_scale *bias_and_scale; 450 struct dc_bias_and_scale *bias_and_scale;
463 struct csc_transform input_csc_color_matrix; 451 struct dc_csc_transform input_csc_color_matrix;
464 struct fixed31_32 coeff_reduction_factor; 452 struct fixed31_32 coeff_reduction_factor;
465 uint32_t sdr_white_level; 453 uint32_t sdr_white_level;
466 454
@@ -468,7 +456,6 @@ struct dc_plane_state {
468 struct dc_hdr_static_metadata hdr_static_ctx; 456 struct dc_hdr_static_metadata hdr_static_ctx;
469 457
470 enum dc_color_space color_space; 458 enum dc_color_space color_space;
471 enum color_transfer_func input_tf;
472 459
473 enum surface_pixel_format format; 460 enum surface_pixel_format format;
474 enum dc_rotation_angle rotation; 461 enum dc_rotation_angle rotation;
@@ -498,7 +485,6 @@ struct dc_plane_info {
498 enum dc_rotation_angle rotation; 485 enum dc_rotation_angle rotation;
499 enum plane_stereo_format stereo_format; 486 enum plane_stereo_format stereo_format;
500 enum dc_color_space color_space; 487 enum dc_color_space color_space;
501 enum color_transfer_func input_tf;
502 unsigned int sdr_white_level; 488 unsigned int sdr_white_level;
503 bool horizontal_mirror; 489 bool horizontal_mirror;
504 bool visible; 490 bool visible;
@@ -517,19 +503,18 @@ struct dc_surface_update {
517 struct dc_plane_state *surface; 503 struct dc_plane_state *surface;
518 504
519 /* isr safe update parameters. null means no updates */ 505 /* isr safe update parameters. null means no updates */
520 struct dc_flip_addrs *flip_addr; 506 const struct dc_flip_addrs *flip_addr;
521 struct dc_plane_info *plane_info; 507 const struct dc_plane_info *plane_info;
522 struct dc_scaling_info *scaling_info; 508 const struct dc_scaling_info *scaling_info;
523 509
524 /* following updates require alloc/sleep/spin that is not isr safe, 510 /* following updates require alloc/sleep/spin that is not isr safe,
525 * null means no updates 511 * null means no updates
526 */ 512 */
527 struct dc_gamma *gamma; 513 const struct dc_gamma *gamma;
528 enum color_transfer_func color_input_tf; 514 const struct dc_transfer_func *in_transfer_func;
529 struct dc_transfer_func *in_transfer_func;
530 515
531 struct csc_transform *input_csc_color_matrix; 516 const struct dc_csc_transform *input_csc_color_matrix;
532 struct fixed31_32 *coeff_reduction_factor; 517 const struct fixed31_32 *coeff_reduction_factor;
533}; 518};
534 519
535/* 520/*
@@ -699,6 +684,7 @@ struct dc_cursor {
699 struct dc_cursor_attributes attributes; 684 struct dc_cursor_attributes attributes;
700}; 685};
701 686
687
702/******************************************************************************* 688/*******************************************************************************
703 * Interrupt interfaces 689 * Interrupt interfaces
704 ******************************************************************************/ 690 ******************************************************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
index 2726b02e006b..90bccd5ccaa2 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -26,6 +26,8 @@
26#ifndef DC_DP_TYPES_H 26#ifndef DC_DP_TYPES_H
27#define DC_DP_TYPES_H 27#define DC_DP_TYPES_H
28 28
29#include "os_types.h"
30
29enum dc_lane_count { 31enum dc_lane_count {
30 LANE_COUNT_UNKNOWN = 0, 32 LANE_COUNT_UNKNOWN = 0,
31 LANE_COUNT_ONE = 1, 33 LANE_COUNT_ONE = 1,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c
index 48e1fcf53d43..bd0fda0ceb91 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c
@@ -117,6 +117,65 @@ uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
117 return reg_val; 117 return reg_val;
118} 118}
119 119
120uint32_t generic_reg_get6(const struct dc_context *ctx, uint32_t addr,
121 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
122 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
123 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
124 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
125 uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
126 uint8_t shift6, uint32_t mask6, uint32_t *field_value6)
127{
128 uint32_t reg_val = dm_read_reg(ctx, addr);
129 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
130 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
131 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
132 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
133 *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
134 *field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6);
135 return reg_val;
136}
137
138uint32_t generic_reg_get7(const struct dc_context *ctx, uint32_t addr,
139 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
140 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
141 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
142 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
143 uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
144 uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
145 uint8_t shift7, uint32_t mask7, uint32_t *field_value7)
146{
147 uint32_t reg_val = dm_read_reg(ctx, addr);
148 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
149 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
150 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
151 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
152 *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
153 *field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6);
154 *field_value7 = get_reg_field_value_ex(reg_val, mask7, shift7);
155 return reg_val;
156}
157
158uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr,
159 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
160 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
161 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
162 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
163 uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
164 uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
165 uint8_t shift7, uint32_t mask7, uint32_t *field_value7,
166 uint8_t shift8, uint32_t mask8, uint32_t *field_value8)
167{
168 uint32_t reg_val = dm_read_reg(ctx, addr);
169 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
170 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
171 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
172 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
173 *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
174 *field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6);
175 *field_value7 = get_reg_field_value_ex(reg_val, mask7, shift7);
176 *field_value8 = get_reg_field_value_ex(reg_val, mask8, shift8);
177 return reg_val;
178}
120/* note: va version of this is pretty bad idea, since there is a output parameter pass by pointer 179/* note: va version of this is pretty bad idea, since there is a output parameter pass by pointer
121 * compiler won't be able to check for size match and is prone to stack corruption type of bugs 180 * compiler won't be able to check for size match and is prone to stack corruption type of bugs
122 181
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index b83a7dc2f5a9..b1f70579d61b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -423,6 +423,11 @@ enum dc_gamma_type {
423 GAMMA_CS_TFM_1D = 3, 423 GAMMA_CS_TFM_1D = 3,
424}; 424};
425 425
426struct dc_csc_transform {
427 uint16_t matrix[12];
428 bool enable_adjustment;
429};
430
426struct dc_gamma { 431struct dc_gamma {
427 struct kref refcount; 432 struct kref refcount;
428 enum dc_gamma_type type; 433 enum dc_gamma_type type;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index dc34515ef01f..8a716baa1203 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -51,6 +51,14 @@ struct link_mst_stream_allocation_table {
51 struct link_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM]; 51 struct link_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM];
52}; 52};
53 53
54struct time_stamp {
55 uint64_t edp_poweroff;
56 uint64_t edp_poweron;
57};
58
59struct link_trace {
60 struct time_stamp time_stamp;
61};
54/* 62/*
55 * A link contains one or more sinks and their connected status. 63 * A link contains one or more sinks and their connected status.
56 * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported. 64 * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
@@ -114,6 +122,7 @@ struct dc_link {
114 122
115 struct dc_link_status link_status; 123 struct dc_link_status link_status;
116 124
125 struct link_trace link_trace;
117}; 126};
118 127
119const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link); 128const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index d017df56b2ba..d7e6d53bb383 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -58,18 +58,20 @@ struct dc_stream_state {
58 58
59 struct freesync_context freesync_ctx; 59 struct freesync_context freesync_ctx;
60 60
61 struct dc_hdr_static_metadata hdr_static_metadata; 61 struct dc_info_packet hdr_static_metadata;
62 struct dc_transfer_func *out_transfer_func; 62 struct dc_transfer_func *out_transfer_func;
63 struct colorspace_transform gamut_remap_matrix; 63 struct colorspace_transform gamut_remap_matrix;
64 struct csc_transform csc_color_matrix; 64 struct dc_csc_transform csc_color_matrix;
65 65
66 enum dc_color_space output_color_space; 66 enum dc_color_space output_color_space;
67 enum dc_dither_option dither_option; 67 enum dc_dither_option dither_option;
68 68
69 enum view_3d_format view_format; 69 enum view_3d_format view_format;
70 enum color_transfer_func output_tf;
71 70
72 bool ignore_msa_timing_param; 71 bool ignore_msa_timing_param;
72
73 unsigned long long periodic_fn_vsync_delta;
74
73 /* TODO: custom INFO packets */ 75 /* TODO: custom INFO packets */
74 /* TODO: ABM info (DMCU) */ 76 /* TODO: ABM info (DMCU) */
75 /* PSR info */ 77 /* PSR info */
@@ -110,9 +112,10 @@ struct dc_stream_update {
110 struct rect src; 112 struct rect src;
111 struct rect dst; 113 struct rect dst;
112 struct dc_transfer_func *out_transfer_func; 114 struct dc_transfer_func *out_transfer_func;
113 struct dc_hdr_static_metadata *hdr_static_metadata; 115 struct dc_info_packet *hdr_static_metadata;
114 enum color_transfer_func color_output_tf;
115 unsigned int *abm_level; 116 unsigned int *abm_level;
117
118 unsigned long long *periodic_fn_vsync_delta;
116}; 119};
117 120
118bool dc_is_stream_unchanged( 121bool dc_is_stream_unchanged(
@@ -131,13 +134,6 @@ bool dc_is_stream_scaling_unchanged(
131 * This does not trigger a flip. No surface address is programmed. 134 * This does not trigger a flip. No surface address is programmed.
132 */ 135 */
133 136
134bool dc_commit_planes_to_stream(
135 struct dc *dc,
136 struct dc_plane_state **plane_states,
137 uint8_t new_plane_count,
138 struct dc_stream_state *dc_stream,
139 struct dc_state *state);
140
141void dc_commit_updates_for_stream(struct dc *dc, 137void dc_commit_updates_for_stream(struct dc *dc,
142 struct dc_surface_update *srf_updates, 138 struct dc_surface_update *srf_updates,
143 int surface_count, 139 int surface_count,
@@ -209,14 +205,6 @@ bool dc_add_all_planes_for_stream(
209enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream); 205enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
210 206
211/* 207/*
212 * This function takes a stream and checks if it is guaranteed to be supported.
213 * Guaranteed means that MAX_COFUNC similar streams are supported.
214 *
215 * After this call:
216 * No hardware is programmed for call. Only validation is done.
217 */
218
219/*
220 * Set up streams and links associated to drive sinks 208 * Set up streams and links associated to drive sinks
221 * The streams parameter is an absolute set of all active streams. 209 * The streams parameter is an absolute set of all active streams.
222 * 210 *
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 9441305d3ab5..76df2534c4a4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -25,7 +25,7 @@
25#ifndef DC_TYPES_H_ 25#ifndef DC_TYPES_H_
26#define DC_TYPES_H_ 26#define DC_TYPES_H_
27 27
28#include "fixed32_32.h" 28#include "os_types.h"
29#include "fixed31_32.h" 29#include "fixed31_32.h"
30#include "irq_types.h" 30#include "irq_types.h"
31#include "dc_dp_types.h" 31#include "dc_dp_types.h"
@@ -370,12 +370,6 @@ struct dc_csc_adjustments {
370 struct fixed31_32 hue; 370 struct fixed31_32 hue;
371}; 371};
372 372
373enum {
374 MAX_LANES = 2,
375 MAX_COFUNC_PATH = 6,
376 LAYER_INDEX_PRIMARY = -1,
377};
378
379enum dpcd_downstream_port_max_bpc { 373enum dpcd_downstream_port_max_bpc {
380 DOWN_STREAM_MAX_8BPC = 0, 374 DOWN_STREAM_MAX_8BPC = 0,
381 DOWN_STREAM_MAX_10BPC, 375 DOWN_STREAM_MAX_10BPC,
@@ -530,6 +524,15 @@ struct vrr_params {
530 uint32_t frame_counter; 524 uint32_t frame_counter;
531}; 525};
532 526
527struct dc_info_packet {
528 bool valid;
529 uint8_t hb0;
530 uint8_t hb1;
531 uint8_t hb2;
532 uint8_t hb3;
533 uint8_t sb[32];
534};
535
533#define DC_PLANE_UPDATE_TIMES_MAX 10 536#define DC_PLANE_UPDATE_TIMES_MAX 10
534 537
535struct dc_plane_flip_time { 538struct dc_plane_flip_time {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
index fe92a1222803..29294db1a96b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
@@ -26,7 +26,7 @@
26#include "dce_abm.h" 26#include "dce_abm.h"
27#include "dm_services.h" 27#include "dm_services.h"
28#include "reg_helper.h" 28#include "reg_helper.h"
29#include "fixed32_32.h" 29#include "fixed31_32.h"
30#include "dc.h" 30#include "dc.h"
31 31
32#include "atom.h" 32#include "atom.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
index 6d5cdcdc8ec9..7f6d724686f1 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -33,8 +33,9 @@
33 33
34#define CTX \ 34#define CTX \
35 aud->base.ctx 35 aud->base.ctx
36#define DC_LOGGER \ 36
37 aud->base.ctx->logger 37#define DC_LOGGER_INIT()
38
38#define REG(reg)\ 39#define REG(reg)\
39 (aud->regs->reg) 40 (aud->regs->reg)
40 41
@@ -348,8 +349,8 @@ static void set_audio_latency(
348 349
349void dce_aud_az_enable(struct audio *audio) 350void dce_aud_az_enable(struct audio *audio)
350{ 351{
351 struct dce_audio *aud = DCE_AUD(audio);
352 uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL); 352 uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
353 DC_LOGGER_INIT();
353 354
354 set_reg_field_value(value, 1, 355 set_reg_field_value(value, 1,
355 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, 356 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
@@ -371,7 +372,7 @@ void dce_aud_az_enable(struct audio *audio)
371void dce_aud_az_disable(struct audio *audio) 372void dce_aud_az_disable(struct audio *audio)
372{ 373{
373 uint32_t value; 374 uint32_t value;
374 struct dce_audio *aud = DCE_AUD(audio); 375 DC_LOGGER_INIT();
375 376
376 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL); 377 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
377 set_reg_field_value(value, 1, 378 set_reg_field_value(value, 1,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
index 0aa2cda60890..599c7ab6befe 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
@@ -41,8 +41,9 @@
41 41
42#define CTX \ 42#define CTX \
43 clk_src->base.ctx 43 clk_src->base.ctx
44#define DC_LOGGER \ 44
45 calc_pll_cs->ctx->logger 45#define DC_LOGGER_INIT()
46
46#undef FN 47#undef FN
47#define FN(reg_name, field_name) \ 48#define FN(reg_name, field_name) \
48 clk_src->cs_shift->field_name, clk_src->cs_mask->field_name 49 clk_src->cs_shift->field_name, clk_src->cs_mask->field_name
@@ -467,7 +468,7 @@ static uint32_t dce110_get_pix_clk_dividers_helper (
467{ 468{
468 uint32_t field = 0; 469 uint32_t field = 0;
469 uint32_t pll_calc_error = MAX_PLL_CALC_ERROR; 470 uint32_t pll_calc_error = MAX_PLL_CALC_ERROR;
470 struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll; 471 DC_LOGGER_INIT();
471 /* Check if reference clock is external (not pcie/xtalin) 472 /* Check if reference clock is external (not pcie/xtalin)
472 * HW Dce80 spec: 473 * HW Dce80 spec:
473 * 00 - PCIE_REFCLK, 01 - XTALIN, 02 - GENERICA, 03 - GENERICB 474 * 00 - PCIE_REFCLK, 01 - XTALIN, 02 - GENERICA, 03 - GENERICB
@@ -557,8 +558,8 @@ static uint32_t dce110_get_pix_clk_dividers(
557 struct pll_settings *pll_settings) 558 struct pll_settings *pll_settings)
558{ 559{
559 struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs); 560 struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs);
560 struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll;
561 uint32_t pll_calc_error = MAX_PLL_CALC_ERROR; 561 uint32_t pll_calc_error = MAX_PLL_CALC_ERROR;
562 DC_LOGGER_INIT();
562 563
563 if (pix_clk_params == NULL || pll_settings == NULL 564 if (pix_clk_params == NULL || pll_settings == NULL
564 || pix_clk_params->requested_pix_clk == 0) { 565 || pix_clk_params->requested_pix_clk == 0) {
@@ -589,6 +590,7 @@ static uint32_t dce110_get_pix_clk_dividers(
589 pll_settings, pix_clk_params); 590 pll_settings, pix_clk_params);
590 break; 591 break;
591 case DCE_VERSION_11_2: 592 case DCE_VERSION_11_2:
593 case DCE_VERSION_11_22:
592 case DCE_VERSION_12_0: 594 case DCE_VERSION_12_0:
593#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 595#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
594 case DCN_VERSION_1_0: 596 case DCN_VERSION_1_0:
@@ -655,12 +657,12 @@ static uint32_t dce110_get_d_to_pixel_rate_in_hz(
655 return 0; 657 return 0;
656 } 658 }
657 659
658 pix_rate = dal_fixed31_32_from_int(clk_src->ref_freq_khz); 660 pix_rate = dc_fixpt_from_int(clk_src->ref_freq_khz);
659 pix_rate = dal_fixed31_32_mul_int(pix_rate, 1000); 661 pix_rate = dc_fixpt_mul_int(pix_rate, 1000);
660 pix_rate = dal_fixed31_32_mul_int(pix_rate, phase); 662 pix_rate = dc_fixpt_mul_int(pix_rate, phase);
661 pix_rate = dal_fixed31_32_div_int(pix_rate, modulo); 663 pix_rate = dc_fixpt_div_int(pix_rate, modulo);
662 664
663 return dal_fixed31_32_round(pix_rate); 665 return dc_fixpt_round(pix_rate);
664 } else { 666 } else {
665 return dce110_get_dp_pixel_rate_from_combo_phy_pll(cs, pix_clk_params, pll_settings); 667 return dce110_get_dp_pixel_rate_from_combo_phy_pll(cs, pix_clk_params, pll_settings);
666 } 668 }
@@ -709,12 +711,12 @@ static bool calculate_ss(
709 const struct spread_spectrum_data *ss_data, 711 const struct spread_spectrum_data *ss_data,
710 struct delta_sigma_data *ds_data) 712 struct delta_sigma_data *ds_data)
711{ 713{
712 struct fixed32_32 fb_div; 714 struct fixed31_32 fb_div;
713 struct fixed32_32 ss_amount; 715 struct fixed31_32 ss_amount;
714 struct fixed32_32 ss_nslip_amount; 716 struct fixed31_32 ss_nslip_amount;
715 struct fixed32_32 ss_ds_frac_amount; 717 struct fixed31_32 ss_ds_frac_amount;
716 struct fixed32_32 ss_step_size; 718 struct fixed31_32 ss_step_size;
717 struct fixed32_32 modulation_time; 719 struct fixed31_32 modulation_time;
718 720
719 if (ds_data == NULL) 721 if (ds_data == NULL)
720 return false; 722 return false;
@@ -729,42 +731,42 @@ static bool calculate_ss(
729 731
730 /* compute SS_AMOUNT_FBDIV & SS_AMOUNT_NFRAC_SLIP & SS_AMOUNT_DSFRAC*/ 732 /* compute SS_AMOUNT_FBDIV & SS_AMOUNT_NFRAC_SLIP & SS_AMOUNT_DSFRAC*/
731 /* 6 decimal point support in fractional feedback divider */ 733 /* 6 decimal point support in fractional feedback divider */
732 fb_div = dal_fixed32_32_from_fraction( 734 fb_div = dc_fixpt_from_fraction(
733 pll_settings->fract_feedback_divider, 1000000); 735 pll_settings->fract_feedback_divider, 1000000);
734 fb_div = dal_fixed32_32_add_int(fb_div, pll_settings->feedback_divider); 736 fb_div = dc_fixpt_add_int(fb_div, pll_settings->feedback_divider);
735 737
736 ds_data->ds_frac_amount = 0; 738 ds_data->ds_frac_amount = 0;
737 /*spreadSpectrumPercentage is in the unit of .01%, 739 /*spreadSpectrumPercentage is in the unit of .01%,
738 * so have to divided by 100 * 100*/ 740 * so have to divided by 100 * 100*/
739 ss_amount = dal_fixed32_32_mul( 741 ss_amount = dc_fixpt_mul(
740 fb_div, dal_fixed32_32_from_fraction(ss_data->percentage, 742 fb_div, dc_fixpt_from_fraction(ss_data->percentage,
741 100 * ss_data->percentage_divider)); 743 100 * ss_data->percentage_divider));
742 ds_data->feedback_amount = dal_fixed32_32_floor(ss_amount); 744 ds_data->feedback_amount = dc_fixpt_floor(ss_amount);
743 745
744 ss_nslip_amount = dal_fixed32_32_sub(ss_amount, 746 ss_nslip_amount = dc_fixpt_sub(ss_amount,
745 dal_fixed32_32_from_int(ds_data->feedback_amount)); 747 dc_fixpt_from_int(ds_data->feedback_amount));
746 ss_nslip_amount = dal_fixed32_32_mul_int(ss_nslip_amount, 10); 748 ss_nslip_amount = dc_fixpt_mul_int(ss_nslip_amount, 10);
747 ds_data->nfrac_amount = dal_fixed32_32_floor(ss_nslip_amount); 749 ds_data->nfrac_amount = dc_fixpt_floor(ss_nslip_amount);
748 750
749 ss_ds_frac_amount = dal_fixed32_32_sub(ss_nslip_amount, 751 ss_ds_frac_amount = dc_fixpt_sub(ss_nslip_amount,
750 dal_fixed32_32_from_int(ds_data->nfrac_amount)); 752 dc_fixpt_from_int(ds_data->nfrac_amount));
751 ss_ds_frac_amount = dal_fixed32_32_mul_int(ss_ds_frac_amount, 65536); 753 ss_ds_frac_amount = dc_fixpt_mul_int(ss_ds_frac_amount, 65536);
752 ds_data->ds_frac_amount = dal_fixed32_32_floor(ss_ds_frac_amount); 754 ds_data->ds_frac_amount = dc_fixpt_floor(ss_ds_frac_amount);
753 755
754 /* compute SS_STEP_SIZE_DSFRAC */ 756 /* compute SS_STEP_SIZE_DSFRAC */
755 modulation_time = dal_fixed32_32_from_fraction( 757 modulation_time = dc_fixpt_from_fraction(
756 pll_settings->reference_freq * 1000, 758 pll_settings->reference_freq * 1000,
757 pll_settings->reference_divider * ss_data->modulation_freq_hz); 759 pll_settings->reference_divider * ss_data->modulation_freq_hz);
758 760
759 if (ss_data->flags.CENTER_SPREAD) 761 if (ss_data->flags.CENTER_SPREAD)
760 modulation_time = dal_fixed32_32_div_int(modulation_time, 4); 762 modulation_time = dc_fixpt_div_int(modulation_time, 4);
761 else 763 else
762 modulation_time = dal_fixed32_32_div_int(modulation_time, 2); 764 modulation_time = dc_fixpt_div_int(modulation_time, 2);
763 765
764 ss_step_size = dal_fixed32_32_div(ss_amount, modulation_time); 766 ss_step_size = dc_fixpt_div(ss_amount, modulation_time);
765 /* SS_STEP_SIZE_DSFRAC_DEC = Int(SS_STEP_SIZE * 2 ^ 16 * 10)*/ 767 /* SS_STEP_SIZE_DSFRAC_DEC = Int(SS_STEP_SIZE * 2 ^ 16 * 10)*/
766 ss_step_size = dal_fixed32_32_mul_int(ss_step_size, 65536 * 10); 768 ss_step_size = dc_fixpt_mul_int(ss_step_size, 65536 * 10);
767 ds_data->ds_frac_size = dal_fixed32_32_floor(ss_step_size); 769 ds_data->ds_frac_size = dc_fixpt_floor(ss_step_size);
768 770
769 return true; 771 return true;
770} 772}
@@ -978,6 +980,7 @@ static bool dce110_program_pix_clk(
978 980
979 break; 981 break;
980 case DCE_VERSION_11_2: 982 case DCE_VERSION_11_2:
983 case DCE_VERSION_11_22:
981 case DCE_VERSION_12_0: 984 case DCE_VERSION_12_0:
982#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 985#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
983 case DCN_VERSION_1_0: 986 case DCN_VERSION_1_0:
@@ -1054,7 +1057,7 @@ static void get_ss_info_from_atombios(
1054 struct spread_spectrum_info *ss_info_cur; 1057 struct spread_spectrum_info *ss_info_cur;
1055 struct spread_spectrum_data *ss_data_cur; 1058 struct spread_spectrum_data *ss_data_cur;
1056 uint32_t i; 1059 uint32_t i;
1057 struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll; 1060 DC_LOGGER_INIT();
1058 if (ss_entries_num == NULL) { 1061 if (ss_entries_num == NULL) {
1059 DC_LOG_SYNC( 1062 DC_LOG_SYNC(
1060 "Invalid entry !!!\n"); 1063 "Invalid entry !!!\n");
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
index 78e6beb6cf26..8a581c67bf2d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
@@ -26,7 +26,7 @@
26#include "dce_clocks.h" 26#include "dce_clocks.h"
27#include "dm_services.h" 27#include "dm_services.h"
28#include "reg_helper.h" 28#include "reg_helper.h"
29#include "fixed32_32.h" 29#include "fixed31_32.h"
30#include "bios_parser_interface.h" 30#include "bios_parser_interface.h"
31#include "dc.h" 31#include "dc.h"
32#include "dmcu.h" 32#include "dmcu.h"
@@ -35,7 +35,7 @@
35#endif 35#endif
36#include "core_types.h" 36#include "core_types.h"
37#include "dc_types.h" 37#include "dc_types.h"
38 38#include "dal_asic_id.h"
39 39
40#define TO_DCE_CLOCKS(clocks)\ 40#define TO_DCE_CLOCKS(clocks)\
41 container_of(clocks, struct dce_disp_clk, base) 41 container_of(clocks, struct dce_disp_clk, base)
@@ -228,19 +228,19 @@ static int dce_clocks_get_dp_ref_freq(struct display_clock *clk)
228 generated according to average value (case as with previous ASICs) 228 generated according to average value (case as with previous ASICs)
229 */ 229 */
230 if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { 230 if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) {
231 struct fixed32_32 ss_percentage = dal_fixed32_32_div_int( 231 struct fixed31_32 ss_percentage = dc_fixpt_div_int(
232 dal_fixed32_32_from_fraction( 232 dc_fixpt_from_fraction(
233 clk_dce->dprefclk_ss_percentage, 233 clk_dce->dprefclk_ss_percentage,
234 clk_dce->dprefclk_ss_divider), 200); 234 clk_dce->dprefclk_ss_divider), 200);
235 struct fixed32_32 adj_dp_ref_clk_khz; 235 struct fixed31_32 adj_dp_ref_clk_khz;
236 236
237 ss_percentage = dal_fixed32_32_sub(dal_fixed32_32_one, 237 ss_percentage = dc_fixpt_sub(dc_fixpt_one,
238 ss_percentage); 238 ss_percentage);
239 adj_dp_ref_clk_khz = 239 adj_dp_ref_clk_khz =
240 dal_fixed32_32_mul_int( 240 dc_fixpt_mul_int(
241 ss_percentage, 241 ss_percentage,
242 dp_ref_clk_khz); 242 dp_ref_clk_khz);
243 dp_ref_clk_khz = dal_fixed32_32_floor(adj_dp_ref_clk_khz); 243 dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz);
244 } 244 }
245 245
246 return dp_ref_clk_khz; 246 return dp_ref_clk_khz;
@@ -256,19 +256,19 @@ static int dce_clocks_get_dp_ref_freq_wrkaround(struct display_clock *clk)
256 int dp_ref_clk_khz = 600000; 256 int dp_ref_clk_khz = 600000;
257 257
258 if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { 258 if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) {
259 struct fixed32_32 ss_percentage = dal_fixed32_32_div_int( 259 struct fixed31_32 ss_percentage = dc_fixpt_div_int(
260 dal_fixed32_32_from_fraction( 260 dc_fixpt_from_fraction(
261 clk_dce->dprefclk_ss_percentage, 261 clk_dce->dprefclk_ss_percentage,
262 clk_dce->dprefclk_ss_divider), 200); 262 clk_dce->dprefclk_ss_divider), 200);
263 struct fixed32_32 adj_dp_ref_clk_khz; 263 struct fixed31_32 adj_dp_ref_clk_khz;
264 264
265 ss_percentage = dal_fixed32_32_sub(dal_fixed32_32_one, 265 ss_percentage = dc_fixpt_sub(dc_fixpt_one,
266 ss_percentage); 266 ss_percentage);
267 adj_dp_ref_clk_khz = 267 adj_dp_ref_clk_khz =
268 dal_fixed32_32_mul_int( 268 dc_fixpt_mul_int(
269 ss_percentage, 269 ss_percentage,
270 dp_ref_clk_khz); 270 dp_ref_clk_khz);
271 dp_ref_clk_khz = dal_fixed32_32_floor(adj_dp_ref_clk_khz); 271 dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz);
272 } 272 }
273 273
274 return dp_ref_clk_khz; 274 return dp_ref_clk_khz;
@@ -413,9 +413,12 @@ static int dce112_set_clock(
413 /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ 413 /*VBIOS will determine DPREFCLK frequency, so we don't set it*/
414 dce_clk_params.target_clock_frequency = 0; 414 dce_clk_params.target_clock_frequency = 0;
415 dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; 415 dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK;
416 dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = 416 if (!ASICREV_IS_VEGA20_P(clk->ctx->asic_id.hw_internal_rev))
417 dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK =
417 (dce_clk_params.pll_id == 418 (dce_clk_params.pll_id ==
418 CLOCK_SOURCE_COMBO_DISPLAY_PLL0); 419 CLOCK_SOURCE_COMBO_DISPLAY_PLL0);
420 else
421 dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = false;
419 422
420 bp->funcs->set_dce_clock(bp, &dce_clk_params); 423 bp->funcs->set_dce_clock(bp, &dce_clk_params);
421 424
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
index 2ee3d9bf1062..a576b8bbb3cd 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -28,7 +28,7 @@
28#include "dce_dmcu.h" 28#include "dce_dmcu.h"
29#include "dm_services.h" 29#include "dm_services.h"
30#include "reg_helper.h" 30#include "reg_helper.h"
31#include "fixed32_32.h" 31#include "fixed31_32.h"
32#include "dc.h" 32#include "dc.h"
33 33
34#define TO_DCE_DMCU(dmcu)\ 34#define TO_DCE_DMCU(dmcu)\
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
index 487724345d9d..0275d6d60da4 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
@@ -53,7 +53,8 @@ void dce_pipe_control_lock(struct dc *dc,
53 struct dce_hwseq *hws = dc->hwseq; 53 struct dce_hwseq *hws = dc->hwseq;
54 54
55 /* Not lock pipe when blank */ 55 /* Not lock pipe when blank */
56 if (lock && pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg)) 56 if (lock && pipe->stream_res.tg->funcs->is_blanked &&
57 pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg))
57 return; 58 return;
58 59
59 val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], 60 val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst],
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
index d737e911971b..5d9506b3d46b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
@@ -195,13 +195,13 @@ static void dce_ipp_program_input_lut(
195 195
196 for (i = 0; i < gamma->num_entries; i++) { 196 for (i = 0; i < gamma->num_entries; i++) {
197 REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR, 197 REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR,
198 dal_fixed31_32_round( 198 dc_fixpt_round(
199 gamma->entries.red[i])); 199 gamma->entries.red[i]));
200 REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR, 200 REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR,
201 dal_fixed31_32_round( 201 dc_fixpt_round(
202 gamma->entries.green[i])); 202 gamma->entries.green[i]));
203 REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR, 203 REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR,
204 dal_fixed31_32_round( 204 dc_fixpt_round(
205 gamma->entries.blue[i])); 205 gamma->entries.blue[i]));
206 } 206 }
207 207
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index 8167cad7bcf7..dbe3b26b6d9e 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -113,6 +113,7 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
113 .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe, 113 .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe,
114 .enable_hpd = dce110_link_encoder_enable_hpd, 114 .enable_hpd = dce110_link_encoder_enable_hpd,
115 .disable_hpd = dce110_link_encoder_disable_hpd, 115 .disable_hpd = dce110_link_encoder_disable_hpd,
116 .is_dig_enabled = dce110_is_dig_enabled,
116 .destroy = dce110_link_encoder_destroy 117 .destroy = dce110_link_encoder_destroy
117}; 118};
118 119
@@ -535,8 +536,9 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc,
535 DP_SEC_GSP0_PRIORITY, 1); 536 DP_SEC_GSP0_PRIORITY, 1);
536} 537}
537 538
538static bool is_dig_enabled(const struct dce110_link_encoder *enc110) 539bool dce110_is_dig_enabled(struct link_encoder *enc)
539{ 540{
541 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
540 uint32_t value; 542 uint32_t value;
541 543
542 REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value); 544 REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value);
@@ -1031,7 +1033,7 @@ void dce110_link_encoder_disable_output(
1031 struct bp_transmitter_control cntl = { 0 }; 1033 struct bp_transmitter_control cntl = { 0 };
1032 enum bp_result result; 1034 enum bp_result result;
1033 1035
1034 if (!is_dig_enabled(enc110)) { 1036 if (!dce110_is_dig_enabled(enc)) {
1035 /* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */ 1037 /* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */
1036 return; 1038 return;
1037 } 1039 }
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
index 0ec3433d34b6..347069461a22 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
@@ -263,4 +263,6 @@ void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
263void dce110_psr_program_secondary_packet(struct link_encoder *enc, 263void dce110_psr_program_secondary_packet(struct link_encoder *enc,
264 unsigned int sdp_transmit_line_num_deadline); 264 unsigned int sdp_transmit_line_num_deadline);
265 265
266bool dce110_is_dig_enabled(struct link_encoder *enc);
267
266#endif /* __DC_LINK_ENCODER__DCE110_H__ */ 268#endif /* __DC_LINK_ENCODER__DCE110_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
index 0790f25c7b3b..b235a75355b8 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
@@ -174,6 +174,25 @@ static void program_urgency_watermark(
174 URGENCY_HIGH_WATERMARK, urgency_high_wm); 174 URGENCY_HIGH_WATERMARK, urgency_high_wm);
175} 175}
176 176
177static void dce120_program_urgency_watermark(
178 struct dce_mem_input *dce_mi,
179 uint32_t wm_select,
180 uint32_t urgency_low_wm,
181 uint32_t urgency_high_wm)
182{
183 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
184 URGENCY_WATERMARK_MASK, wm_select);
185
186 REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
187 URGENCY_LOW_WATERMARK, urgency_low_wm,
188 URGENCY_HIGH_WATERMARK, urgency_high_wm);
189
190 REG_SET_2(DPG_PIPE_URGENT_LEVEL_CONTROL, 0,
191 URGENT_LEVEL_LOW_WATERMARK, urgency_low_wm,
192 URGENT_LEVEL_HIGH_WATERMARK, urgency_high_wm);
193
194}
195
177static void program_nbp_watermark( 196static void program_nbp_watermark(
178 struct dce_mem_input *dce_mi, 197 struct dce_mem_input *dce_mi,
179 uint32_t wm_select, 198 uint32_t wm_select,
@@ -206,6 +225,25 @@ static void program_nbp_watermark(
206 } 225 }
207} 226}
208 227
228static void dce120_program_stutter_watermark(
229 struct dce_mem_input *dce_mi,
230 uint32_t wm_select,
231 uint32_t stutter_mark,
232 uint32_t stutter_entry)
233{
234 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
235 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
236
237 if (REG(DPG_PIPE_STUTTER_CONTROL2))
238 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL2,
239 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
240 STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
241 else
242 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
243 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
244 STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
245}
246
209static void program_stutter_watermark( 247static void program_stutter_watermark(
210 struct dce_mem_input *dce_mi, 248 struct dce_mem_input *dce_mi,
211 uint32_t wm_select, 249 uint32_t wm_select,
@@ -225,7 +263,8 @@ static void program_stutter_watermark(
225static void dce_mi_program_display_marks( 263static void dce_mi_program_display_marks(
226 struct mem_input *mi, 264 struct mem_input *mi,
227 struct dce_watermarks nbp, 265 struct dce_watermarks nbp,
228 struct dce_watermarks stutter, 266 struct dce_watermarks stutter_exit,
267 struct dce_watermarks stutter_enter,
229 struct dce_watermarks urgent, 268 struct dce_watermarks urgent,
230 uint32_t total_dest_line_time_ns) 269 uint32_t total_dest_line_time_ns)
231{ 270{
@@ -243,13 +282,14 @@ static void dce_mi_program_display_marks(
243 program_nbp_watermark(dce_mi, 2, nbp.a_mark); /* set a */ 282 program_nbp_watermark(dce_mi, 2, nbp.a_mark); /* set a */
244 program_nbp_watermark(dce_mi, 1, nbp.d_mark); /* set d */ 283 program_nbp_watermark(dce_mi, 1, nbp.d_mark); /* set d */
245 284
246 program_stutter_watermark(dce_mi, 2, stutter.a_mark); /* set a */ 285 program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark); /* set a */
247 program_stutter_watermark(dce_mi, 1, stutter.d_mark); /* set d */ 286 program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark); /* set d */
248} 287}
249 288
250static void dce120_mi_program_display_marks(struct mem_input *mi, 289static void dce112_mi_program_display_marks(struct mem_input *mi,
251 struct dce_watermarks nbp, 290 struct dce_watermarks nbp,
252 struct dce_watermarks stutter, 291 struct dce_watermarks stutter_exit,
292 struct dce_watermarks stutter_entry,
253 struct dce_watermarks urgent, 293 struct dce_watermarks urgent,
254 uint32_t total_dest_line_time_ns) 294 uint32_t total_dest_line_time_ns)
255{ 295{
@@ -273,10 +313,43 @@ static void dce120_mi_program_display_marks(struct mem_input *mi,
273 program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */ 313 program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */
274 program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */ 314 program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */
275 315
276 program_stutter_watermark(dce_mi, 0, stutter.a_mark); /* set a */ 316 program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark); /* set a */
277 program_stutter_watermark(dce_mi, 1, stutter.b_mark); /* set b */ 317 program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark); /* set b */
278 program_stutter_watermark(dce_mi, 2, stutter.c_mark); /* set c */ 318 program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark); /* set c */
279 program_stutter_watermark(dce_mi, 3, stutter.d_mark); /* set d */ 319 program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark); /* set d */
320}
321
322static void dce120_mi_program_display_marks(struct mem_input *mi,
323 struct dce_watermarks nbp,
324 struct dce_watermarks stutter_exit,
325 struct dce_watermarks stutter_entry,
326 struct dce_watermarks urgent,
327 uint32_t total_dest_line_time_ns)
328{
329 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
330 uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
331
332 dce120_program_urgency_watermark(dce_mi, 0, /* set a */
333 urgent.a_mark, total_dest_line_time_ns);
334 dce120_program_urgency_watermark(dce_mi, 1, /* set b */
335 urgent.b_mark, total_dest_line_time_ns);
336 dce120_program_urgency_watermark(dce_mi, 2, /* set c */
337 urgent.c_mark, total_dest_line_time_ns);
338 dce120_program_urgency_watermark(dce_mi, 3, /* set d */
339 urgent.d_mark, total_dest_line_time_ns);
340
341 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
342 STUTTER_ENABLE, stutter_en,
343 STUTTER_IGNORE_FBC, 1);
344 program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */
345 program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */
346 program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */
347 program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */
348
349 dce120_program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark, stutter_entry.a_mark); /* set a */
350 dce120_program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark, stutter_entry.b_mark); /* set b */
351 dce120_program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark, stutter_entry.c_mark); /* set c */
352 dce120_program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark, stutter_entry.d_mark); /* set d */
280} 353}
281 354
282static void program_tiling( 355static void program_tiling(
@@ -696,5 +769,17 @@ void dce112_mem_input_construct(
696 const struct dce_mem_input_mask *mi_mask) 769 const struct dce_mem_input_mask *mi_mask)
697{ 770{
698 dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); 771 dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
772 dce_mi->base.funcs->mem_input_program_display_marks = dce112_mi_program_display_marks;
773}
774
775void dce120_mem_input_construct(
776 struct dce_mem_input *dce_mi,
777 struct dc_context *ctx,
778 int inst,
779 const struct dce_mem_input_registers *regs,
780 const struct dce_mem_input_shift *mi_shift,
781 const struct dce_mem_input_mask *mi_mask)
782{
783 dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
699 dce_mi->base.funcs->mem_input_program_display_marks = dce120_mi_program_display_marks; 784 dce_mi->base.funcs->mem_input_program_display_marks = dce120_mi_program_display_marks;
700} 785}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h
index 05d39c0cbe87..d15b0d7f47fc 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h
@@ -106,6 +106,7 @@ struct dce_mem_input_registers {
106 uint32_t DPG_PIPE_ARBITRATION_CONTROL1; 106 uint32_t DPG_PIPE_ARBITRATION_CONTROL1;
107 uint32_t DPG_WATERMARK_MASK_CONTROL; 107 uint32_t DPG_WATERMARK_MASK_CONTROL;
108 uint32_t DPG_PIPE_URGENCY_CONTROL; 108 uint32_t DPG_PIPE_URGENCY_CONTROL;
109 uint32_t DPG_PIPE_URGENT_LEVEL_CONTROL;
109 uint32_t DPG_PIPE_NB_PSTATE_CHANGE_CONTROL; 110 uint32_t DPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
110 uint32_t DPG_PIPE_LOW_POWER_CONTROL; 111 uint32_t DPG_PIPE_LOW_POWER_CONTROL;
111 uint32_t DPG_PIPE_STUTTER_CONTROL; 112 uint32_t DPG_PIPE_STUTTER_CONTROL;
@@ -213,6 +214,11 @@ struct dce_mem_input_registers {
213 214
214#define MI_DCE12_DMIF_PG_MASK_SH_LIST(mask_sh, blk)\ 215#define MI_DCE12_DMIF_PG_MASK_SH_LIST(mask_sh, blk)\
215 SFB(blk, DPG_PIPE_STUTTER_CONTROL2, STUTTER_EXIT_SELF_REFRESH_WATERMARK, mask_sh),\ 216 SFB(blk, DPG_PIPE_STUTTER_CONTROL2, STUTTER_EXIT_SELF_REFRESH_WATERMARK, mask_sh),\
217 SFB(blk, DPG_PIPE_STUTTER_CONTROL2, STUTTER_ENTER_SELF_REFRESH_WATERMARK, mask_sh),\
218 SFB(blk, DPG_PIPE_URGENT_LEVEL_CONTROL, URGENT_LEVEL_LOW_WATERMARK, mask_sh),\
219 SFB(blk, DPG_PIPE_URGENT_LEVEL_CONTROL, URGENT_LEVEL_HIGH_WATERMARK, mask_sh),\
220 SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_LOW_WATERMARK, mask_sh),\
221 SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_HIGH_WATERMARK, mask_sh),\
216 SFB(blk, DPG_WATERMARK_MASK_CONTROL, PSTATE_CHANGE_WATERMARK_MASK, mask_sh),\ 222 SFB(blk, DPG_WATERMARK_MASK_CONTROL, PSTATE_CHANGE_WATERMARK_MASK, mask_sh),\
217 SFB(blk, DPG_PIPE_LOW_POWER_CONTROL, PSTATE_CHANGE_ENABLE, mask_sh),\ 223 SFB(blk, DPG_PIPE_LOW_POWER_CONTROL, PSTATE_CHANGE_ENABLE, mask_sh),\
218 SFB(blk, DPG_PIPE_LOW_POWER_CONTROL, PSTATE_CHANGE_URGENT_DURING_REQUEST, mask_sh),\ 224 SFB(blk, DPG_PIPE_LOW_POWER_CONTROL, PSTATE_CHANGE_URGENT_DURING_REQUEST, mask_sh),\
@@ -286,6 +292,8 @@ struct dce_mem_input_registers {
286 type STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK; \ 292 type STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK; \
287 type URGENCY_LOW_WATERMARK; \ 293 type URGENCY_LOW_WATERMARK; \
288 type URGENCY_HIGH_WATERMARK; \ 294 type URGENCY_HIGH_WATERMARK; \
295 type URGENT_LEVEL_LOW_WATERMARK;\
296 type URGENT_LEVEL_HIGH_WATERMARK;\
289 type NB_PSTATE_CHANGE_ENABLE; \ 297 type NB_PSTATE_CHANGE_ENABLE; \
290 type NB_PSTATE_CHANGE_URGENT_DURING_REQUEST; \ 298 type NB_PSTATE_CHANGE_URGENT_DURING_REQUEST; \
291 type NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST; \ 299 type NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST; \
@@ -297,6 +305,7 @@ struct dce_mem_input_registers {
297 type STUTTER_ENABLE; \ 305 type STUTTER_ENABLE; \
298 type STUTTER_IGNORE_FBC; \ 306 type STUTTER_IGNORE_FBC; \
299 type STUTTER_EXIT_SELF_REFRESH_WATERMARK; \ 307 type STUTTER_EXIT_SELF_REFRESH_WATERMARK; \
308 type STUTTER_ENTER_SELF_REFRESH_WATERMARK; \
300 type DMIF_BUFFERS_ALLOCATED; \ 309 type DMIF_BUFFERS_ALLOCATED; \
301 type DMIF_BUFFERS_ALLOCATION_COMPLETED; \ 310 type DMIF_BUFFERS_ALLOCATION_COMPLETED; \
302 type ENABLE; /* MC_HUB_RDREQ_DMIF_LIMIT */\ 311 type ENABLE; /* MC_HUB_RDREQ_DMIF_LIMIT */\
@@ -344,4 +353,12 @@ void dce112_mem_input_construct(
344 const struct dce_mem_input_shift *mi_shift, 353 const struct dce_mem_input_shift *mi_shift,
345 const struct dce_mem_input_mask *mi_mask); 354 const struct dce_mem_input_mask *mi_mask);
346 355
356void dce120_mem_input_construct(
357 struct dce_mem_input *dce_mi,
358 struct dc_context *ctx,
359 int inst,
360 const struct dce_mem_input_registers *regs,
361 const struct dce_mem_input_shift *mi_shift,
362 const struct dce_mem_input_mask *mi_mask);
363
347#endif /*__DCE_MEM_INPUT_H__*/ 364#endif /*__DCE_MEM_INPUT_H__*/
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c b/drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c
index 6243450b41b7..48862bebf29e 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c
@@ -1014,11 +1014,11 @@ static const uint16_t filter_8tap_64p_183[264] = {
1014 1014
1015const uint16_t *get_filter_3tap_16p(struct fixed31_32 ratio) 1015const uint16_t *get_filter_3tap_16p(struct fixed31_32 ratio)
1016{ 1016{
1017 if (ratio.value < dal_fixed31_32_one.value) 1017 if (ratio.value < dc_fixpt_one.value)
1018 return filter_3tap_16p_upscale; 1018 return filter_3tap_16p_upscale;
1019 else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) 1019 else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
1020 return filter_3tap_16p_117; 1020 return filter_3tap_16p_117;
1021 else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) 1021 else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
1022 return filter_3tap_16p_150; 1022 return filter_3tap_16p_150;
1023 else 1023 else
1024 return filter_3tap_16p_183; 1024 return filter_3tap_16p_183;
@@ -1026,11 +1026,11 @@ const uint16_t *get_filter_3tap_16p(struct fixed31_32 ratio)
1026 1026
1027const uint16_t *get_filter_3tap_64p(struct fixed31_32 ratio) 1027const uint16_t *get_filter_3tap_64p(struct fixed31_32 ratio)
1028{ 1028{
1029 if (ratio.value < dal_fixed31_32_one.value) 1029 if (ratio.value < dc_fixpt_one.value)
1030 return filter_3tap_64p_upscale; 1030 return filter_3tap_64p_upscale;
1031 else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) 1031 else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
1032 return filter_3tap_64p_117; 1032 return filter_3tap_64p_117;
1033 else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) 1033 else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
1034 return filter_3tap_64p_150; 1034 return filter_3tap_64p_150;
1035 else 1035 else
1036 return filter_3tap_64p_183; 1036 return filter_3tap_64p_183;
@@ -1038,11 +1038,11 @@ const uint16_t *get_filter_3tap_64p(struct fixed31_32 ratio)
1038 1038
1039const uint16_t *get_filter_4tap_16p(struct fixed31_32 ratio) 1039const uint16_t *get_filter_4tap_16p(struct fixed31_32 ratio)
1040{ 1040{
1041 if (ratio.value < dal_fixed31_32_one.value) 1041 if (ratio.value < dc_fixpt_one.value)
1042 return filter_4tap_16p_upscale; 1042 return filter_4tap_16p_upscale;
1043 else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) 1043 else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
1044 return filter_4tap_16p_117; 1044 return filter_4tap_16p_117;
1045 else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) 1045 else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
1046 return filter_4tap_16p_150; 1046 return filter_4tap_16p_150;
1047 else 1047 else
1048 return filter_4tap_16p_183; 1048 return filter_4tap_16p_183;
@@ -1050,11 +1050,11 @@ const uint16_t *get_filter_4tap_16p(struct fixed31_32 ratio)
1050 1050
1051const uint16_t *get_filter_4tap_64p(struct fixed31_32 ratio) 1051const uint16_t *get_filter_4tap_64p(struct fixed31_32 ratio)
1052{ 1052{
1053 if (ratio.value < dal_fixed31_32_one.value) 1053 if (ratio.value < dc_fixpt_one.value)
1054 return filter_4tap_64p_upscale; 1054 return filter_4tap_64p_upscale;
1055 else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) 1055 else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
1056 return filter_4tap_64p_117; 1056 return filter_4tap_64p_117;
1057 else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) 1057 else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
1058 return filter_4tap_64p_150; 1058 return filter_4tap_64p_150;
1059 else 1059 else
1060 return filter_4tap_64p_183; 1060 return filter_4tap_64p_183;
@@ -1062,11 +1062,11 @@ const uint16_t *get_filter_4tap_64p(struct fixed31_32 ratio)
1062 1062
1063const uint16_t *get_filter_5tap_64p(struct fixed31_32 ratio) 1063const uint16_t *get_filter_5tap_64p(struct fixed31_32 ratio)
1064{ 1064{
1065 if (ratio.value < dal_fixed31_32_one.value) 1065 if (ratio.value < dc_fixpt_one.value)
1066 return filter_5tap_64p_upscale; 1066 return filter_5tap_64p_upscale;
1067 else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) 1067 else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
1068 return filter_5tap_64p_117; 1068 return filter_5tap_64p_117;
1069 else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) 1069 else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
1070 return filter_5tap_64p_150; 1070 return filter_5tap_64p_150;
1071 else 1071 else
1072 return filter_5tap_64p_183; 1072 return filter_5tap_64p_183;
@@ -1074,11 +1074,11 @@ const uint16_t *get_filter_5tap_64p(struct fixed31_32 ratio)
1074 1074
1075const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio) 1075const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio)
1076{ 1076{
1077 if (ratio.value < dal_fixed31_32_one.value) 1077 if (ratio.value < dc_fixpt_one.value)
1078 return filter_6tap_64p_upscale; 1078 return filter_6tap_64p_upscale;
1079 else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) 1079 else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
1080 return filter_6tap_64p_117; 1080 return filter_6tap_64p_117;
1081 else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) 1081 else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
1082 return filter_6tap_64p_150; 1082 return filter_6tap_64p_150;
1083 else 1083 else
1084 return filter_6tap_64p_183; 1084 return filter_6tap_64p_183;
@@ -1086,11 +1086,11 @@ const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio)
1086 1086
1087const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio) 1087const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio)
1088{ 1088{
1089 if (ratio.value < dal_fixed31_32_one.value) 1089 if (ratio.value < dc_fixpt_one.value)
1090 return filter_7tap_64p_upscale; 1090 return filter_7tap_64p_upscale;
1091 else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) 1091 else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
1092 return filter_7tap_64p_117; 1092 return filter_7tap_64p_117;
1093 else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) 1093 else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
1094 return filter_7tap_64p_150; 1094 return filter_7tap_64p_150;
1095 else 1095 else
1096 return filter_7tap_64p_183; 1096 return filter_7tap_64p_183;
@@ -1098,11 +1098,11 @@ const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio)
1098 1098
1099const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio) 1099const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio)
1100{ 1100{
1101 if (ratio.value < dal_fixed31_32_one.value) 1101 if (ratio.value < dc_fixpt_one.value)
1102 return filter_8tap_64p_upscale; 1102 return filter_8tap_64p_upscale;
1103 else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value) 1103 else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
1104 return filter_8tap_64p_117; 1104 return filter_8tap_64p_117;
1105 else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value) 1105 else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
1106 return filter_8tap_64p_150; 1106 return filter_8tap_64p_150;
1107 else 1107 else
1108 return filter_8tap_64p_183; 1108 return filter_8tap_64p_183;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
index 162f6a6c4208..0a6d483dc046 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
@@ -26,27 +26,10 @@
26#include "dc_bios_types.h" 26#include "dc_bios_types.h"
27#include "dce_stream_encoder.h" 27#include "dce_stream_encoder.h"
28#include "reg_helper.h" 28#include "reg_helper.h"
29#include "hw_shared.h"
30
29#define DC_LOGGER \ 31#define DC_LOGGER \
30 enc110->base.ctx->logger 32 enc110->base.ctx->logger
31enum DP_PIXEL_ENCODING {
32DP_PIXEL_ENCODING_RGB444 = 0x00000000,
33DP_PIXEL_ENCODING_YCBCR422 = 0x00000001,
34DP_PIXEL_ENCODING_YCBCR444 = 0x00000002,
35DP_PIXEL_ENCODING_RGB_WIDE_GAMUT = 0x00000003,
36DP_PIXEL_ENCODING_Y_ONLY = 0x00000004,
37DP_PIXEL_ENCODING_YCBCR420 = 0x00000005,
38DP_PIXEL_ENCODING_RESERVED = 0x00000006,
39};
40
41
42enum DP_COMPONENT_DEPTH {
43DP_COMPONENT_DEPTH_6BPC = 0x00000000,
44DP_COMPONENT_DEPTH_8BPC = 0x00000001,
45DP_COMPONENT_DEPTH_10BPC = 0x00000002,
46DP_COMPONENT_DEPTH_12BPC = 0x00000003,
47DP_COMPONENT_DEPTH_16BPC = 0x00000004,
48DP_COMPONENT_DEPTH_RESERVED = 0x00000005,
49};
50 33
51 34
52#define REG(reg)\ 35#define REG(reg)\
@@ -80,7 +63,7 @@ enum {
80static void dce110_update_generic_info_packet( 63static void dce110_update_generic_info_packet(
81 struct dce110_stream_encoder *enc110, 64 struct dce110_stream_encoder *enc110,
82 uint32_t packet_index, 65 uint32_t packet_index,
83 const struct encoder_info_packet *info_packet) 66 const struct dc_info_packet *info_packet)
84{ 67{
85 uint32_t regval; 68 uint32_t regval;
86 /* TODOFPGA Figure out a proper number for max_retries polling for lock 69 /* TODOFPGA Figure out a proper number for max_retries polling for lock
@@ -196,7 +179,7 @@ static void dce110_update_generic_info_packet(
196static void dce110_update_hdmi_info_packet( 179static void dce110_update_hdmi_info_packet(
197 struct dce110_stream_encoder *enc110, 180 struct dce110_stream_encoder *enc110,
198 uint32_t packet_index, 181 uint32_t packet_index,
199 const struct encoder_info_packet *info_packet) 182 const struct dc_info_packet *info_packet)
200{ 183{
201 uint32_t cont, send, line; 184 uint32_t cont, send, line;
202 185
@@ -314,11 +297,11 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
314 switch (crtc_timing->pixel_encoding) { 297 switch (crtc_timing->pixel_encoding) {
315 case PIXEL_ENCODING_YCBCR422: 298 case PIXEL_ENCODING_YCBCR422:
316 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 299 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
317 DP_PIXEL_ENCODING_YCBCR422); 300 DP_PIXEL_ENCODING_TYPE_YCBCR422);
318 break; 301 break;
319 case PIXEL_ENCODING_YCBCR444: 302 case PIXEL_ENCODING_YCBCR444:
320 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 303 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
321 DP_PIXEL_ENCODING_YCBCR444); 304 DP_PIXEL_ENCODING_TYPE_YCBCR444);
322 305
323 if (crtc_timing->flags.Y_ONLY) 306 if (crtc_timing->flags.Y_ONLY)
324 if (crtc_timing->display_color_depth != COLOR_DEPTH_666) 307 if (crtc_timing->display_color_depth != COLOR_DEPTH_666)
@@ -326,7 +309,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
326 * Color depth of Y-only could be 309 * Color depth of Y-only could be
327 * 8, 10, 12, 16 bits */ 310 * 8, 10, 12, 16 bits */
328 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 311 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
329 DP_PIXEL_ENCODING_Y_ONLY); 312 DP_PIXEL_ENCODING_TYPE_Y_ONLY);
330 /* Note: DP_MSA_MISC1 bit 7 is the indicator 313 /* Note: DP_MSA_MISC1 bit 7 is the indicator
331 * of Y-only mode. 314 * of Y-only mode.
332 * This bit is set in HW if register 315 * This bit is set in HW if register
@@ -334,7 +317,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
334 break; 317 break;
335 case PIXEL_ENCODING_YCBCR420: 318 case PIXEL_ENCODING_YCBCR420:
336 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 319 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
337 DP_PIXEL_ENCODING_YCBCR420); 320 DP_PIXEL_ENCODING_TYPE_YCBCR420);
338 if (enc110->se_mask->DP_VID_M_DOUBLE_VALUE_EN) 321 if (enc110->se_mask->DP_VID_M_DOUBLE_VALUE_EN)
339 REG_UPDATE(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, 1); 322 REG_UPDATE(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, 1);
340 323
@@ -345,7 +328,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
345 break; 328 break;
346 default: 329 default:
347 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 330 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
348 DP_PIXEL_ENCODING_RGB444); 331 DP_PIXEL_ENCODING_TYPE_RGB444);
349 break; 332 break;
350 } 333 }
351 334
@@ -363,20 +346,20 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
363 break; 346 break;
364 case COLOR_DEPTH_888: 347 case COLOR_DEPTH_888:
365 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 348 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,
366 DP_COMPONENT_DEPTH_8BPC); 349 DP_COMPONENT_PIXEL_DEPTH_8BPC);
367 break; 350 break;
368 case COLOR_DEPTH_101010: 351 case COLOR_DEPTH_101010:
369 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 352 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,
370 DP_COMPONENT_DEPTH_10BPC); 353 DP_COMPONENT_PIXEL_DEPTH_10BPC);
371 354
372 break; 355 break;
373 case COLOR_DEPTH_121212: 356 case COLOR_DEPTH_121212:
374 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 357 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,
375 DP_COMPONENT_DEPTH_12BPC); 358 DP_COMPONENT_PIXEL_DEPTH_12BPC);
376 break; 359 break;
377 default: 360 default:
378 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 361 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,
379 DP_COMPONENT_DEPTH_6BPC); 362 DP_COMPONENT_PIXEL_DEPTH_6BPC);
380 break; 363 break;
381 } 364 }
382 365
@@ -700,11 +683,11 @@ static void dce110_stream_encoder_set_mst_bandwidth(
700 struct fixed31_32 avg_time_slots_per_mtp) 683 struct fixed31_32 avg_time_slots_per_mtp)
701{ 684{
702 struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); 685 struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
703 uint32_t x = dal_fixed31_32_floor( 686 uint32_t x = dc_fixpt_floor(
704 avg_time_slots_per_mtp); 687 avg_time_slots_per_mtp);
705 uint32_t y = dal_fixed31_32_ceil( 688 uint32_t y = dc_fixpt_ceil(
706 dal_fixed31_32_shl( 689 dc_fixpt_shl(
707 dal_fixed31_32_sub_int( 690 dc_fixpt_sub_int(
708 avg_time_slots_per_mtp, 691 avg_time_slots_per_mtp,
709 x), 692 x),
710 26)); 693 26));
@@ -836,7 +819,7 @@ static void dce110_stream_encoder_update_dp_info_packets(
836 const struct encoder_info_frame *info_frame) 819 const struct encoder_info_frame *info_frame)
837{ 820{
838 struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); 821 struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
839 uint32_t value = REG_READ(DP_SEC_CNTL); 822 uint32_t value = 0;
840 823
841 if (info_frame->vsc.valid) 824 if (info_frame->vsc.valid)
842 dce110_update_generic_info_packet( 825 dce110_update_generic_info_packet(
@@ -870,6 +853,7 @@ static void dce110_stream_encoder_update_dp_info_packets(
870 * Therefore we need to enable master bit 853 * Therefore we need to enable master bit
871 * if at least on of the fields is not 0 854 * if at least on of the fields is not 0
872 */ 855 */
856 value = REG_READ(DP_SEC_CNTL);
873 if (value) 857 if (value)
874 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); 858 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
875} 859}
@@ -879,7 +863,7 @@ static void dce110_stream_encoder_stop_dp_info_packets(
879{ 863{
880 /* stop generic packets on DP */ 864 /* stop generic packets on DP */
881 struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); 865 struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
882 uint32_t value = REG_READ(DP_SEC_CNTL); 866 uint32_t value = 0;
883 867
884 if (enc110->se_mask->DP_SEC_AVI_ENABLE) { 868 if (enc110->se_mask->DP_SEC_AVI_ENABLE) {
885 REG_SET_7(DP_SEC_CNTL, 0, 869 REG_SET_7(DP_SEC_CNTL, 0,
@@ -892,25 +876,10 @@ static void dce110_stream_encoder_stop_dp_info_packets(
892 DP_SEC_STREAM_ENABLE, 0); 876 DP_SEC_STREAM_ENABLE, 0);
893 } 877 }
894 878
895#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
896 if (enc110->se_mask->DP_SEC_GSP7_ENABLE) {
897 REG_SET_10(DP_SEC_CNTL, 0,
898 DP_SEC_GSP0_ENABLE, 0,
899 DP_SEC_GSP1_ENABLE, 0,
900 DP_SEC_GSP2_ENABLE, 0,
901 DP_SEC_GSP3_ENABLE, 0,
902 DP_SEC_GSP4_ENABLE, 0,
903 DP_SEC_GSP5_ENABLE, 0,
904 DP_SEC_GSP6_ENABLE, 0,
905 DP_SEC_GSP7_ENABLE, 0,
906 DP_SEC_MPG_ENABLE, 0,
907 DP_SEC_STREAM_ENABLE, 0);
908 }
909#endif
910 /* this register shared with audio info frame. 879 /* this register shared with audio info frame.
911 * therefore we need to keep master enabled 880 * therefore we need to keep master enabled
912 * if at least one of the fields is not 0 */ 881 * if at least one of the fields is not 0 */
913 882 value = REG_READ(DP_SEC_CNTL);
914 if (value) 883 if (value)
915 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); 884 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
916 885
@@ -1513,7 +1482,7 @@ static void dce110_se_disable_dp_audio(
1513 struct stream_encoder *enc) 1482 struct stream_encoder *enc)
1514{ 1483{
1515 struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); 1484 struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
1516 uint32_t value = REG_READ(DP_SEC_CNTL); 1485 uint32_t value = 0;
1517 1486
1518 /* Disable Audio packets */ 1487 /* Disable Audio packets */
1519 REG_UPDATE_5(DP_SEC_CNTL, 1488 REG_UPDATE_5(DP_SEC_CNTL,
@@ -1525,6 +1494,7 @@ static void dce110_se_disable_dp_audio(
1525 1494
1526 /* This register shared with encoder info frame. Therefore we need to 1495 /* This register shared with encoder info frame. Therefore we need to
1527 keep master enabled if at least on of the fields is not 0 */ 1496 keep master enabled if at least on of the fields is not 0 */
1497 value = REG_READ(DP_SEC_CNTL);
1528 if (value != 0) 1498 if (value != 0)
1529 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); 1499 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
1530 1500
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
index 832c5daada35..a02e719d7794 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
@@ -41,7 +41,7 @@
41#define DC_LOGGER \ 41#define DC_LOGGER \
42 xfm_dce->base.ctx->logger 42 xfm_dce->base.ctx->logger
43 43
44#define IDENTITY_RATIO(ratio) (dal_fixed31_32_u2d19(ratio) == (1 << 19)) 44#define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19))
45#define GAMUT_MATRIX_SIZE 12 45#define GAMUT_MATRIX_SIZE 12
46#define SCL_PHASES 16 46#define SCL_PHASES 16
47 47
@@ -256,27 +256,27 @@ static void calculate_inits(
256 struct fixed31_32 v_init; 256 struct fixed31_32 v_init;
257 257
258 inits->h_int_scale_ratio = 258 inits->h_int_scale_ratio =
259 dal_fixed31_32_u2d19(data->ratios.horz) << 5; 259 dc_fixpt_u2d19(data->ratios.horz) << 5;
260 inits->v_int_scale_ratio = 260 inits->v_int_scale_ratio =
261 dal_fixed31_32_u2d19(data->ratios.vert) << 5; 261 dc_fixpt_u2d19(data->ratios.vert) << 5;
262 262
263 h_init = 263 h_init =
264 dal_fixed31_32_div_int( 264 dc_fixpt_div_int(
265 dal_fixed31_32_add( 265 dc_fixpt_add(
266 data->ratios.horz, 266 data->ratios.horz,
267 dal_fixed31_32_from_int(data->taps.h_taps + 1)), 267 dc_fixpt_from_int(data->taps.h_taps + 1)),
268 2); 268 2);
269 inits->h_init.integer = dal_fixed31_32_floor(h_init); 269 inits->h_init.integer = dc_fixpt_floor(h_init);
270 inits->h_init.fraction = dal_fixed31_32_u0d19(h_init) << 5; 270 inits->h_init.fraction = dc_fixpt_u0d19(h_init) << 5;
271 271
272 v_init = 272 v_init =
273 dal_fixed31_32_div_int( 273 dc_fixpt_div_int(
274 dal_fixed31_32_add( 274 dc_fixpt_add(
275 data->ratios.vert, 275 data->ratios.vert,
276 dal_fixed31_32_from_int(data->taps.v_taps + 1)), 276 dc_fixpt_from_int(data->taps.v_taps + 1)),
277 2); 277 2);
278 inits->v_init.integer = dal_fixed31_32_floor(v_init); 278 inits->v_init.integer = dc_fixpt_floor(v_init);
279 inits->v_init.fraction = dal_fixed31_32_u0d19(v_init) << 5; 279 inits->v_init.fraction = dc_fixpt_u0d19(v_init) << 5;
280} 280}
281 281
282static void program_scl_ratios_inits( 282static void program_scl_ratios_inits(
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
index 3092f76bdb75..38ec0d609297 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
@@ -733,38 +733,6 @@ enum dc_status dce100_add_stream_to_ctx(
733 return result; 733 return result;
734} 734}
735 735
736enum dc_status dce100_validate_guaranteed(
737 struct dc *dc,
738 struct dc_stream_state *dc_stream,
739 struct dc_state *context)
740{
741 enum dc_status result = DC_ERROR_UNEXPECTED;
742
743 context->streams[0] = dc_stream;
744 dc_stream_retain(context->streams[0]);
745 context->stream_count++;
746
747 result = resource_map_pool_resources(dc, context, dc_stream);
748
749 if (result == DC_OK)
750 result = resource_map_clock_resources(dc, context, dc_stream);
751
752 if (result == DC_OK)
753 result = build_mapped_resource(dc, context, dc_stream);
754
755 if (result == DC_OK) {
756 validate_guaranteed_copy_streams(
757 context, dc->caps.max_streams);
758 result = resource_build_scaling_params_for_context(dc, context);
759 }
760
761 if (result == DC_OK)
762 if (!dce100_validate_bandwidth(dc, context))
763 result = DC_FAIL_BANDWIDTH_VALIDATE;
764
765 return result;
766}
767
768static void dce100_destroy_resource_pool(struct resource_pool **pool) 736static void dce100_destroy_resource_pool(struct resource_pool **pool)
769{ 737{
770 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool); 738 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
@@ -786,7 +754,6 @@ enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, s
786static const struct resource_funcs dce100_res_pool_funcs = { 754static const struct resource_funcs dce100_res_pool_funcs = {
787 .destroy = dce100_destroy_resource_pool, 755 .destroy = dce100_destroy_resource_pool,
788 .link_enc_create = dce100_link_encoder_create, 756 .link_enc_create = dce100_link_encoder_create,
789 .validate_guaranteed = dce100_validate_guaranteed,
790 .validate_bandwidth = dce100_validate_bandwidth, 757 .validate_bandwidth = dce100_validate_bandwidth,
791 .validate_plane = dce100_validate_plane, 758 .validate_plane = dce100_validate_plane,
792 .add_stream_to_ctx = dce100_add_stream_to_ctx, 759 .add_stream_to_ctx = dce100_add_stream_to_ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index d0575999f172..a92fb0aa2ff3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -70,8 +70,9 @@
70 70
71#define CTX \ 71#define CTX \
72 hws->ctx 72 hws->ctx
73#define DC_LOGGER \ 73
74 ctx->logger 74#define DC_LOGGER_INIT()
75
75#define REG(reg)\ 76#define REG(reg)\
76 hws->regs->reg 77 hws->regs->reg
77 78
@@ -279,7 +280,9 @@ dce110_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
279 build_prescale_params(&prescale_params, plane_state); 280 build_prescale_params(&prescale_params, plane_state);
280 ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 281 ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
281 282
282 if (plane_state->gamma_correction && dce_use_lut(plane_state->format)) 283 if (plane_state->gamma_correction &&
284 !plane_state->gamma_correction->is_identity &&
285 dce_use_lut(plane_state->format))
283 ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction); 286 ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction);
284 287
285 if (tf == NULL) { 288 if (tf == NULL) {
@@ -506,19 +509,19 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
506 rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 509 rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
507 rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 510 rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
508 511
509 arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 512 arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2),
510 dal_fixed31_32_from_int(region_start)); 513 dc_fixpt_from_int(region_start));
511 arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 514 arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2),
512 dal_fixed31_32_from_int(region_end)); 515 dc_fixpt_from_int(region_end));
513 516
514 y_r = rgb_resulted[0].red; 517 y_r = rgb_resulted[0].red;
515 y_g = rgb_resulted[0].green; 518 y_g = rgb_resulted[0].green;
516 y_b = rgb_resulted[0].blue; 519 y_b = rgb_resulted[0].blue;
517 520
518 y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b)); 521 y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b));
519 522
520 arr_points[0].y = y1_min; 523 arr_points[0].y = y1_min;
521 arr_points[0].slope = dal_fixed31_32_div(arr_points[0].y, 524 arr_points[0].slope = dc_fixpt_div(arr_points[0].y,
522 arr_points[0].x); 525 arr_points[0].x);
523 526
524 y_r = rgb_resulted[hw_points - 1].red; 527 y_r = rgb_resulted[hw_points - 1].red;
@@ -528,21 +531,21 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
528 /* see comment above, m_arrPoints[1].y should be the Y value for the 531 /* see comment above, m_arrPoints[1].y should be the Y value for the
529 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 532 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
530 */ 533 */
531 y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b)); 534 y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b));
532 535
533 arr_points[1].y = y3_max; 536 arr_points[1].y = y3_max;
534 537
535 arr_points[1].slope = dal_fixed31_32_zero; 538 arr_points[1].slope = dc_fixpt_zero;
536 539
537 if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 540 if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
538 /* for PQ, we want to have a straight line from last HW X point, 541 /* for PQ, we want to have a straight line from last HW X point,
539 * and the slope to be such that we hit 1.0 at 10000 nits. 542 * and the slope to be such that we hit 1.0 at 10000 nits.
540 */ 543 */
541 const struct fixed31_32 end_value = dal_fixed31_32_from_int(125); 544 const struct fixed31_32 end_value = dc_fixpt_from_int(125);
542 545
543 arr_points[1].slope = dal_fixed31_32_div( 546 arr_points[1].slope = dc_fixpt_div(
544 dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 547 dc_fixpt_sub(dc_fixpt_one, arr_points[1].y),
545 dal_fixed31_32_sub(end_value, arr_points[1].x)); 548 dc_fixpt_sub(end_value, arr_points[1].x));
546 } 549 }
547 550
548 regamma_params->hw_points_num = hw_points; 551 regamma_params->hw_points_num = hw_points;
@@ -566,16 +569,16 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
566 i = 1; 569 i = 1;
567 570
568 while (i != hw_points + 1) { 571 while (i != hw_points + 1) {
569 if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red)) 572 if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
570 rgb_plus_1->red = rgb->red; 573 rgb_plus_1->red = rgb->red;
571 if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green)) 574 if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
572 rgb_plus_1->green = rgb->green; 575 rgb_plus_1->green = rgb->green;
573 if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue)) 576 if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
574 rgb_plus_1->blue = rgb->blue; 577 rgb_plus_1->blue = rgb->blue;
575 578
576 rgb->delta_red = dal_fixed31_32_sub(rgb_plus_1->red, rgb->red); 579 rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
577 rgb->delta_green = dal_fixed31_32_sub(rgb_plus_1->green, rgb->green); 580 rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
578 rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue); 581 rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
579 582
580 ++rgb_plus_1; 583 ++rgb_plus_1;
581 ++rgb; 584 ++rgb;
@@ -851,6 +854,28 @@ void hwss_edp_power_control(
851 854
852 if (power_up != is_panel_powered_on(hwseq)) { 855 if (power_up != is_panel_powered_on(hwseq)) {
853 /* Send VBIOS command to prompt eDP panel power */ 856 /* Send VBIOS command to prompt eDP panel power */
857 if (power_up) {
858 unsigned long long current_ts = dm_get_timestamp(ctx);
859 unsigned long long duration_in_ms =
860 dm_get_elapse_time_in_ns(
861 ctx,
862 current_ts,
863 div64_u64(link->link_trace.time_stamp.edp_poweroff, 1000000));
864 unsigned long long wait_time_ms = 0;
865
866 /* max 500ms from LCDVDD off to on */
867 if (link->link_trace.time_stamp.edp_poweroff == 0)
868 wait_time_ms = 500;
869 else if (duration_in_ms < 500)
870 wait_time_ms = 500 - duration_in_ms;
871
872 if (wait_time_ms) {
873 msleep(wait_time_ms);
874 dm_output_to_console("%s: wait %lld ms to power on eDP.\n",
875 __func__, wait_time_ms);
876 }
877
878 }
854 879
855 DC_LOG_HW_RESUME_S3( 880 DC_LOG_HW_RESUME_S3(
856 "%s: Panel Power action: %s\n", 881 "%s: Panel Power action: %s\n",
@@ -864,9 +889,14 @@ void hwss_edp_power_control(
864 cntl.coherent = false; 889 cntl.coherent = false;
865 cntl.lanes_number = LANE_COUNT_FOUR; 890 cntl.lanes_number = LANE_COUNT_FOUR;
866 cntl.hpd_sel = link->link_enc->hpd_source; 891 cntl.hpd_sel = link->link_enc->hpd_source;
867
868 bp_result = link_transmitter_control(ctx->dc_bios, &cntl); 892 bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
869 893
894 if (!power_up)
895 /*save driver power off time stamp*/
896 link->link_trace.time_stamp.edp_poweroff = dm_get_timestamp(ctx);
897 else
898 link->link_trace.time_stamp.edp_poweron = dm_get_timestamp(ctx);
899
870 if (bp_result != BP_RESULT_OK) 900 if (bp_result != BP_RESULT_OK)
871 DC_LOG_ERROR( 901 DC_LOG_ERROR(
872 "%s: Panel Power bp_result: %d\n", 902 "%s: Panel Power bp_result: %d\n",
@@ -1011,7 +1041,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
1011 1041
1012 if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1042 if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
1013 link->dc->hwss.edp_backlight_control(link, true); 1043 link->dc->hwss.edp_backlight_control(link, true);
1014 stream->bl_pwm_level = 0; 1044 stream->bl_pwm_level = EDP_BACKLIGHT_RAMP_DISABLE_LEVEL;
1015 } 1045 }
1016} 1046}
1017void dce110_blank_stream(struct pipe_ctx *pipe_ctx) 1047void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
@@ -1203,7 +1233,7 @@ static void program_scaler(const struct dc *dc,
1203 &pipe_ctx->plane_res.scl_data); 1233 &pipe_ctx->plane_res.scl_data);
1204} 1234}
1205 1235
1206static enum dc_status dce110_prog_pixclk_crtc_otg( 1236static enum dc_status dce110_enable_stream_timing(
1207 struct pipe_ctx *pipe_ctx, 1237 struct pipe_ctx *pipe_ctx,
1208 struct dc_state *context, 1238 struct dc_state *context,
1209 struct dc *dc) 1239 struct dc *dc)
@@ -1269,7 +1299,7 @@ static enum dc_status apply_single_controller_ctx_to_hw(
1269 pipe_ctx[pipe_ctx->pipe_idx]; 1299 pipe_ctx[pipe_ctx->pipe_idx];
1270 1300
1271 /* */ 1301 /* */
1272 dc->hwss.prog_pixclk_crtc_otg(pipe_ctx, context, dc); 1302 dc->hwss.enable_stream_timing(pipe_ctx, context, dc);
1273 1303
1274 /* FPGA does not program backend */ 1304 /* FPGA does not program backend */
1275 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 1305 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
@@ -1441,6 +1471,17 @@ static void disable_vga_and_power_gate_all_controllers(
1441 } 1471 }
1442} 1472}
1443 1473
1474static struct dc_link *get_link_for_edp(struct dc *dc)
1475{
1476 int i;
1477
1478 for (i = 0; i < dc->link_count; i++) {
1479 if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP)
1480 return dc->links[i];
1481 }
1482 return NULL;
1483}
1484
1444static struct dc_link *get_link_for_edp_not_in_use( 1485static struct dc_link *get_link_for_edp_not_in_use(
1445 struct dc *dc, 1486 struct dc *dc,
1446 struct dc_state *context) 1487 struct dc_state *context)
@@ -1475,20 +1516,21 @@ static struct dc_link *get_link_for_edp_not_in_use(
1475 */ 1516 */
1476void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) 1517void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
1477{ 1518{
1478 struct dc_bios *dcb = dc->ctx->dc_bios;
1479
1480 /* vbios already light up eDP, so we can leverage vbios and skip eDP
1481 * programming
1482 */
1483 bool can_eDP_fast_boot_optimize =
1484 (dcb->funcs->get_vga_enabled_displays(dc->ctx->dc_bios) == ATOM_DISPLAY_LCD1_ACTIVE);
1485
1486 /* if OS doesn't light up eDP and eDP link is available, we want to disable */
1487 struct dc_link *edp_link_to_turnoff = NULL; 1519 struct dc_link *edp_link_to_turnoff = NULL;
1520 struct dc_link *edp_link = get_link_for_edp(dc);
1521 bool can_eDP_fast_boot_optimize = false;
1522
1523 if (edp_link) {
1524 can_eDP_fast_boot_optimize =
1525 edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc);
1526 }
1488 1527
1489 if (can_eDP_fast_boot_optimize) { 1528 if (can_eDP_fast_boot_optimize) {
1490 edp_link_to_turnoff = get_link_for_edp_not_in_use(dc, context); 1529 edp_link_to_turnoff = get_link_for_edp_not_in_use(dc, context);
1491 1530
1531 /* if OS doesn't light up eDP and eDP link is available, we want to disable
1532 * If resume from S4/S5, should optimization.
1533 */
1492 if (!edp_link_to_turnoff) 1534 if (!edp_link_to_turnoff)
1493 dc->apply_edp_fast_boot_optimization = true; 1535 dc->apply_edp_fast_boot_optimization = true;
1494 } 1536 }
@@ -1544,6 +1586,7 @@ static void dce110_set_displaymarks(
1544 pipe_ctx->plane_res.mi, 1586 pipe_ctx->plane_res.mi,
1545 context->bw.dce.nbp_state_change_wm_ns[num_pipes], 1587 context->bw.dce.nbp_state_change_wm_ns[num_pipes],
1546 context->bw.dce.stutter_exit_wm_ns[num_pipes], 1588 context->bw.dce.stutter_exit_wm_ns[num_pipes],
1589 context->bw.dce.stutter_entry_wm_ns[num_pipes],
1547 context->bw.dce.urgent_wm_ns[num_pipes], 1590 context->bw.dce.urgent_wm_ns[num_pipes],
1548 total_dest_line_time_ns); 1591 total_dest_line_time_ns);
1549 if (i == underlay_idx) { 1592 if (i == underlay_idx) {
@@ -1569,6 +1612,7 @@ static void set_safe_displaymarks(
1569 MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 1612 MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK };
1570 struct dce_watermarks nbp_marks = { 1613 struct dce_watermarks nbp_marks = {
1571 SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 1614 SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
1615 struct dce_watermarks min_marks = { 0, 0, 0, 0};
1572 1616
1573 for (i = 0; i < MAX_PIPES; i++) { 1617 for (i = 0; i < MAX_PIPES; i++) {
1574 if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL) 1618 if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
@@ -1578,6 +1622,7 @@ static void set_safe_displaymarks(
1578 res_ctx->pipe_ctx[i].plane_res.mi, 1622 res_ctx->pipe_ctx[i].plane_res.mi,
1579 nbp_marks, 1623 nbp_marks,
1580 max_marks, 1624 max_marks,
1625 min_marks,
1581 max_marks, 1626 max_marks,
1582 MAX_WATERMARK); 1627 MAX_WATERMARK);
1583 1628
@@ -1803,6 +1848,9 @@ static bool should_enable_fbc(struct dc *dc,
1803 } 1848 }
1804 } 1849 }
1805 1850
1851 /* Pipe context should be found */
1852 ASSERT(pipe_ctx);
1853
1806 /* Only supports eDP */ 1854 /* Only supports eDP */
1807 if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP) 1855 if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP)
1808 return false; 1856 return false;
@@ -2221,74 +2269,6 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
2221 2269
2222 pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 2270 pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
2223} 2271}
2224
2225/**
2226 * TODO REMOVE, USE UPDATE INSTEAD
2227 */
2228static void set_plane_config(
2229 const struct dc *dc,
2230 struct pipe_ctx *pipe_ctx,
2231 struct resource_context *res_ctx)
2232{
2233 struct mem_input *mi = pipe_ctx->plane_res.mi;
2234 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
2235 struct xfm_grph_csc_adjustment adjust;
2236 struct out_csc_color_matrix tbl_entry;
2237 unsigned int i;
2238
2239 memset(&adjust, 0, sizeof(adjust));
2240 memset(&tbl_entry, 0, sizeof(tbl_entry));
2241 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
2242
2243 dce_enable_fe_clock(dc->hwseq, mi->inst, true);
2244
2245 set_default_colors(pipe_ctx);
2246 if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
2247 tbl_entry.color_space =
2248 pipe_ctx->stream->output_color_space;
2249
2250 for (i = 0; i < 12; i++)
2251 tbl_entry.regval[i] =
2252 pipe_ctx->stream->csc_color_matrix.matrix[i];
2253
2254 pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment
2255 (pipe_ctx->plane_res.xfm, &tbl_entry);
2256 }
2257
2258 if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
2259 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
2260
2261 for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
2262 adjust.temperature_matrix[i] =
2263 pipe_ctx->stream->gamut_remap_matrix.matrix[i];
2264 }
2265
2266 pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
2267
2268 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
2269 program_scaler(dc, pipe_ctx);
2270
2271 program_surface_visibility(dc, pipe_ctx);
2272
2273 mi->funcs->mem_input_program_surface_config(
2274 mi,
2275 plane_state->format,
2276 &plane_state->tiling_info,
2277 &plane_state->plane_size,
2278 plane_state->rotation,
2279 NULL,
2280 false);
2281 if (mi->funcs->set_blank)
2282 mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);
2283
2284 if (dc->config.gpu_vm_support)
2285 mi->funcs->mem_input_program_pte_vm(
2286 pipe_ctx->plane_res.mi,
2287 plane_state->format,
2288 &plane_state->tiling_info,
2289 plane_state->rotation);
2290}
2291
2292static void update_plane_addr(const struct dc *dc, 2272static void update_plane_addr(const struct dc *dc,
2293 struct pipe_ctx *pipe_ctx) 2273 struct pipe_ctx *pipe_ctx)
2294{ 2274{
@@ -2699,8 +2679,11 @@ static void dce110_program_front_end_for_pipe(
2699 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 2679 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
2700 struct xfm_grph_csc_adjustment adjust; 2680 struct xfm_grph_csc_adjustment adjust;
2701 struct out_csc_color_matrix tbl_entry; 2681 struct out_csc_color_matrix tbl_entry;
2682#if defined(CONFIG_DRM_AMD_DC_FBC)
2683 unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
2684#endif
2702 unsigned int i; 2685 unsigned int i;
2703 struct dc_context *ctx = dc->ctx; 2686 DC_LOGGER_INIT();
2704 memset(&tbl_entry, 0, sizeof(tbl_entry)); 2687 memset(&tbl_entry, 0, sizeof(tbl_entry));
2705 2688
2706 if (dc->current_state) 2689 if (dc->current_state)
@@ -2740,7 +2723,9 @@ static void dce110_program_front_end_for_pipe(
2740 program_scaler(dc, pipe_ctx); 2723 program_scaler(dc, pipe_ctx);
2741 2724
2742#if defined(CONFIG_DRM_AMD_DC_FBC) 2725#if defined(CONFIG_DRM_AMD_DC_FBC)
2743 if (dc->fbc_compressor && old_pipe->stream) { 2726 /* fbc not applicable on Underlay pipe */
2727 if (dc->fbc_compressor && old_pipe->stream &&
2728 pipe_ctx->pipe_idx != underlay_idx) {
2744 if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 2729 if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
2745 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 2730 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
2746 else 2731 else
@@ -2776,13 +2761,13 @@ static void dce110_program_front_end_for_pipe(
2776 dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); 2761 dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream);
2777 2762
2778 DC_LOG_SURFACE( 2763 DC_LOG_SURFACE(
2779 "Pipe:%d 0x%x: addr hi:0x%x, " 2764 "Pipe:%d %p: addr hi:0x%x, "
2780 "addr low:0x%x, " 2765 "addr low:0x%x, "
2781 "src: %d, %d, %d," 2766 "src: %d, %d, %d,"
2782 " %d; dst: %d, %d, %d, %d;" 2767 " %d; dst: %d, %d, %d, %d;"
2783 "clip: %d, %d, %d, %d\n", 2768 "clip: %d, %d, %d, %d\n",
2784 pipe_ctx->pipe_idx, 2769 pipe_ctx->pipe_idx,
2785 pipe_ctx->plane_state, 2770 (void *) pipe_ctx->plane_state,
2786 pipe_ctx->plane_state->address.grph.addr.high_part, 2771 pipe_ctx->plane_state->address.grph.addr.high_part,
2787 pipe_ctx->plane_state->address.grph.addr.low_part, 2772 pipe_ctx->plane_state->address.grph.addr.low_part,
2788 pipe_ctx->plane_state->src_rect.x, 2773 pipe_ctx->plane_state->src_rect.x,
@@ -2970,7 +2955,6 @@ static const struct hw_sequencer_funcs dce110_funcs = {
2970 .init_hw = init_hw, 2955 .init_hw = init_hw,
2971 .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 2956 .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
2972 .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 2957 .apply_ctx_for_surface = dce110_apply_ctx_for_surface,
2973 .set_plane_config = set_plane_config,
2974 .update_plane_addr = update_plane_addr, 2958 .update_plane_addr = update_plane_addr,
2975 .update_pending_status = dce110_update_pending_status, 2959 .update_pending_status = dce110_update_pending_status,
2976 .set_input_transfer_func = dce110_set_input_transfer_func, 2960 .set_input_transfer_func = dce110_set_input_transfer_func,
@@ -2993,7 +2977,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
2993 .get_position = get_position, 2977 .get_position = get_position,
2994 .set_static_screen_control = set_static_screen_control, 2978 .set_static_screen_control = set_static_screen_control,
2995 .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, 2979 .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap,
2996 .prog_pixclk_crtc_otg = dce110_prog_pixclk_crtc_otg, 2980 .enable_stream_timing = dce110_enable_stream_timing,
2997 .setup_stereo = NULL, 2981 .setup_stereo = NULL,
2998 .set_avmute = dce110_set_avmute, 2982 .set_avmute = dce110_set_avmute,
2999 .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, 2983 .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
index 7bab8c6d2a73..0564c8e31252 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
@@ -923,6 +923,7 @@ void dce_mem_input_v_program_display_marks(
923 struct mem_input *mem_input, 923 struct mem_input *mem_input,
924 struct dce_watermarks nbp, 924 struct dce_watermarks nbp,
925 struct dce_watermarks stutter, 925 struct dce_watermarks stutter,
926 struct dce_watermarks stutter_enter,
926 struct dce_watermarks urgent, 927 struct dce_watermarks urgent,
927 uint32_t total_dest_line_time_ns) 928 uint32_t total_dest_line_time_ns)
928{ 929{
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
index b1f14be20fdf..ee33786bdef6 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
@@ -930,38 +930,6 @@ static enum dc_status dce110_add_stream_to_ctx(
930 return result; 930 return result;
931} 931}
932 932
933static enum dc_status dce110_validate_guaranteed(
934 struct dc *dc,
935 struct dc_stream_state *dc_stream,
936 struct dc_state *context)
937{
938 enum dc_status result = DC_ERROR_UNEXPECTED;
939
940 context->streams[0] = dc_stream;
941 dc_stream_retain(context->streams[0]);
942 context->stream_count++;
943
944 result = resource_map_pool_resources(dc, context, dc_stream);
945
946 if (result == DC_OK)
947 result = resource_map_clock_resources(dc, context, dc_stream);
948
949 if (result == DC_OK)
950 result = build_mapped_resource(dc, context, dc_stream);
951
952 if (result == DC_OK) {
953 validate_guaranteed_copy_streams(
954 context, dc->caps.max_streams);
955 result = resource_build_scaling_params_for_context(dc, context);
956 }
957
958 if (result == DC_OK)
959 if (!dce110_validate_bandwidth(dc, context))
960 result = DC_FAIL_BANDWIDTH_VALIDATE;
961
962 return result;
963}
964
965static struct pipe_ctx *dce110_acquire_underlay( 933static struct pipe_ctx *dce110_acquire_underlay(
966 struct dc_state *context, 934 struct dc_state *context,
967 const struct resource_pool *pool, 935 const struct resource_pool *pool,
@@ -1036,7 +1004,6 @@ static void dce110_destroy_resource_pool(struct resource_pool **pool)
1036static const struct resource_funcs dce110_res_pool_funcs = { 1004static const struct resource_funcs dce110_res_pool_funcs = {
1037 .destroy = dce110_destroy_resource_pool, 1005 .destroy = dce110_destroy_resource_pool,
1038 .link_enc_create = dce110_link_encoder_create, 1006 .link_enc_create = dce110_link_encoder_create,
1039 .validate_guaranteed = dce110_validate_guaranteed,
1040 .validate_bandwidth = dce110_validate_bandwidth, 1007 .validate_bandwidth = dce110_validate_bandwidth,
1041 .validate_plane = dce110_validate_plane, 1008 .validate_plane = dce110_validate_plane,
1042 .acquire_idle_pipe_for_layer = dce110_acquire_underlay, 1009 .acquire_idle_pipe_for_layer = dce110_acquire_underlay,
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
index be7153924a70..1b2fe0df347f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
@@ -431,14 +431,6 @@ void dce110_timing_generator_set_drr(
431 0, 431 0,
432 CRTC_V_TOTAL_CONTROL, 432 CRTC_V_TOTAL_CONTROL,
433 CRTC_SET_V_TOTAL_MIN_MASK); 433 CRTC_SET_V_TOTAL_MIN_MASK);
434 set_reg_field_value(v_total_min,
435 0,
436 CRTC_V_TOTAL_MIN,
437 CRTC_V_TOTAL_MIN);
438 set_reg_field_value(v_total_max,
439 0,
440 CRTC_V_TOTAL_MAX,
441 CRTC_V_TOTAL_MAX);
442 set_reg_field_value(v_total_cntl, 434 set_reg_field_value(v_total_cntl,
443 0, 435 0,
444 CRTC_V_TOTAL_CONTROL, 436 CRTC_V_TOTAL_CONTROL,
@@ -447,6 +439,14 @@ void dce110_timing_generator_set_drr(
447 0, 439 0,
448 CRTC_V_TOTAL_CONTROL, 440 CRTC_V_TOTAL_CONTROL,
449 CRTC_V_TOTAL_MAX_SEL); 441 CRTC_V_TOTAL_MAX_SEL);
442 set_reg_field_value(v_total_min,
443 0,
444 CRTC_V_TOTAL_MIN,
445 CRTC_V_TOTAL_MIN);
446 set_reg_field_value(v_total_max,
447 0,
448 CRTC_V_TOTAL_MAX,
449 CRTC_V_TOTAL_MAX);
450 set_reg_field_value(v_total_cntl, 450 set_reg_field_value(v_total_cntl,
451 0, 451 0,
452 CRTC_V_TOTAL_CONTROL, 452 CRTC_V_TOTAL_CONTROL,
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
index 8ad04816e7d3..a3cef60380ed 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
@@ -648,12 +648,6 @@ static void dce110_timing_generator_v_disable_vga(
648 return; 648 return;
649} 649}
650 650
651static bool dce110_tg_v_is_blanked(struct timing_generator *tg)
652{
653 /* Signal comes from the primary pipe, underlay is never blanked. */
654 return false;
655}
656
657/** ******************************************************************************************** 651/** ********************************************************************************************
658 * 652 *
659 * DCE11 Timing Generator Constructor / Destructor 653 * DCE11 Timing Generator Constructor / Destructor
@@ -670,7 +664,6 @@ static const struct timing_generator_funcs dce110_tg_v_funcs = {
670 .set_early_control = dce110_timing_generator_v_set_early_control, 664 .set_early_control = dce110_timing_generator_v_set_early_control,
671 .wait_for_state = dce110_timing_generator_v_wait_for_state, 665 .wait_for_state = dce110_timing_generator_v_wait_for_state,
672 .set_blank = dce110_timing_generator_v_set_blank, 666 .set_blank = dce110_timing_generator_v_set_blank,
673 .is_blanked = dce110_tg_v_is_blanked,
674 .set_colors = dce110_timing_generator_v_set_colors, 667 .set_colors = dce110_timing_generator_v_set_colors,
675 .set_overscan_blank_color = 668 .set_overscan_blank_color =
676 dce110_timing_generator_v_set_overscan_color_black, 669 dce110_timing_generator_v_set_overscan_color_black,
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c
index 8ba3c12fc608..a7dce060204f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c
@@ -373,13 +373,13 @@ static void calculate_inits(
373 struct rect *chroma_viewport) 373 struct rect *chroma_viewport)
374{ 374{
375 inits->h_int_scale_ratio_luma = 375 inits->h_int_scale_ratio_luma =
376 dal_fixed31_32_u2d19(data->ratios.horz) << 5; 376 dc_fixpt_u2d19(data->ratios.horz) << 5;
377 inits->v_int_scale_ratio_luma = 377 inits->v_int_scale_ratio_luma =
378 dal_fixed31_32_u2d19(data->ratios.vert) << 5; 378 dc_fixpt_u2d19(data->ratios.vert) << 5;
379 inits->h_int_scale_ratio_chroma = 379 inits->h_int_scale_ratio_chroma =
380 dal_fixed31_32_u2d19(data->ratios.horz_c) << 5; 380 dc_fixpt_u2d19(data->ratios.horz_c) << 5;
381 inits->v_int_scale_ratio_chroma = 381 inits->v_int_scale_ratio_chroma =
382 dal_fixed31_32_u2d19(data->ratios.vert_c) << 5; 382 dc_fixpt_u2d19(data->ratios.vert_c) << 5;
383 383
384 inits->h_init_luma.integer = 1; 384 inits->h_init_luma.integer = 1;
385 inits->v_init_luma.integer = 1; 385 inits->v_init_luma.integer = 1;
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
index cd1e3f72c44e..00c0a1ef15eb 100644
--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
@@ -430,7 +430,7 @@ static struct stream_encoder *dce112_stream_encoder_create(
430 430
431 if (!enc110) 431 if (!enc110)
432 return NULL; 432 return NULL;
433 433
434 dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, 434 dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
435 &stream_enc_regs[eng_id], 435 &stream_enc_regs[eng_id],
436 &se_shift, &se_mask); 436 &se_shift, &se_mask);
@@ -867,38 +867,6 @@ enum dc_status dce112_add_stream_to_ctx(
867 return result; 867 return result;
868} 868}
869 869
870enum dc_status dce112_validate_guaranteed(
871 struct dc *dc,
872 struct dc_stream_state *stream,
873 struct dc_state *context)
874{
875 enum dc_status result = DC_ERROR_UNEXPECTED;
876
877 context->streams[0] = stream;
878 dc_stream_retain(context->streams[0]);
879 context->stream_count++;
880
881 result = resource_map_pool_resources(dc, context, stream);
882
883 if (result == DC_OK)
884 result = resource_map_phy_clock_resources(dc, context, stream);
885
886 if (result == DC_OK)
887 result = build_mapped_resource(dc, context, stream);
888
889 if (result == DC_OK) {
890 validate_guaranteed_copy_streams(
891 context, dc->caps.max_streams);
892 result = resource_build_scaling_params_for_context(dc, context);
893 }
894
895 if (result == DC_OK)
896 if (!dce112_validate_bandwidth(dc, context))
897 result = DC_FAIL_BANDWIDTH_VALIDATE;
898
899 return result;
900}
901
902enum dc_status dce112_validate_global( 870enum dc_status dce112_validate_global(
903 struct dc *dc, 871 struct dc *dc,
904 struct dc_state *context) 872 struct dc_state *context)
@@ -921,7 +889,6 @@ static void dce112_destroy_resource_pool(struct resource_pool **pool)
921static const struct resource_funcs dce112_res_pool_funcs = { 889static const struct resource_funcs dce112_res_pool_funcs = {
922 .destroy = dce112_destroy_resource_pool, 890 .destroy = dce112_destroy_resource_pool,
923 .link_enc_create = dce112_link_encoder_create, 891 .link_enc_create = dce112_link_encoder_create,
924 .validate_guaranteed = dce112_validate_guaranteed,
925 .validate_bandwidth = dce112_validate_bandwidth, 892 .validate_bandwidth = dce112_validate_bandwidth,
926 .validate_plane = dce100_validate_plane, 893 .validate_plane = dce100_validate_plane,
927 .add_stream_to_ctx = dce112_add_stream_to_ctx, 894 .add_stream_to_ctx = dce112_add_stream_to_ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h
index d5c19d34eb0a..95a403396219 100644
--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h
@@ -42,11 +42,6 @@ enum dc_status dce112_validate_with_context(
42 struct dc_state *context, 42 struct dc_state *context,
43 struct dc_state *old_context); 43 struct dc_state *old_context);
44 44
45enum dc_status dce112_validate_guaranteed(
46 struct dc *dc,
47 struct dc_stream_state *dc_stream,
48 struct dc_state *context);
49
50bool dce112_validate_bandwidth( 45bool dce112_validate_bandwidth(
51 struct dc *dc, 46 struct dc *dc,
52 struct dc_state *context); 47 struct dc_state *context);
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
index 4659a4bfabaa..2d58daccc005 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
@@ -652,7 +652,7 @@ static struct mem_input *dce120_mem_input_create(
652 return NULL; 652 return NULL;
653 } 653 }
654 654
655 dce112_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks); 655 dce120_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
656 return &dce_mi->base; 656 return &dce_mi->base;
657} 657}
658 658
@@ -684,7 +684,6 @@ static void dce120_destroy_resource_pool(struct resource_pool **pool)
684static const struct resource_funcs dce120_res_pool_funcs = { 684static const struct resource_funcs dce120_res_pool_funcs = {
685 .destroy = dce120_destroy_resource_pool, 685 .destroy = dce120_destroy_resource_pool,
686 .link_enc_create = dce120_link_encoder_create, 686 .link_enc_create = dce120_link_encoder_create,
687 .validate_guaranteed = dce112_validate_guaranteed,
688 .validate_bandwidth = dce112_validate_bandwidth, 687 .validate_bandwidth = dce112_validate_bandwidth,
689 .validate_plane = dce100_validate_plane, 688 .validate_plane = dce100_validate_plane,
690 .add_stream_to_ctx = dce112_add_stream_to_ctx 689 .add_stream_to_ctx = dce112_add_stream_to_ctx
@@ -815,14 +814,25 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc)
815 dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges); 814 dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);
816} 815}
817 816
817static uint32_t read_pipe_fuses(struct dc_context *ctx)
818{
819 uint32_t value = dm_read_reg_soc15(ctx, mmCC_DC_PIPE_DIS, 0);
820 /* VG20 support max 6 pipes */
821 value = value & 0x3f;
822 return value;
823}
824
818static bool construct( 825static bool construct(
819 uint8_t num_virtual_links, 826 uint8_t num_virtual_links,
820 struct dc *dc, 827 struct dc *dc,
821 struct dce110_resource_pool *pool) 828 struct dce110_resource_pool *pool)
822{ 829{
823 unsigned int i; 830 unsigned int i;
831 int j;
824 struct dc_context *ctx = dc->ctx; 832 struct dc_context *ctx = dc->ctx;
825 struct irq_service_init_data irq_init_data; 833 struct irq_service_init_data irq_init_data;
834 bool harvest_enabled = ASICREV_IS_VEGA20_P(ctx->asic_id.hw_internal_rev);
835 uint32_t pipe_fuses;
826 836
827 ctx->dc_bios->regs = &bios_regs; 837 ctx->dc_bios->regs = &bios_regs;
828 838
@@ -916,28 +926,41 @@ static bool construct(
916 if (!pool->base.irqs) 926 if (!pool->base.irqs)
917 goto irqs_create_fail; 927 goto irqs_create_fail;
918 928
929 /* retrieve valid pipe fuses */
930 if (harvest_enabled)
931 pipe_fuses = read_pipe_fuses(ctx);
932
933 /* index to valid pipe resource */
934 j = 0;
919 for (i = 0; i < pool->base.pipe_count; i++) { 935 for (i = 0; i < pool->base.pipe_count; i++) {
920 pool->base.timing_generators[i] = 936 if (harvest_enabled) {
937 if ((pipe_fuses & (1 << i)) != 0) {
938 dm_error("DC: skip invalid pipe %d!\n", i);
939 continue;
940 }
941 }
942
943 pool->base.timing_generators[j] =
921 dce120_timing_generator_create( 944 dce120_timing_generator_create(
922 ctx, 945 ctx,
923 i, 946 i,
924 &dce120_tg_offsets[i]); 947 &dce120_tg_offsets[i]);
925 if (pool->base.timing_generators[i] == NULL) { 948 if (pool->base.timing_generators[j] == NULL) {
926 BREAK_TO_DEBUGGER(); 949 BREAK_TO_DEBUGGER();
927 dm_error("DC: failed to create tg!\n"); 950 dm_error("DC: failed to create tg!\n");
928 goto controller_create_fail; 951 goto controller_create_fail;
929 } 952 }
930 953
931 pool->base.mis[i] = dce120_mem_input_create(ctx, i); 954 pool->base.mis[j] = dce120_mem_input_create(ctx, i);
932 955
933 if (pool->base.mis[i] == NULL) { 956 if (pool->base.mis[j] == NULL) {
934 BREAK_TO_DEBUGGER(); 957 BREAK_TO_DEBUGGER();
935 dm_error( 958 dm_error(
936 "DC: failed to create memory input!\n"); 959 "DC: failed to create memory input!\n");
937 goto controller_create_fail; 960 goto controller_create_fail;
938 } 961 }
939 962
940 pool->base.ipps[i] = dce120_ipp_create(ctx, i); 963 pool->base.ipps[j] = dce120_ipp_create(ctx, i);
941 if (pool->base.ipps[i] == NULL) { 964 if (pool->base.ipps[i] == NULL) {
942 BREAK_TO_DEBUGGER(); 965 BREAK_TO_DEBUGGER();
943 dm_error( 966 dm_error(
@@ -945,7 +968,7 @@ static bool construct(
945 goto controller_create_fail; 968 goto controller_create_fail;
946 } 969 }
947 970
948 pool->base.transforms[i] = dce120_transform_create(ctx, i); 971 pool->base.transforms[j] = dce120_transform_create(ctx, i);
949 if (pool->base.transforms[i] == NULL) { 972 if (pool->base.transforms[i] == NULL) {
950 BREAK_TO_DEBUGGER(); 973 BREAK_TO_DEBUGGER();
951 dm_error( 974 dm_error(
@@ -953,16 +976,23 @@ static bool construct(
953 goto res_create_fail; 976 goto res_create_fail;
954 } 977 }
955 978
956 pool->base.opps[i] = dce120_opp_create( 979 pool->base.opps[j] = dce120_opp_create(
957 ctx, 980 ctx,
958 i); 981 i);
959 if (pool->base.opps[i] == NULL) { 982 if (pool->base.opps[j] == NULL) {
960 BREAK_TO_DEBUGGER(); 983 BREAK_TO_DEBUGGER();
961 dm_error( 984 dm_error(
962 "DC: failed to create output pixel processor!\n"); 985 "DC: failed to create output pixel processor!\n");
963 } 986 }
987
988 /* check next valid pipe */
989 j++;
964 } 990 }
965 991
992 /* valid pipe num */
993 pool->base.pipe_count = j;
994 pool->base.timing_generator_count = j;
995
966 if (!resource_construct(num_virtual_links, dc, &pool->base, 996 if (!resource_construct(num_virtual_links, dc, &pool->base,
967 &res_create_funcs)) 997 &res_create_funcs))
968 goto res_create_fail; 998 goto res_create_fail;
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
index 7bee78172d85..2ea490f8482e 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
@@ -570,12 +570,6 @@ void dce120_timing_generator_set_drr(
570 0x180); 570 0x180);
571 571
572 } else { 572 } else {
573 CRTC_REG_UPDATE(
574 CRTC0_CRTC_V_TOTAL_MIN,
575 CRTC_V_TOTAL_MIN, 0);
576 CRTC_REG_UPDATE(
577 CRTC0_CRTC_V_TOTAL_MAX,
578 CRTC_V_TOTAL_MAX, 0);
579 CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 5, 573 CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 5,
580 FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 0, 574 FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 0,
581 FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 0, 575 FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 0,
@@ -583,6 +577,12 @@ void dce120_timing_generator_set_drr(
583 FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0, 577 FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0,
584 FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0); 578 FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0);
585 CRTC_REG_UPDATE( 579 CRTC_REG_UPDATE(
580 CRTC0_CRTC_V_TOTAL_MIN,
581 CRTC_V_TOTAL_MIN, 0);
582 CRTC_REG_UPDATE(
583 CRTC0_CRTC_V_TOTAL_MAX,
584 CRTC_V_TOTAL_MAX, 0);
585 CRTC_REG_UPDATE(
586 CRTC0_CRTC_STATIC_SCREEN_CONTROL, 586 CRTC0_CRTC_STATIC_SCREEN_CONTROL,
587 CRTC_STATIC_SCREEN_EVENT_MASK, 587 CRTC_STATIC_SCREEN_EVENT_MASK,
588 0); 588 0);
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
index 5d854a37a978..48a068964722 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
@@ -691,23 +691,6 @@ static void destruct(struct dce110_resource_pool *pool)
691 } 691 }
692} 692}
693 693
694static enum dc_status build_mapped_resource(
695 const struct dc *dc,
696 struct dc_state *context,
697 struct dc_stream_state *stream)
698{
699 struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
700
701 if (!pipe_ctx)
702 return DC_ERROR_UNEXPECTED;
703
704 dce110_resource_build_pipe_hw_param(pipe_ctx);
705
706 resource_build_info_frame(pipe_ctx);
707
708 return DC_OK;
709}
710
711bool dce80_validate_bandwidth( 694bool dce80_validate_bandwidth(
712 struct dc *dc, 695 struct dc *dc,
713 struct dc_state *context) 696 struct dc_state *context)
@@ -749,37 +732,6 @@ enum dc_status dce80_validate_global(
749 return DC_OK; 732 return DC_OK;
750} 733}
751 734
752enum dc_status dce80_validate_guaranteed(
753 struct dc *dc,
754 struct dc_stream_state *dc_stream,
755 struct dc_state *context)
756{
757 enum dc_status result = DC_ERROR_UNEXPECTED;
758
759 context->streams[0] = dc_stream;
760 dc_stream_retain(context->streams[0]);
761 context->stream_count++;
762
763 result = resource_map_pool_resources(dc, context, dc_stream);
764
765 if (result == DC_OK)
766 result = resource_map_clock_resources(dc, context, dc_stream);
767
768 if (result == DC_OK)
769 result = build_mapped_resource(dc, context, dc_stream);
770
771 if (result == DC_OK) {
772 validate_guaranteed_copy_streams(
773 context, dc->caps.max_streams);
774 result = resource_build_scaling_params_for_context(dc, context);
775 }
776
777 if (result == DC_OK)
778 result = dce80_validate_bandwidth(dc, context);
779
780 return result;
781}
782
783static void dce80_destroy_resource_pool(struct resource_pool **pool) 735static void dce80_destroy_resource_pool(struct resource_pool **pool)
784{ 736{
785 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool); 737 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
@@ -792,7 +744,6 @@ static void dce80_destroy_resource_pool(struct resource_pool **pool)
792static const struct resource_funcs dce80_res_pool_funcs = { 744static const struct resource_funcs dce80_res_pool_funcs = {
793 .destroy = dce80_destroy_resource_pool, 745 .destroy = dce80_destroy_resource_pool,
794 .link_enc_create = dce80_link_encoder_create, 746 .link_enc_create = dce80_link_encoder_create,
795 .validate_guaranteed = dce80_validate_guaranteed,
796 .validate_bandwidth = dce80_validate_bandwidth, 747 .validate_bandwidth = dce80_validate_bandwidth,
797 .validate_plane = dce100_validate_plane, 748 .validate_plane = dce100_validate_plane,
798 .add_stream_to_ctx = dce100_add_stream_to_ctx, 749 .add_stream_to_ctx = dce100_add_stream_to_ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
index 5469bdfe19f3..84f52c63d95c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
@@ -26,7 +26,7 @@ DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \
26 dcn10_dpp.o dcn10_opp.o dcn10_optc.o \ 26 dcn10_dpp.o dcn10_opp.o dcn10_optc.o \
27 dcn10_hubp.o dcn10_mpc.o \ 27 dcn10_hubp.o dcn10_mpc.o \
28 dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o \ 28 dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o \
29 dcn10_hubbub.o 29 dcn10_hubbub.o dcn10_stream_encoder.o dcn10_link_encoder.o
30 30
31AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) 31AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10))
32 32
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index 881a1bff94d2..5d95a997fd9f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -169,7 +169,7 @@ bool cm_helper_convert_to_custom_float(
169 } 169 }
170 170
171 if (fixpoint == true) 171 if (fixpoint == true)
172 arr_points[1].custom_float_y = dal_fixed31_32_clamp_u0d14(arr_points[1].y); 172 arr_points[1].custom_float_y = dc_fixpt_clamp_u0d14(arr_points[1].y);
173 else if (!convert_to_custom_float_format(arr_points[1].y, &fmt, 173 else if (!convert_to_custom_float_format(arr_points[1].y, &fmt,
174 &arr_points[1].custom_float_y)) { 174 &arr_points[1].custom_float_y)) {
175 BREAK_TO_DEBUGGER(); 175 BREAK_TO_DEBUGGER();
@@ -327,19 +327,19 @@ bool cm_helper_translate_curve_to_hw_format(
327 rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 327 rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
328 rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 328 rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
329 329
330 arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 330 arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2),
331 dal_fixed31_32_from_int(region_start)); 331 dc_fixpt_from_int(region_start));
332 arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 332 arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2),
333 dal_fixed31_32_from_int(region_end)); 333 dc_fixpt_from_int(region_end));
334 334
335 y_r = rgb_resulted[0].red; 335 y_r = rgb_resulted[0].red;
336 y_g = rgb_resulted[0].green; 336 y_g = rgb_resulted[0].green;
337 y_b = rgb_resulted[0].blue; 337 y_b = rgb_resulted[0].blue;
338 338
339 y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b)); 339 y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b));
340 340
341 arr_points[0].y = y1_min; 341 arr_points[0].y = y1_min;
342 arr_points[0].slope = dal_fixed31_32_div(arr_points[0].y, arr_points[0].x); 342 arr_points[0].slope = dc_fixpt_div(arr_points[0].y, arr_points[0].x);
343 y_r = rgb_resulted[hw_points - 1].red; 343 y_r = rgb_resulted[hw_points - 1].red;
344 y_g = rgb_resulted[hw_points - 1].green; 344 y_g = rgb_resulted[hw_points - 1].green;
345 y_b = rgb_resulted[hw_points - 1].blue; 345 y_b = rgb_resulted[hw_points - 1].blue;
@@ -347,35 +347,35 @@ bool cm_helper_translate_curve_to_hw_format(
347 /* see comment above, m_arrPoints[1].y should be the Y value for the 347 /* see comment above, m_arrPoints[1].y should be the Y value for the
348 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 348 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
349 */ 349 */
350 y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b)); 350 y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b));
351 351
352 arr_points[1].y = y3_max; 352 arr_points[1].y = y3_max;
353 353
354 arr_points[1].slope = dal_fixed31_32_zero; 354 arr_points[1].slope = dc_fixpt_zero;
355 355
356 if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 356 if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
357 /* for PQ, we want to have a straight line from last HW X point, 357 /* for PQ, we want to have a straight line from last HW X point,
358 * and the slope to be such that we hit 1.0 at 10000 nits. 358 * and the slope to be such that we hit 1.0 at 10000 nits.
359 */ 359 */
360 const struct fixed31_32 end_value = 360 const struct fixed31_32 end_value =
361 dal_fixed31_32_from_int(125); 361 dc_fixpt_from_int(125);
362 362
363 arr_points[1].slope = dal_fixed31_32_div( 363 arr_points[1].slope = dc_fixpt_div(
364 dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 364 dc_fixpt_sub(dc_fixpt_one, arr_points[1].y),
365 dal_fixed31_32_sub(end_value, arr_points[1].x)); 365 dc_fixpt_sub(end_value, arr_points[1].x));
366 } 366 }
367 367
368 lut_params->hw_points_num = hw_points; 368 lut_params->hw_points_num = hw_points;
369 369
370 i = 1; 370 k = 0;
371 for (k = 0; k < MAX_REGIONS_NUMBER && i < MAX_REGIONS_NUMBER; k++) { 371 for (i = 1; i < MAX_REGIONS_NUMBER; i++) {
372 if (seg_distr[k] != -1) { 372 if (seg_distr[k] != -1) {
373 lut_params->arr_curve_points[k].segments_num = 373 lut_params->arr_curve_points[k].segments_num =
374 seg_distr[k]; 374 seg_distr[k];
375 lut_params->arr_curve_points[i].offset = 375 lut_params->arr_curve_points[i].offset =
376 lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 376 lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
377 } 377 }
378 i++; 378 k++;
379 } 379 }
380 380
381 if (seg_distr[k] != -1) 381 if (seg_distr[k] != -1)
@@ -386,24 +386,24 @@ bool cm_helper_translate_curve_to_hw_format(
386 386
387 i = 1; 387 i = 1;
388 while (i != hw_points + 1) { 388 while (i != hw_points + 1) {
389 if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red)) 389 if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
390 rgb_plus_1->red = rgb->red; 390 rgb_plus_1->red = rgb->red;
391 if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green)) 391 if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
392 rgb_plus_1->green = rgb->green; 392 rgb_plus_1->green = rgb->green;
393 if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue)) 393 if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
394 rgb_plus_1->blue = rgb->blue; 394 rgb_plus_1->blue = rgb->blue;
395 395
396 rgb->delta_red = dal_fixed31_32_sub(rgb_plus_1->red, rgb->red); 396 rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
397 rgb->delta_green = dal_fixed31_32_sub(rgb_plus_1->green, rgb->green); 397 rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
398 rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue); 398 rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
399 399
400 if (fixpoint == true) { 400 if (fixpoint == true) {
401 rgb->delta_red_reg = dal_fixed31_32_clamp_u0d10(rgb->delta_red); 401 rgb->delta_red_reg = dc_fixpt_clamp_u0d10(rgb->delta_red);
402 rgb->delta_green_reg = dal_fixed31_32_clamp_u0d10(rgb->delta_green); 402 rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green);
403 rgb->delta_blue_reg = dal_fixed31_32_clamp_u0d10(rgb->delta_blue); 403 rgb->delta_blue_reg = dc_fixpt_clamp_u0d10(rgb->delta_blue);
404 rgb->red_reg = dal_fixed31_32_clamp_u0d14(rgb->red); 404 rgb->red_reg = dc_fixpt_clamp_u0d14(rgb->red);
405 rgb->green_reg = dal_fixed31_32_clamp_u0d14(rgb->green); 405 rgb->green_reg = dc_fixpt_clamp_u0d14(rgb->green);
406 rgb->blue_reg = dal_fixed31_32_clamp_u0d14(rgb->blue); 406 rgb->blue_reg = dc_fixpt_clamp_u0d14(rgb->blue);
407 } 407 }
408 408
409 ++rgb_plus_1; 409 ++rgb_plus_1;
@@ -489,19 +489,19 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
489 rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 489 rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
490 rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 490 rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
491 491
492 arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 492 arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2),
493 dal_fixed31_32_from_int(region_start)); 493 dc_fixpt_from_int(region_start));
494 arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 494 arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2),
495 dal_fixed31_32_from_int(region_end)); 495 dc_fixpt_from_int(region_end));
496 496
497 y_r = rgb_resulted[0].red; 497 y_r = rgb_resulted[0].red;
498 y_g = rgb_resulted[0].green; 498 y_g = rgb_resulted[0].green;
499 y_b = rgb_resulted[0].blue; 499 y_b = rgb_resulted[0].blue;
500 500
501 y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b)); 501 y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b));
502 502
503 arr_points[0].y = y1_min; 503 arr_points[0].y = y1_min;
504 arr_points[0].slope = dal_fixed31_32_div(arr_points[0].y, arr_points[0].x); 504 arr_points[0].slope = dc_fixpt_div(arr_points[0].y, arr_points[0].x);
505 y_r = rgb_resulted[hw_points - 1].red; 505 y_r = rgb_resulted[hw_points - 1].red;
506 y_g = rgb_resulted[hw_points - 1].green; 506 y_g = rgb_resulted[hw_points - 1].green;
507 y_b = rgb_resulted[hw_points - 1].blue; 507 y_b = rgb_resulted[hw_points - 1].blue;
@@ -509,35 +509,35 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
509 /* see comment above, m_arrPoints[1].y should be the Y value for the 509 /* see comment above, m_arrPoints[1].y should be the Y value for the
510 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 510 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
511 */ 511 */
512 y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b)); 512 y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b));
513 513
514 arr_points[1].y = y3_max; 514 arr_points[1].y = y3_max;
515 515
516 arr_points[1].slope = dal_fixed31_32_zero; 516 arr_points[1].slope = dc_fixpt_zero;
517 517
518 if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 518 if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
519 /* for PQ, we want to have a straight line from last HW X point, 519 /* for PQ, we want to have a straight line from last HW X point,
520 * and the slope to be such that we hit 1.0 at 10000 nits. 520 * and the slope to be such that we hit 1.0 at 10000 nits.
521 */ 521 */
522 const struct fixed31_32 end_value = 522 const struct fixed31_32 end_value =
523 dal_fixed31_32_from_int(125); 523 dc_fixpt_from_int(125);
524 524
525 arr_points[1].slope = dal_fixed31_32_div( 525 arr_points[1].slope = dc_fixpt_div(
526 dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 526 dc_fixpt_sub(dc_fixpt_one, arr_points[1].y),
527 dal_fixed31_32_sub(end_value, arr_points[1].x)); 527 dc_fixpt_sub(end_value, arr_points[1].x));
528 } 528 }
529 529
530 lut_params->hw_points_num = hw_points; 530 lut_params->hw_points_num = hw_points;
531 531
532 i = 1; 532 k = 0;
533 for (k = 0; k < MAX_REGIONS_NUMBER && i < MAX_REGIONS_NUMBER; k++) { 533 for (i = 1; i < MAX_REGIONS_NUMBER; i++) {
534 if (seg_distr[k] != -1) { 534 if (seg_distr[k] != -1) {
535 lut_params->arr_curve_points[k].segments_num = 535 lut_params->arr_curve_points[k].segments_num =
536 seg_distr[k]; 536 seg_distr[k];
537 lut_params->arr_curve_points[i].offset = 537 lut_params->arr_curve_points[i].offset =
538 lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 538 lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
539 } 539 }
540 i++; 540 k++;
541 } 541 }
542 542
543 if (seg_distr[k] != -1) 543 if (seg_distr[k] != -1)
@@ -548,16 +548,16 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
548 548
549 i = 1; 549 i = 1;
550 while (i != hw_points + 1) { 550 while (i != hw_points + 1) {
551 if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red)) 551 if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
552 rgb_plus_1->red = rgb->red; 552 rgb_plus_1->red = rgb->red;
553 if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green)) 553 if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
554 rgb_plus_1->green = rgb->green; 554 rgb_plus_1->green = rgb->green;
555 if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue)) 555 if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
556 rgb_plus_1->blue = rgb->blue; 556 rgb_plus_1->blue = rgb->blue;
557 557
558 rgb->delta_red = dal_fixed31_32_sub(rgb_plus_1->red, rgb->red); 558 rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
559 rgb->delta_green = dal_fixed31_32_sub(rgb_plus_1->green, rgb->green); 559 rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
560 rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue); 560 rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
561 561
562 ++rgb_plus_1; 562 ++rgb_plus_1;
563 ++rgb; 563 ++rgb;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
index e305c28c98de..46a35c7f01df 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -98,6 +98,30 @@ enum gamut_remap_select {
98 GAMUT_REMAP_COMB_COEFF 98 GAMUT_REMAP_COMB_COEFF
99}; 99};
100 100
101void dpp_read_state(struct dpp *dpp_base,
102 struct dcn_dpp_state *s)
103{
104 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
105
106 REG_GET(CM_IGAM_CONTROL,
107 CM_IGAM_LUT_MODE, &s->igam_lut_mode);
108 REG_GET(CM_IGAM_CONTROL,
109 CM_IGAM_INPUT_FORMAT, &s->igam_input_format);
110 REG_GET(CM_DGAM_CONTROL,
111 CM_DGAM_LUT_MODE, &s->dgam_lut_mode);
112 REG_GET(CM_RGAM_CONTROL,
113 CM_RGAM_LUT_MODE, &s->rgam_lut_mode);
114 REG_GET(CM_GAMUT_REMAP_CONTROL,
115 CM_GAMUT_REMAP_MODE, &s->gamut_remap_mode);
116
117 s->gamut_remap_c11_c12 = REG_READ(CM_GAMUT_REMAP_C11_C12);
118 s->gamut_remap_c13_c14 = REG_READ(CM_GAMUT_REMAP_C13_C14);
119 s->gamut_remap_c21_c22 = REG_READ(CM_GAMUT_REMAP_C21_C22);
120 s->gamut_remap_c23_c24 = REG_READ(CM_GAMUT_REMAP_C23_C24);
121 s->gamut_remap_c31_c32 = REG_READ(CM_GAMUT_REMAP_C31_C32);
122 s->gamut_remap_c33_c34 = REG_READ(CM_GAMUT_REMAP_C33_C34);
123}
124
101/* Program gamut remap in bypass mode */ 125/* Program gamut remap in bypass mode */
102void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp) 126void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp)
103{ 127{
@@ -106,7 +130,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp)
106 /* Gamut remap in bypass */ 130 /* Gamut remap in bypass */
107} 131}
108 132
109#define IDENTITY_RATIO(ratio) (dal_fixed31_32_u2d19(ratio) == (1 << 19)) 133#define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19))
110 134
111 135
112bool dpp_get_optimal_number_of_taps( 136bool dpp_get_optimal_number_of_taps(
@@ -121,6 +145,18 @@ bool dpp_get_optimal_number_of_taps(
121 else 145 else
122 pixel_width = scl_data->viewport.width; 146 pixel_width = scl_data->viewport.width;
123 147
148 /* Some ASICs does not support FP16 scaling, so we reject modes require this*/
149 if (scl_data->viewport.width != scl_data->h_active &&
150 scl_data->viewport.height != scl_data->v_active &&
151 dpp->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT &&
152 scl_data->format == PIXEL_FORMAT_FP16)
153 return false;
154
155 if (scl_data->viewport.width > scl_data->h_active &&
156 dpp->ctx->dc->debug.max_downscale_src_width != 0 &&
157 scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width)
158 return false;
159
124 /* TODO: add lb check */ 160 /* TODO: add lb check */
125 161
126 /* No support for programming ratio of 4, drop to 3.99999.. */ 162 /* No support for programming ratio of 4, drop to 3.99999.. */
@@ -257,7 +293,7 @@ void dpp1_cnv_setup (
257 struct dpp *dpp_base, 293 struct dpp *dpp_base,
258 enum surface_pixel_format format, 294 enum surface_pixel_format format,
259 enum expansion_mode mode, 295 enum expansion_mode mode,
260 struct csc_transform input_csc_color_matrix, 296 struct dc_csc_transform input_csc_color_matrix,
261 enum dc_color_space input_color_space) 297 enum dc_color_space input_color_space)
262{ 298{
263 uint32_t pixel_format; 299 uint32_t pixel_format;
@@ -416,7 +452,7 @@ void dpp1_set_cursor_position(
416 if (src_x_offset >= (int)param->viewport_width) 452 if (src_x_offset >= (int)param->viewport_width)
417 cur_en = 0; /* not visible beyond right edge*/ 453 cur_en = 0; /* not visible beyond right edge*/
418 454
419 if (src_x_offset + (int)width < 0) 455 if (src_x_offset + (int)width <= 0)
420 cur_en = 0; /* not visible beyond left edge*/ 456 cur_en = 0; /* not visible beyond left edge*/
421 457
422 REG_UPDATE(CURSOR0_CONTROL, 458 REG_UPDATE(CURSOR0_CONTROL,
@@ -443,6 +479,7 @@ void dpp1_dppclk_control(
443} 479}
444 480
445static const struct dpp_funcs dcn10_dpp_funcs = { 481static const struct dpp_funcs dcn10_dpp_funcs = {
482 .dpp_read_state = dpp_read_state,
446 .dpp_reset = dpp_reset, 483 .dpp_reset = dpp_reset,
447 .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale, 484 .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
448 .dpp_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps, 485 .dpp_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
index 17b062a8f88a..5944a3ba0409 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
@@ -44,6 +44,10 @@
44#define TF_REG_LIST_DCN(id) \ 44#define TF_REG_LIST_DCN(id) \
45 SRI(CM_GAMUT_REMAP_CONTROL, CM, id),\ 45 SRI(CM_GAMUT_REMAP_CONTROL, CM, id),\
46 SRI(CM_GAMUT_REMAP_C11_C12, CM, id),\ 46 SRI(CM_GAMUT_REMAP_C11_C12, CM, id),\
47 SRI(CM_GAMUT_REMAP_C13_C14, CM, id),\
48 SRI(CM_GAMUT_REMAP_C21_C22, CM, id),\
49 SRI(CM_GAMUT_REMAP_C23_C24, CM, id),\
50 SRI(CM_GAMUT_REMAP_C31_C32, CM, id),\
47 SRI(CM_GAMUT_REMAP_C33_C34, CM, id),\ 51 SRI(CM_GAMUT_REMAP_C33_C34, CM, id),\
48 SRI(DSCL_EXT_OVERSCAN_LEFT_RIGHT, DSCL, id), \ 52 SRI(DSCL_EXT_OVERSCAN_LEFT_RIGHT, DSCL, id), \
49 SRI(DSCL_EXT_OVERSCAN_TOP_BOTTOM, DSCL, id), \ 53 SRI(DSCL_EXT_OVERSCAN_TOP_BOTTOM, DSCL, id), \
@@ -108,6 +112,8 @@
108 SRI(CM_DGAM_LUT_DATA, CM, id), \ 112 SRI(CM_DGAM_LUT_DATA, CM, id), \
109 SRI(CM_CONTROL, CM, id), \ 113 SRI(CM_CONTROL, CM, id), \
110 SRI(CM_DGAM_CONTROL, CM, id), \ 114 SRI(CM_DGAM_CONTROL, CM, id), \
115 SRI(CM_TEST_DEBUG_INDEX, CM, id), \
116 SRI(CM_TEST_DEBUG_DATA, CM, id), \
111 SRI(FORMAT_CONTROL, CNVC_CFG, id), \ 117 SRI(FORMAT_CONTROL, CNVC_CFG, id), \
112 SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \ 118 SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
113 SRI(CURSOR0_CONTROL, CNVC_CUR, id), \ 119 SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
@@ -175,6 +181,14 @@
175 TF_SF(CM0_CM_GAMUT_REMAP_CONTROL, CM_GAMUT_REMAP_MODE, mask_sh),\ 181 TF_SF(CM0_CM_GAMUT_REMAP_CONTROL, CM_GAMUT_REMAP_MODE, mask_sh),\
176 TF_SF(CM0_CM_GAMUT_REMAP_C11_C12, CM_GAMUT_REMAP_C11, mask_sh),\ 182 TF_SF(CM0_CM_GAMUT_REMAP_C11_C12, CM_GAMUT_REMAP_C11, mask_sh),\
177 TF_SF(CM0_CM_GAMUT_REMAP_C11_C12, CM_GAMUT_REMAP_C12, mask_sh),\ 183 TF_SF(CM0_CM_GAMUT_REMAP_C11_C12, CM_GAMUT_REMAP_C12, mask_sh),\
184 TF_SF(CM0_CM_GAMUT_REMAP_C13_C14, CM_GAMUT_REMAP_C13, mask_sh),\
185 TF_SF(CM0_CM_GAMUT_REMAP_C13_C14, CM_GAMUT_REMAP_C14, mask_sh),\
186 TF_SF(CM0_CM_GAMUT_REMAP_C21_C22, CM_GAMUT_REMAP_C21, mask_sh),\
187 TF_SF(CM0_CM_GAMUT_REMAP_C21_C22, CM_GAMUT_REMAP_C22, mask_sh),\
188 TF_SF(CM0_CM_GAMUT_REMAP_C23_C24, CM_GAMUT_REMAP_C23, mask_sh),\
189 TF_SF(CM0_CM_GAMUT_REMAP_C23_C24, CM_GAMUT_REMAP_C24, mask_sh),\
190 TF_SF(CM0_CM_GAMUT_REMAP_C31_C32, CM_GAMUT_REMAP_C31, mask_sh),\
191 TF_SF(CM0_CM_GAMUT_REMAP_C31_C32, CM_GAMUT_REMAP_C32, mask_sh),\
178 TF_SF(CM0_CM_GAMUT_REMAP_C33_C34, CM_GAMUT_REMAP_C33, mask_sh),\ 192 TF_SF(CM0_CM_GAMUT_REMAP_C33_C34, CM_GAMUT_REMAP_C33, mask_sh),\
179 TF_SF(CM0_CM_GAMUT_REMAP_C33_C34, CM_GAMUT_REMAP_C34, mask_sh),\ 193 TF_SF(CM0_CM_GAMUT_REMAP_C33_C34, CM_GAMUT_REMAP_C34, mask_sh),\
180 TF_SF(DSCL0_DSCL_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT, mask_sh),\ 194 TF_SF(DSCL0_DSCL_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT, mask_sh),\
@@ -300,6 +314,7 @@
300 TF_SF(CM0_CM_DGAM_LUT_INDEX, CM_DGAM_LUT_INDEX, mask_sh), \ 314 TF_SF(CM0_CM_DGAM_LUT_INDEX, CM_DGAM_LUT_INDEX, mask_sh), \
301 TF_SF(CM0_CM_DGAM_LUT_DATA, CM_DGAM_LUT_DATA, mask_sh), \ 315 TF_SF(CM0_CM_DGAM_LUT_DATA, CM_DGAM_LUT_DATA, mask_sh), \
302 TF_SF(CM0_CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, mask_sh), \ 316 TF_SF(CM0_CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, mask_sh), \
317 TF_SF(CM0_CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_INDEX, mask_sh), \
303 TF_SF(CNVC_CFG0_FORMAT_CONTROL, CNVC_BYPASS, mask_sh), \ 318 TF_SF(CNVC_CFG0_FORMAT_CONTROL, CNVC_BYPASS, mask_sh), \
304 TF2_SF(CNVC_CFG0, FORMAT_CONTROL__ALPHA_EN, mask_sh), \ 319 TF2_SF(CNVC_CFG0, FORMAT_CONTROL__ALPHA_EN, mask_sh), \
305 TF_SF(CNVC_CFG0_FORMAT_CONTROL, FORMAT_EXPANSION_MODE, mask_sh), \ 320 TF_SF(CNVC_CFG0_FORMAT_CONTROL, FORMAT_EXPANSION_MODE, mask_sh), \
@@ -417,6 +432,41 @@
417 TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \ 432 TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
418 TF_SF(DPP_TOP0_DPP_CONTROL, DPPCLK_RATE_CONTROL, mask_sh) 433 TF_SF(DPP_TOP0_DPP_CONTROL, DPPCLK_RATE_CONTROL, mask_sh)
419 434
435/*
436 *
437 DCN1 CM debug status register definition
438
439 register :ID9_CM_STATUS do
440 implement_ref :cm
441 map to: :cmdebugind, at: j
442 width 32
443 disclosure NEVER
444
445 field :ID9_VUPDATE_CFG, [0], R
446 field :ID9_IGAM_LUT_MODE, [2..1], R
447 field :ID9_BNS_BYPASS, [3], R
448 field :ID9_ICSC_MODE, [5..4], R
449 field :ID9_DGAM_LUT_MODE, [8..6], R
450 field :ID9_HDR_BYPASS, [9], R
451 field :ID9_GAMUT_REMAP_MODE, [11..10], R
452 field :ID9_RGAM_LUT_MODE, [14..12], R
453 #1 free bit
454 field :ID9_OCSC_MODE, [18..16], R
455 field :ID9_DENORM_MODE, [21..19], R
456 field :ID9_ROUND_TRUNC_MODE, [25..22], R
457 field :ID9_DITHER_EN, [26], R
458 field :ID9_DITHER_MODE, [28..27], R
459 end
460*/
461
462#define TF_DEBUG_REG_LIST_SH_DCN10 \
463 .CM_TEST_DEBUG_DATA_ID9_ICSC_MODE = 4, \
464 .CM_TEST_DEBUG_DATA_ID9_OCSC_MODE = 16
465
466#define TF_DEBUG_REG_LIST_MASK_DCN10 \
467 .CM_TEST_DEBUG_DATA_ID9_ICSC_MODE = 0x30, \
468 .CM_TEST_DEBUG_DATA_ID9_OCSC_MODE = 0x70000
469
420#define TF_REG_FIELD_LIST(type) \ 470#define TF_REG_FIELD_LIST(type) \
421 type EXT_OVERSCAN_LEFT; \ 471 type EXT_OVERSCAN_LEFT; \
422 type EXT_OVERSCAN_RIGHT; \ 472 type EXT_OVERSCAN_RIGHT; \
@@ -486,6 +536,14 @@
486 type CM_GAMUT_REMAP_MODE; \ 536 type CM_GAMUT_REMAP_MODE; \
487 type CM_GAMUT_REMAP_C11; \ 537 type CM_GAMUT_REMAP_C11; \
488 type CM_GAMUT_REMAP_C12; \ 538 type CM_GAMUT_REMAP_C12; \
539 type CM_GAMUT_REMAP_C13; \
540 type CM_GAMUT_REMAP_C14; \
541 type CM_GAMUT_REMAP_C21; \
542 type CM_GAMUT_REMAP_C22; \
543 type CM_GAMUT_REMAP_C23; \
544 type CM_GAMUT_REMAP_C24; \
545 type CM_GAMUT_REMAP_C31; \
546 type CM_GAMUT_REMAP_C32; \
489 type CM_GAMUT_REMAP_C33; \ 547 type CM_GAMUT_REMAP_C33; \
490 type CM_GAMUT_REMAP_C34; \ 548 type CM_GAMUT_REMAP_C34; \
491 type CM_COMA_C11; \ 549 type CM_COMA_C11; \
@@ -1010,6 +1068,9 @@
1010 type CUR0_EXPANSION_MODE; \ 1068 type CUR0_EXPANSION_MODE; \
1011 type CUR0_ENABLE; \ 1069 type CUR0_ENABLE; \
1012 type CM_BYPASS; \ 1070 type CM_BYPASS; \
1071 type CM_TEST_DEBUG_INDEX; \
1072 type CM_TEST_DEBUG_DATA_ID9_ICSC_MODE; \
1073 type CM_TEST_DEBUG_DATA_ID9_OCSC_MODE;\
1013 type FORMAT_CONTROL__ALPHA_EN; \ 1074 type FORMAT_CONTROL__ALPHA_EN; \
1014 type CUR0_COLOR0; \ 1075 type CUR0_COLOR0; \
1015 type CUR0_COLOR1; \ 1076 type CUR0_COLOR1; \
@@ -1054,6 +1115,10 @@ struct dcn_dpp_mask {
1054 uint32_t RECOUT_SIZE; \ 1115 uint32_t RECOUT_SIZE; \
1055 uint32_t CM_GAMUT_REMAP_CONTROL; \ 1116 uint32_t CM_GAMUT_REMAP_CONTROL; \
1056 uint32_t CM_GAMUT_REMAP_C11_C12; \ 1117 uint32_t CM_GAMUT_REMAP_C11_C12; \
1118 uint32_t CM_GAMUT_REMAP_C13_C14; \
1119 uint32_t CM_GAMUT_REMAP_C21_C22; \
1120 uint32_t CM_GAMUT_REMAP_C23_C24; \
1121 uint32_t CM_GAMUT_REMAP_C31_C32; \
1057 uint32_t CM_GAMUT_REMAP_C33_C34; \ 1122 uint32_t CM_GAMUT_REMAP_C33_C34; \
1058 uint32_t CM_COMA_C11_C12; \ 1123 uint32_t CM_COMA_C11_C12; \
1059 uint32_t CM_COMA_C33_C34; \ 1124 uint32_t CM_COMA_C33_C34; \
@@ -1255,6 +1320,8 @@ struct dcn_dpp_mask {
1255 uint32_t CM_IGAM_LUT_RW_CONTROL; \ 1320 uint32_t CM_IGAM_LUT_RW_CONTROL; \
1256 uint32_t CM_IGAM_LUT_RW_INDEX; \ 1321 uint32_t CM_IGAM_LUT_RW_INDEX; \
1257 uint32_t CM_IGAM_LUT_SEQ_COLOR; \ 1322 uint32_t CM_IGAM_LUT_SEQ_COLOR; \
1323 uint32_t CM_TEST_DEBUG_INDEX; \
1324 uint32_t CM_TEST_DEBUG_DATA; \
1258 uint32_t FORMAT_CONTROL; \ 1325 uint32_t FORMAT_CONTROL; \
1259 uint32_t CNVC_SURFACE_PIXEL_FORMAT; \ 1326 uint32_t CNVC_SURFACE_PIXEL_FORMAT; \
1260 uint32_t CURSOR_CONTROL; \ 1327 uint32_t CURSOR_CONTROL; \
@@ -1289,8 +1356,8 @@ struct dcn10_dpp {
1289 1356
1290enum dcn10_input_csc_select { 1357enum dcn10_input_csc_select {
1291 INPUT_CSC_SELECT_BYPASS = 0, 1358 INPUT_CSC_SELECT_BYPASS = 0,
1292 INPUT_CSC_SELECT_ICSC, 1359 INPUT_CSC_SELECT_ICSC = 1,
1293 INPUT_CSC_SELECT_COMA 1360 INPUT_CSC_SELECT_COMA = 2
1294}; 1361};
1295 1362
1296void dpp1_set_cursor_attributes( 1363void dpp1_set_cursor_attributes(
@@ -1364,6 +1431,9 @@ bool dpp_get_optimal_number_of_taps(
1364 struct scaler_data *scl_data, 1431 struct scaler_data *scl_data,
1365 const struct scaling_taps *in_taps); 1432 const struct scaling_taps *in_taps);
1366 1433
1434void dpp_read_state(struct dpp *dpp_base,
1435 struct dcn_dpp_state *s);
1436
1367void dpp_reset(struct dpp *dpp_base); 1437void dpp_reset(struct dpp *dpp_base);
1368 1438
1369void dpp1_cm_program_regamma_lut( 1439void dpp1_cm_program_regamma_lut(
@@ -1408,7 +1478,7 @@ void dpp1_cnv_setup (
1408 struct dpp *dpp_base, 1478 struct dpp *dpp_base,
1409 enum surface_pixel_format format, 1479 enum surface_pixel_format format,
1410 enum expansion_mode mode, 1480 enum expansion_mode mode,
1411 struct csc_transform input_csc_color_matrix, 1481 struct dc_csc_transform input_csc_color_matrix,
1412 enum dc_color_space input_color_space); 1482 enum dc_color_space input_color_space);
1413 1483
1414void dpp1_full_bypass(struct dpp *dpp_base); 1484void dpp1_full_bypass(struct dpp *dpp_base);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
index fb32975e4b67..116977eb24e2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
@@ -216,41 +216,55 @@ static void dpp1_cm_program_color_matrix(
216 struct dcn10_dpp *dpp, 216 struct dcn10_dpp *dpp,
217 const uint16_t *regval) 217 const uint16_t *regval)
218{ 218{
219 uint32_t mode; 219 uint32_t ocsc_mode;
220 uint32_t cur_mode;
220 struct color_matrices_reg gam_regs; 221 struct color_matrices_reg gam_regs;
221 222
222 REG_GET(CM_OCSC_CONTROL, CM_OCSC_MODE, &mode);
223
224 if (regval == NULL) { 223 if (regval == NULL) {
225 BREAK_TO_DEBUGGER(); 224 BREAK_TO_DEBUGGER();
226 return; 225 return;
227 } 226 }
228 mode = 4; 227
228 /* determine which CSC matrix (ocsc or comb) we are using
229 * currently. select the alternate set to double buffer
230 * the CSC update so CSC is updated on frame boundary
231 */
232 REG_SET(CM_TEST_DEBUG_INDEX, 0,
233 CM_TEST_DEBUG_INDEX, 9);
234
235 REG_GET(CM_TEST_DEBUG_DATA,
236 CM_TEST_DEBUG_DATA_ID9_OCSC_MODE, &cur_mode);
237
238 if (cur_mode != 4)
239 ocsc_mode = 4;
240 else
241 ocsc_mode = 5;
242
243
229 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11; 244 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11;
230 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_OCSC_C11; 245 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_OCSC_C11;
231 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12; 246 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12;
232 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_OCSC_C12; 247 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_OCSC_C12;
233 248
234 if (mode == 4) { 249 if (ocsc_mode == 4) {
235 250
236 gam_regs.csc_c11_c12 = REG(CM_OCSC_C11_C12); 251 gam_regs.csc_c11_c12 = REG(CM_OCSC_C11_C12);
237 gam_regs.csc_c33_c34 = REG(CM_OCSC_C33_C34); 252 gam_regs.csc_c33_c34 = REG(CM_OCSC_C33_C34);
238 253
239 cm_helper_program_color_matrices(
240 dpp->base.ctx,
241 regval,
242 &gam_regs);
243
244 } else { 254 } else {
245 255
246 gam_regs.csc_c11_c12 = REG(CM_COMB_C11_C12); 256 gam_regs.csc_c11_c12 = REG(CM_COMB_C11_C12);
247 gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34); 257 gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
248 258
249 cm_helper_program_color_matrices(
250 dpp->base.ctx,
251 regval,
252 &gam_regs);
253 } 259 }
260
261 cm_helper_program_color_matrices(
262 dpp->base.ctx,
263 regval,
264 &gam_regs);
265
266 REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
267
254} 268}
255 269
256void dpp1_cm_set_output_csc_default( 270void dpp1_cm_set_output_csc_default(
@@ -260,15 +274,14 @@ void dpp1_cm_set_output_csc_default(
260 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); 274 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
261 const uint16_t *regval = NULL; 275 const uint16_t *regval = NULL;
262 int arr_size; 276 int arr_size;
263 uint32_t ocsc_mode = 4;
264 277
265 regval = find_color_matrix(colorspace, &arr_size); 278 regval = find_color_matrix(colorspace, &arr_size);
266 if (regval == NULL) { 279 if (regval == NULL) {
267 BREAK_TO_DEBUGGER(); 280 BREAK_TO_DEBUGGER();
268 return; 281 return;
269 } 282 }
283
270 dpp1_cm_program_color_matrix(dpp, regval); 284 dpp1_cm_program_color_matrix(dpp, regval);
271 REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
272} 285}
273 286
274static void dpp1_cm_get_reg_field( 287static void dpp1_cm_get_reg_field(
@@ -329,9 +342,8 @@ void dpp1_cm_set_output_csc_adjustment(
329 const uint16_t *regval) 342 const uint16_t *regval)
330{ 343{
331 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); 344 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
332 uint32_t ocsc_mode = 4; 345
333 dpp1_cm_program_color_matrix(dpp, regval); 346 dpp1_cm_program_color_matrix(dpp, regval);
334 REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
335} 347}
336 348
337void dpp1_cm_power_on_regamma_lut(struct dpp *dpp_base, 349void dpp1_cm_power_on_regamma_lut(struct dpp *dpp_base,
@@ -437,17 +449,18 @@ void dpp1_cm_program_regamma_lutb_settings(
437void dpp1_program_input_csc( 449void dpp1_program_input_csc(
438 struct dpp *dpp_base, 450 struct dpp *dpp_base,
439 enum dc_color_space color_space, 451 enum dc_color_space color_space,
440 enum dcn10_input_csc_select select, 452 enum dcn10_input_csc_select input_select,
441 const struct out_csc_color_matrix *tbl_entry) 453 const struct out_csc_color_matrix *tbl_entry)
442{ 454{
443 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); 455 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
444 int i; 456 int i;
445 int arr_size = sizeof(dcn10_input_csc_matrix)/sizeof(struct dcn10_input_csc_matrix); 457 int arr_size = sizeof(dcn10_input_csc_matrix)/sizeof(struct dcn10_input_csc_matrix);
446 const uint16_t *regval = NULL; 458 const uint16_t *regval = NULL;
447 uint32_t selection = 1; 459 uint32_t cur_select = 0;
460 enum dcn10_input_csc_select select;
448 struct color_matrices_reg gam_regs; 461 struct color_matrices_reg gam_regs;
449 462
450 if (select == INPUT_CSC_SELECT_BYPASS) { 463 if (input_select == INPUT_CSC_SELECT_BYPASS) {
451 REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0); 464 REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0);
452 return; 465 return;
453 } 466 }
@@ -467,36 +480,45 @@ void dpp1_program_input_csc(
467 regval = tbl_entry->regval; 480 regval = tbl_entry->regval;
468 } 481 }
469 482
470 if (select == INPUT_CSC_SELECT_COMA) 483 /* determine which CSC matrix (icsc or coma) we are using
471 selection = 2; 484 * currently. select the alternate set to double buffer
472 REG_SET(CM_ICSC_CONTROL, 0, 485 * the CSC update so CSC is updated on frame boundary
473 CM_ICSC_MODE, selection); 486 */
487 REG_SET(CM_TEST_DEBUG_INDEX, 0,
488 CM_TEST_DEBUG_INDEX, 9);
489
490 REG_GET(CM_TEST_DEBUG_DATA,
491 CM_TEST_DEBUG_DATA_ID9_ICSC_MODE, &cur_select);
492
493 if (cur_select != INPUT_CSC_SELECT_ICSC)
494 select = INPUT_CSC_SELECT_ICSC;
495 else
496 select = INPUT_CSC_SELECT_COMA;
474 497
475 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11; 498 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
476 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11; 499 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11;
477 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12; 500 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
478 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12; 501 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
479 502
480
481 if (select == INPUT_CSC_SELECT_ICSC) { 503 if (select == INPUT_CSC_SELECT_ICSC) {
482 504
483 gam_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12); 505 gam_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12);
484 gam_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34); 506 gam_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
485 507
486 cm_helper_program_color_matrices(
487 dpp->base.ctx,
488 regval,
489 &gam_regs);
490 } else { 508 } else {
491 509
492 gam_regs.csc_c11_c12 = REG(CM_COMA_C11_C12); 510 gam_regs.csc_c11_c12 = REG(CM_COMA_C11_C12);
493 gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34); 511 gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34);
494 512
495 cm_helper_program_color_matrices(
496 dpp->base.ctx,
497 regval,
498 &gam_regs);
499 } 513 }
514
515 cm_helper_program_color_matrices(
516 dpp->base.ctx,
517 regval,
518 &gam_regs);
519
520 REG_SET(CM_ICSC_CONTROL, 0,
521 CM_ICSC_MODE, select);
500} 522}
501 523
502//keep here for now, decide multi dce support later 524//keep here for now, decide multi dce support later
@@ -789,13 +811,13 @@ void dpp1_program_input_lut(
789 REG_UPDATE(CM_IGAM_LUT_RW_INDEX, CM_IGAM_LUT_RW_INDEX, 0); 811 REG_UPDATE(CM_IGAM_LUT_RW_INDEX, CM_IGAM_LUT_RW_INDEX, 0);
790 for (i = 0; i < gamma->num_entries; i++) { 812 for (i = 0; i < gamma->num_entries; i++) {
791 REG_SET(CM_IGAM_LUT_SEQ_COLOR, 0, CM_IGAM_LUT_SEQ_COLOR, 813 REG_SET(CM_IGAM_LUT_SEQ_COLOR, 0, CM_IGAM_LUT_SEQ_COLOR,
792 dal_fixed31_32_round( 814 dc_fixpt_round(
793 gamma->entries.red[i])); 815 gamma->entries.red[i]));
794 REG_SET(CM_IGAM_LUT_SEQ_COLOR, 0, CM_IGAM_LUT_SEQ_COLOR, 816 REG_SET(CM_IGAM_LUT_SEQ_COLOR, 0, CM_IGAM_LUT_SEQ_COLOR,
795 dal_fixed31_32_round( 817 dc_fixpt_round(
796 gamma->entries.green[i])); 818 gamma->entries.green[i]));
797 REG_SET(CM_IGAM_LUT_SEQ_COLOR, 0, CM_IGAM_LUT_SEQ_COLOR, 819 REG_SET(CM_IGAM_LUT_SEQ_COLOR, 0, CM_IGAM_LUT_SEQ_COLOR,
798 dal_fixed31_32_round( 820 dc_fixpt_round(
799 gamma->entries.blue[i])); 821 gamma->entries.blue[i]));
800 } 822 }
801 // Power off LUT memory 823 // Power off LUT memory
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
index 3eb824debf43..4ddd6273d5a5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
@@ -169,7 +169,7 @@ static enum dscl_mode_sel dpp1_dscl_get_dscl_mode(
169 const struct scaler_data *data, 169 const struct scaler_data *data,
170 bool dbg_always_scale) 170 bool dbg_always_scale)
171{ 171{
172 const long long one = dal_fixed31_32_one.value; 172 const long long one = dc_fixpt_one.value;
173 173
174 if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { 174 if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
175 /* DSCL is processing data in fixed format */ 175 /* DSCL is processing data in fixed format */
@@ -464,8 +464,8 @@ static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *d
464 int num_part_y, num_part_c; 464 int num_part_y, num_part_c;
465 int vtaps = scl_data->taps.v_taps; 465 int vtaps = scl_data->taps.v_taps;
466 int vtaps_c = scl_data->taps.v_taps_c; 466 int vtaps_c = scl_data->taps.v_taps_c;
467 int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert); 467 int ceil_vratio = dc_fixpt_ceil(scl_data->ratios.vert);
468 int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c); 468 int ceil_vratio_c = dc_fixpt_ceil(scl_data->ratios.vert_c);
469 enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0; 469 enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
470 470
471 if (dpp->base.ctx->dc->debug.use_max_lb) 471 if (dpp->base.ctx->dc->debug.use_max_lb)
@@ -565,52 +565,52 @@ static void dpp1_dscl_set_manual_ratio_init(
565 uint32_t init_int = 0; 565 uint32_t init_int = 0;
566 566
567 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0, 567 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0,
568 SCL_H_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.horz) << 5); 568 SCL_H_SCALE_RATIO, dc_fixpt_u2d19(data->ratios.horz) << 5);
569 569
570 REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0, 570 REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0,
571 SCL_V_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.vert) << 5); 571 SCL_V_SCALE_RATIO, dc_fixpt_u2d19(data->ratios.vert) << 5);
572 572
573 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0, 573 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0,
574 SCL_H_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.horz_c) << 5); 574 SCL_H_SCALE_RATIO_C, dc_fixpt_u2d19(data->ratios.horz_c) << 5);
575 575
576 REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0, 576 REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0,
577 SCL_V_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.vert_c) << 5); 577 SCL_V_SCALE_RATIO_C, dc_fixpt_u2d19(data->ratios.vert_c) << 5);
578 578
579 /* 579 /*
580 * 0.24 format for fraction, first five bits zeroed 580 * 0.24 format for fraction, first five bits zeroed
581 */ 581 */
582 init_frac = dal_fixed31_32_u0d19(data->inits.h) << 5; 582 init_frac = dc_fixpt_u0d19(data->inits.h) << 5;
583 init_int = dal_fixed31_32_floor(data->inits.h); 583 init_int = dc_fixpt_floor(data->inits.h);
584 REG_SET_2(SCL_HORZ_FILTER_INIT, 0, 584 REG_SET_2(SCL_HORZ_FILTER_INIT, 0,
585 SCL_H_INIT_FRAC, init_frac, 585 SCL_H_INIT_FRAC, init_frac,
586 SCL_H_INIT_INT, init_int); 586 SCL_H_INIT_INT, init_int);
587 587
588 init_frac = dal_fixed31_32_u0d19(data->inits.h_c) << 5; 588 init_frac = dc_fixpt_u0d19(data->inits.h_c) << 5;
589 init_int = dal_fixed31_32_floor(data->inits.h_c); 589 init_int = dc_fixpt_floor(data->inits.h_c);
590 REG_SET_2(SCL_HORZ_FILTER_INIT_C, 0, 590 REG_SET_2(SCL_HORZ_FILTER_INIT_C, 0,
591 SCL_H_INIT_FRAC_C, init_frac, 591 SCL_H_INIT_FRAC_C, init_frac,
592 SCL_H_INIT_INT_C, init_int); 592 SCL_H_INIT_INT_C, init_int);
593 593
594 init_frac = dal_fixed31_32_u0d19(data->inits.v) << 5; 594 init_frac = dc_fixpt_u0d19(data->inits.v) << 5;
595 init_int = dal_fixed31_32_floor(data->inits.v); 595 init_int = dc_fixpt_floor(data->inits.v);
596 REG_SET_2(SCL_VERT_FILTER_INIT, 0, 596 REG_SET_2(SCL_VERT_FILTER_INIT, 0,
597 SCL_V_INIT_FRAC, init_frac, 597 SCL_V_INIT_FRAC, init_frac,
598 SCL_V_INIT_INT, init_int); 598 SCL_V_INIT_INT, init_int);
599 599
600 init_frac = dal_fixed31_32_u0d19(data->inits.v_bot) << 5; 600 init_frac = dc_fixpt_u0d19(data->inits.v_bot) << 5;
601 init_int = dal_fixed31_32_floor(data->inits.v_bot); 601 init_int = dc_fixpt_floor(data->inits.v_bot);
602 REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0, 602 REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0,
603 SCL_V_INIT_FRAC_BOT, init_frac, 603 SCL_V_INIT_FRAC_BOT, init_frac,
604 SCL_V_INIT_INT_BOT, init_int); 604 SCL_V_INIT_INT_BOT, init_int);
605 605
606 init_frac = dal_fixed31_32_u0d19(data->inits.v_c) << 5; 606 init_frac = dc_fixpt_u0d19(data->inits.v_c) << 5;
607 init_int = dal_fixed31_32_floor(data->inits.v_c); 607 init_int = dc_fixpt_floor(data->inits.v_c);
608 REG_SET_2(SCL_VERT_FILTER_INIT_C, 0, 608 REG_SET_2(SCL_VERT_FILTER_INIT_C, 0,
609 SCL_V_INIT_FRAC_C, init_frac, 609 SCL_V_INIT_FRAC_C, init_frac,
610 SCL_V_INIT_INT_C, init_int); 610 SCL_V_INIT_INT_C, init_int);
611 611
612 init_frac = dal_fixed31_32_u0d19(data->inits.v_c_bot) << 5; 612 init_frac = dc_fixpt_u0d19(data->inits.v_c_bot) << 5;
613 init_int = dal_fixed31_32_floor(data->inits.v_c_bot); 613 init_int = dc_fixpt_floor(data->inits.v_c_bot);
614 REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0, 614 REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0,
615 SCL_V_INIT_FRAC_BOT_C, init_frac, 615 SCL_V_INIT_FRAC_BOT_C, init_frac,
616 SCL_V_INIT_INT_BOT_C, init_int); 616 SCL_V_INIT_INT_BOT_C, init_int);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
index 738f67ffd1b4..943143efbb82 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
@@ -476,8 +476,235 @@ void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub)
476 DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req); 476 DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req);
477} 477}
478 478
479void hubbub1_soft_reset(struct hubbub *hubbub, bool reset)
480{
481 uint32_t reset_en = reset ? 1 : 0;
482
483 REG_UPDATE(DCHUBBUB_SOFT_RESET,
484 DCHUBBUB_GLOBAL_SOFT_RESET, reset_en);
485}
486
487static bool hubbub1_dcc_support_swizzle(
488 enum swizzle_mode_values swizzle,
489 unsigned int bytes_per_element,
490 enum segment_order *segment_order_horz,
491 enum segment_order *segment_order_vert)
492{
493 bool standard_swizzle = false;
494 bool display_swizzle = false;
495
496 switch (swizzle) {
497 case DC_SW_4KB_S:
498 case DC_SW_64KB_S:
499 case DC_SW_VAR_S:
500 case DC_SW_4KB_S_X:
501 case DC_SW_64KB_S_X:
502 case DC_SW_VAR_S_X:
503 standard_swizzle = true;
504 break;
505 case DC_SW_4KB_D:
506 case DC_SW_64KB_D:
507 case DC_SW_VAR_D:
508 case DC_SW_4KB_D_X:
509 case DC_SW_64KB_D_X:
510 case DC_SW_VAR_D_X:
511 display_swizzle = true;
512 break;
513 default:
514 break;
515 }
516
517 if (bytes_per_element == 1 && standard_swizzle) {
518 *segment_order_horz = segment_order__contiguous;
519 *segment_order_vert = segment_order__na;
520 return true;
521 }
522 if (bytes_per_element == 2 && standard_swizzle) {
523 *segment_order_horz = segment_order__non_contiguous;
524 *segment_order_vert = segment_order__contiguous;
525 return true;
526 }
527 if (bytes_per_element == 4 && standard_swizzle) {
528 *segment_order_horz = segment_order__non_contiguous;
529 *segment_order_vert = segment_order__contiguous;
530 return true;
531 }
532 if (bytes_per_element == 8 && standard_swizzle) {
533 *segment_order_horz = segment_order__na;
534 *segment_order_vert = segment_order__contiguous;
535 return true;
536 }
537 if (bytes_per_element == 8 && display_swizzle) {
538 *segment_order_horz = segment_order__contiguous;
539 *segment_order_vert = segment_order__non_contiguous;
540 return true;
541 }
542
543 return false;
544}
545
546static bool hubbub1_dcc_support_pixel_format(
547 enum surface_pixel_format format,
548 unsigned int *bytes_per_element)
549{
550 /* DML: get_bytes_per_element */
551 switch (format) {
552 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
553 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
554 *bytes_per_element = 2;
555 return true;
556 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
557 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
558 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
559 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
560 *bytes_per_element = 4;
561 return true;
562 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
563 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
564 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
565 *bytes_per_element = 8;
566 return true;
567 default:
568 return false;
569 }
570}
571
572static void hubbub1_get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height,
573 unsigned int bytes_per_element)
574{
575 /* copied from DML. might want to refactor DML to leverage from DML */
576 /* DML : get_blk256_size */
577 if (bytes_per_element == 1) {
578 *blk256_width = 16;
579 *blk256_height = 16;
580 } else if (bytes_per_element == 2) {
581 *blk256_width = 16;
582 *blk256_height = 8;
583 } else if (bytes_per_element == 4) {
584 *blk256_width = 8;
585 *blk256_height = 8;
586 } else if (bytes_per_element == 8) {
587 *blk256_width = 8;
588 *blk256_height = 4;
589 }
590}
591
592static void hubbub1_det_request_size(
593 unsigned int height,
594 unsigned int width,
595 unsigned int bpe,
596 bool *req128_horz_wc,
597 bool *req128_vert_wc)
598{
599 unsigned int detile_buf_size = 164 * 1024; /* 164KB for DCN1.0 */
600
601 unsigned int blk256_height = 0;
602 unsigned int blk256_width = 0;
603 unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc;
604
605 hubbub1_get_blk256_size(&blk256_width, &blk256_height, bpe);
606
607 swath_bytes_horz_wc = height * blk256_height * bpe;
608 swath_bytes_vert_wc = width * blk256_width * bpe;
609
610 *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ?
611 false : /* full 256B request */
612 true; /* half 128b request */
613
614 *req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ?
615 false : /* full 256B request */
616 true; /* half 128b request */
617}
618
619static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub,
620 const struct dc_dcc_surface_param *input,
621 struct dc_surface_dcc_cap *output)
622{
623 struct dc *dc = hubbub->ctx->dc;
624 /* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */
625 enum dcc_control dcc_control;
626 unsigned int bpe;
627 enum segment_order segment_order_horz, segment_order_vert;
628 bool req128_horz_wc, req128_vert_wc;
629
630 memset(output, 0, sizeof(*output));
631
632 if (dc->debug.disable_dcc == DCC_DISABLE)
633 return false;
634
635 if (!hubbub->funcs->dcc_support_pixel_format(input->format, &bpe))
636 return false;
637
638 if (!hubbub->funcs->dcc_support_swizzle(input->swizzle_mode, bpe,
639 &segment_order_horz, &segment_order_vert))
640 return false;
641
642 hubbub1_det_request_size(input->surface_size.height, input->surface_size.width,
643 bpe, &req128_horz_wc, &req128_vert_wc);
644
645 if (!req128_horz_wc && !req128_vert_wc) {
646 dcc_control = dcc_control__256_256_xxx;
647 } else if (input->scan == SCAN_DIRECTION_HORIZONTAL) {
648 if (!req128_horz_wc)
649 dcc_control = dcc_control__256_256_xxx;
650 else if (segment_order_horz == segment_order__contiguous)
651 dcc_control = dcc_control__128_128_xxx;
652 else
653 dcc_control = dcc_control__256_64_64;
654 } else if (input->scan == SCAN_DIRECTION_VERTICAL) {
655 if (!req128_vert_wc)
656 dcc_control = dcc_control__256_256_xxx;
657 else if (segment_order_vert == segment_order__contiguous)
658 dcc_control = dcc_control__128_128_xxx;
659 else
660 dcc_control = dcc_control__256_64_64;
661 } else {
662 if ((req128_horz_wc &&
663 segment_order_horz == segment_order__non_contiguous) ||
664 (req128_vert_wc &&
665 segment_order_vert == segment_order__non_contiguous))
666 /* access_dir not known, must use most constraining */
667 dcc_control = dcc_control__256_64_64;
668 else
669 /* reg128 is true for either horz and vert
670 * but segment_order is contiguous
671 */
672 dcc_control = dcc_control__128_128_xxx;
673 }
674
675 if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
676 dcc_control != dcc_control__256_256_xxx)
677 return false;
678
679 switch (dcc_control) {
680 case dcc_control__256_256_xxx:
681 output->grph.rgb.max_uncompressed_blk_size = 256;
682 output->grph.rgb.max_compressed_blk_size = 256;
683 output->grph.rgb.independent_64b_blks = false;
684 break;
685 case dcc_control__128_128_xxx:
686 output->grph.rgb.max_uncompressed_blk_size = 128;
687 output->grph.rgb.max_compressed_blk_size = 128;
688 output->grph.rgb.independent_64b_blks = false;
689 break;
690 case dcc_control__256_64_64:
691 output->grph.rgb.max_uncompressed_blk_size = 256;
692 output->grph.rgb.max_compressed_blk_size = 64;
693 output->grph.rgb.independent_64b_blks = true;
694 break;
695 }
696
697 output->capable = true;
698 output->const_color_support = false;
699
700 return true;
701}
702
479static const struct hubbub_funcs hubbub1_funcs = { 703static const struct hubbub_funcs hubbub1_funcs = {
480 .update_dchub = hubbub1_update_dchub 704 .update_dchub = hubbub1_update_dchub,
705 .dcc_support_swizzle = hubbub1_dcc_support_swizzle,
706 .dcc_support_pixel_format = hubbub1_dcc_support_pixel_format,
707 .get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
481}; 708};
482 709
483void hubbub1_construct(struct hubbub *hubbub, 710void hubbub1_construct(struct hubbub *hubbub,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
index a16e908821a0..6315a0e6b0d6 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
@@ -27,6 +27,7 @@
27#define __DC_HUBBUB_DCN10_H__ 27#define __DC_HUBBUB_DCN10_H__
28 28
29#include "core_types.h" 29#include "core_types.h"
30#include "dchubbub.h"
30 31
31#define HUBHUB_REG_LIST_DCN()\ 32#define HUBHUB_REG_LIST_DCN()\
32 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\ 33 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\
@@ -47,7 +48,8 @@
47 SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND),\ 48 SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND),\
48 SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ 49 SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
49 SR(DCHUBBUB_TEST_DEBUG_INDEX), \ 50 SR(DCHUBBUB_TEST_DEBUG_INDEX), \
50 SR(DCHUBBUB_TEST_DEBUG_DATA) 51 SR(DCHUBBUB_TEST_DEBUG_DATA),\
52 SR(DCHUBBUB_SOFT_RESET)
51 53
52#define HUBBUB_SR_WATERMARK_REG_LIST()\ 54#define HUBBUB_SR_WATERMARK_REG_LIST()\
53 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\ 55 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
@@ -104,6 +106,7 @@ struct dcn_hubbub_registers {
104 uint32_t DCHUBBUB_SDPIF_AGP_BOT; 106 uint32_t DCHUBBUB_SDPIF_AGP_BOT;
105 uint32_t DCHUBBUB_SDPIF_AGP_TOP; 107 uint32_t DCHUBBUB_SDPIF_AGP_TOP;
106 uint32_t DCHUBBUB_CRC_CTRL; 108 uint32_t DCHUBBUB_CRC_CTRL;
109 uint32_t DCHUBBUB_SOFT_RESET;
107}; 110};
108 111
109/* set field name */ 112/* set field name */
@@ -113,6 +116,7 @@ struct dcn_hubbub_registers {
113 116
114#define HUBBUB_MASK_SH_LIST_DCN(mask_sh)\ 117#define HUBBUB_MASK_SH_LIST_DCN(mask_sh)\
115 HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \ 118 HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \
119 HUBBUB_SF(DCHUBBUB_SOFT_RESET, DCHUBBUB_GLOBAL_SOFT_RESET, mask_sh), \
116 HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \ 120 HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \
117 HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \ 121 HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \
118 HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \ 122 HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \
@@ -142,6 +146,7 @@ struct dcn_hubbub_registers {
142 type DCHUBBUB_ARB_SAT_LEVEL;\ 146 type DCHUBBUB_ARB_SAT_LEVEL;\
143 type DCHUBBUB_ARB_MIN_REQ_OUTSTAND;\ 147 type DCHUBBUB_ARB_MIN_REQ_OUTSTAND;\
144 type DCHUBBUB_GLOBAL_TIMER_REFDIV;\ 148 type DCHUBBUB_GLOBAL_TIMER_REFDIV;\
149 type DCHUBBUB_GLOBAL_SOFT_RESET; \
145 type SDPIF_FB_TOP;\ 150 type SDPIF_FB_TOP;\
146 type SDPIF_FB_BASE;\ 151 type SDPIF_FB_BASE;\
147 type SDPIF_FB_OFFSET;\ 152 type SDPIF_FB_OFFSET;\
@@ -173,12 +178,6 @@ struct dcn_hubbub_wm {
173 struct dcn_hubbub_wm_set sets[4]; 178 struct dcn_hubbub_wm_set sets[4];
174}; 179};
175 180
176struct hubbub_funcs {
177 void (*update_dchub)(
178 struct hubbub *hubbub,
179 struct dchub_init_data *dh_data);
180};
181
182struct hubbub { 181struct hubbub {
183 const struct hubbub_funcs *funcs; 182 const struct hubbub_funcs *funcs;
184 struct dc_context *ctx; 183 struct dc_context *ctx;
@@ -206,6 +205,7 @@ void hubbub1_toggle_watermark_change_req(
206void hubbub1_wm_read_state(struct hubbub *hubbub, 205void hubbub1_wm_read_state(struct hubbub *hubbub,
207 struct dcn_hubbub_wm *wm); 206 struct dcn_hubbub_wm *wm);
208 207
208void hubbub1_soft_reset(struct hubbub *hubbub, bool reset);
209void hubbub1_construct(struct hubbub *hubbub, 209void hubbub1_construct(struct hubbub *hubbub,
210 struct dc_context *ctx, 210 struct dc_context *ctx,
211 const struct dcn_hubbub_registers *hubbub_regs, 211 const struct dcn_hubbub_registers *hubbub_regs,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index 39b72f696ae9..d2ab78b35a7a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -78,6 +78,27 @@ static void hubp1_disconnect(struct hubp *hubp)
78 CURSOR_ENABLE, 0); 78 CURSOR_ENABLE, 0);
79} 79}
80 80
81static void hubp1_disable_control(struct hubp *hubp, bool disable_hubp)
82{
83 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
84 uint32_t disable = disable_hubp ? 1 : 0;
85
86 REG_UPDATE(DCHUBP_CNTL,
87 HUBP_DISABLE, disable);
88}
89
90static unsigned int hubp1_get_underflow_status(struct hubp *hubp)
91{
92 uint32_t hubp_underflow = 0;
93 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
94
95 REG_GET(DCHUBP_CNTL,
96 HUBP_UNDERFLOW_STATUS,
97 &hubp_underflow);
98
99 return hubp_underflow;
100}
101
81static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank) 102static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
82{ 103{
83 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); 104 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
@@ -146,6 +167,9 @@ void hubp1_program_size_and_rotation(
146 * 444 or 420 luma 167 * 444 or 420 luma
147 */ 168 */
148 if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { 169 if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
170 ASSERT(plane_size->video.chroma_pitch != 0);
171 /* Chroma pitch zero can cause system hang! */
172
149 pitch = plane_size->video.luma_pitch - 1; 173 pitch = plane_size->video.luma_pitch - 1;
150 meta_pitch = dcc->video.meta_pitch_l - 1; 174 meta_pitch = dcc->video.meta_pitch_l - 1;
151 pitch_c = plane_size->video.chroma_pitch - 1; 175 pitch_c = plane_size->video.chroma_pitch - 1;
@@ -535,11 +559,13 @@ void hubp1_program_deadline(
535 REG_SET(VBLANK_PARAMETERS_3, 0, 559 REG_SET(VBLANK_PARAMETERS_3, 0,
536 REFCYC_PER_META_CHUNK_VBLANK_L, dlg_attr->refcyc_per_meta_chunk_vblank_l); 560 REFCYC_PER_META_CHUNK_VBLANK_L, dlg_attr->refcyc_per_meta_chunk_vblank_l);
537 561
538 REG_SET(NOM_PARAMETERS_0, 0, 562 if (REG(NOM_PARAMETERS_0))
539 DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l); 563 REG_SET(NOM_PARAMETERS_0, 0,
564 DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l);
540 565
541 REG_SET(NOM_PARAMETERS_1, 0, 566 if (REG(NOM_PARAMETERS_1))
542 REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l); 567 REG_SET(NOM_PARAMETERS_1, 0,
568 REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l);
543 569
544 REG_SET(NOM_PARAMETERS_4, 0, 570 REG_SET(NOM_PARAMETERS_4, 0,
545 DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l); 571 DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l);
@@ -568,11 +594,13 @@ void hubp1_program_deadline(
568 REG_SET(VBLANK_PARAMETERS_4, 0, 594 REG_SET(VBLANK_PARAMETERS_4, 0,
569 REFCYC_PER_META_CHUNK_VBLANK_C, dlg_attr->refcyc_per_meta_chunk_vblank_c); 595 REFCYC_PER_META_CHUNK_VBLANK_C, dlg_attr->refcyc_per_meta_chunk_vblank_c);
570 596
571 REG_SET(NOM_PARAMETERS_2, 0, 597 if (REG(NOM_PARAMETERS_2))
572 DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c); 598 REG_SET(NOM_PARAMETERS_2, 0,
599 DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c);
573 600
574 REG_SET(NOM_PARAMETERS_3, 0, 601 if (REG(NOM_PARAMETERS_3))
575 REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c); 602 REG_SET(NOM_PARAMETERS_3, 0,
603 REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c);
576 604
577 REG_SET(NOM_PARAMETERS_6, 0, 605 REG_SET(NOM_PARAMETERS_6, 0,
578 DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c); 606 DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c);
@@ -609,6 +637,13 @@ void hubp1_program_deadline(
609 REG_SET(DCN_SURF1_TTU_CNTL1, 0, 637 REG_SET(DCN_SURF1_TTU_CNTL1, 0,
610 REFCYC_PER_REQ_DELIVERY_PRE, 638 REFCYC_PER_REQ_DELIVERY_PRE,
611 ttu_attr->refcyc_per_req_delivery_pre_c); 639 ttu_attr->refcyc_per_req_delivery_pre_c);
640
641 REG_SET_3(DCN_CUR0_TTU_CNTL0, 0,
642 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_cur0,
643 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_cur0,
644 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_cur0);
645 REG_SET(DCN_CUR0_TTU_CNTL1, 0,
646 REFCYC_PER_REQ_DELIVERY_PRE, ttu_attr->refcyc_per_req_delivery_pre_cur0);
612} 647}
613 648
614static void hubp1_setup( 649static void hubp1_setup(
@@ -752,9 +787,159 @@ void min_set_viewport(
752 PRI_VIEWPORT_Y_START_C, viewport_c->y); 787 PRI_VIEWPORT_Y_START_C, viewport_c->y);
753} 788}
754 789
755void hubp1_read_state(struct dcn10_hubp *hubp1, 790void hubp1_read_state(struct hubp *hubp)
756 struct dcn_hubp_state *s)
757{ 791{
792 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
793 struct dcn_hubp_state *s = &hubp1->state;
794 struct _vcs_dpi_display_dlg_regs_st *dlg_attr = &s->dlg_attr;
795 struct _vcs_dpi_display_ttu_regs_st *ttu_attr = &s->ttu_attr;
796 struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
797
798 /* Requester */
799 REG_GET(HUBPRET_CONTROL,
800 DET_BUF_PLANE1_BASE_ADDRESS, &rq_regs->plane1_base_address);
801 REG_GET_4(DCN_EXPANSION_MODE,
802 DRQ_EXPANSION_MODE, &rq_regs->drq_expansion_mode,
803 PRQ_EXPANSION_MODE, &rq_regs->prq_expansion_mode,
804 MRQ_EXPANSION_MODE, &rq_regs->mrq_expansion_mode,
805 CRQ_EXPANSION_MODE, &rq_regs->crq_expansion_mode);
806 REG_GET_8(DCHUBP_REQ_SIZE_CONFIG,
807 CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size,
808 MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size,
809 META_CHUNK_SIZE, &rq_regs->rq_regs_l.meta_chunk_size,
810 MIN_META_CHUNK_SIZE, &rq_regs->rq_regs_l.min_meta_chunk_size,
811 DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size,
812 MPTE_GROUP_SIZE, &rq_regs->rq_regs_l.mpte_group_size,
813 SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height,
814 PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear);
815 REG_GET_8(DCHUBP_REQ_SIZE_CONFIG_C,
816 CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size,
817 MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size,
818 META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.meta_chunk_size,
819 MIN_META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_meta_chunk_size,
820 DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size,
821 MPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.mpte_group_size,
822 SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height,
823 PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear);
824
825 /* DLG - Per hubp */
826 REG_GET_2(BLANK_OFFSET_0,
827 REFCYC_H_BLANK_END, &dlg_attr->refcyc_h_blank_end,
828 DLG_V_BLANK_END, &dlg_attr->dlg_vblank_end);
829
830 REG_GET(BLANK_OFFSET_1,
831 MIN_DST_Y_NEXT_START, &dlg_attr->min_dst_y_next_start);
832
833 REG_GET(DST_DIMENSIONS,
834 REFCYC_PER_HTOTAL, &dlg_attr->refcyc_per_htotal);
835
836 REG_GET_2(DST_AFTER_SCALER,
837 REFCYC_X_AFTER_SCALER, &dlg_attr->refcyc_x_after_scaler,
838 DST_Y_AFTER_SCALER, &dlg_attr->dst_y_after_scaler);
839
840 if (REG(PREFETCH_SETTINS))
841 REG_GET_2(PREFETCH_SETTINS,
842 DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch,
843 VRATIO_PREFETCH, &dlg_attr->vratio_prefetch);
844 else
845 REG_GET_2(PREFETCH_SETTINGS,
846 DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch,
847 VRATIO_PREFETCH, &dlg_attr->vratio_prefetch);
848
849 REG_GET_2(VBLANK_PARAMETERS_0,
850 DST_Y_PER_VM_VBLANK, &dlg_attr->dst_y_per_vm_vblank,
851 DST_Y_PER_ROW_VBLANK, &dlg_attr->dst_y_per_row_vblank);
852
853 REG_GET(REF_FREQ_TO_PIX_FREQ,
854 REF_FREQ_TO_PIX_FREQ, &dlg_attr->ref_freq_to_pix_freq);
855
856 /* DLG - Per luma/chroma */
857 REG_GET(VBLANK_PARAMETERS_1,
858 REFCYC_PER_PTE_GROUP_VBLANK_L, &dlg_attr->refcyc_per_pte_group_vblank_l);
859
860 REG_GET(VBLANK_PARAMETERS_3,
861 REFCYC_PER_META_CHUNK_VBLANK_L, &dlg_attr->refcyc_per_meta_chunk_vblank_l);
862
863 if (REG(NOM_PARAMETERS_0))
864 REG_GET(NOM_PARAMETERS_0,
865 DST_Y_PER_PTE_ROW_NOM_L, &dlg_attr->dst_y_per_pte_row_nom_l);
866
867 if (REG(NOM_PARAMETERS_1))
868 REG_GET(NOM_PARAMETERS_1,
869 REFCYC_PER_PTE_GROUP_NOM_L, &dlg_attr->refcyc_per_pte_group_nom_l);
870
871 REG_GET(NOM_PARAMETERS_4,
872 DST_Y_PER_META_ROW_NOM_L, &dlg_attr->dst_y_per_meta_row_nom_l);
873
874 REG_GET(NOM_PARAMETERS_5,
875 REFCYC_PER_META_CHUNK_NOM_L, &dlg_attr->refcyc_per_meta_chunk_nom_l);
876
877 REG_GET_2(PER_LINE_DELIVERY_PRE,
878 REFCYC_PER_LINE_DELIVERY_PRE_L, &dlg_attr->refcyc_per_line_delivery_pre_l,
879 REFCYC_PER_LINE_DELIVERY_PRE_C, &dlg_attr->refcyc_per_line_delivery_pre_c);
880
881 REG_GET_2(PER_LINE_DELIVERY,
882 REFCYC_PER_LINE_DELIVERY_L, &dlg_attr->refcyc_per_line_delivery_l,
883 REFCYC_PER_LINE_DELIVERY_C, &dlg_attr->refcyc_per_line_delivery_c);
884
885 if (REG(PREFETCH_SETTINS_C))
886 REG_GET(PREFETCH_SETTINS_C,
887 VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c);
888 else
889 REG_GET(PREFETCH_SETTINGS_C,
890 VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c);
891
892 REG_GET(VBLANK_PARAMETERS_2,
893 REFCYC_PER_PTE_GROUP_VBLANK_C, &dlg_attr->refcyc_per_pte_group_vblank_c);
894
895 REG_GET(VBLANK_PARAMETERS_4,
896 REFCYC_PER_META_CHUNK_VBLANK_C, &dlg_attr->refcyc_per_meta_chunk_vblank_c);
897
898 if (REG(NOM_PARAMETERS_2))
899 REG_GET(NOM_PARAMETERS_2,
900 DST_Y_PER_PTE_ROW_NOM_C, &dlg_attr->dst_y_per_pte_row_nom_c);
901
902 if (REG(NOM_PARAMETERS_3))
903 REG_GET(NOM_PARAMETERS_3,
904 REFCYC_PER_PTE_GROUP_NOM_C, &dlg_attr->refcyc_per_pte_group_nom_c);
905
906 REG_GET(NOM_PARAMETERS_6,
907 DST_Y_PER_META_ROW_NOM_C, &dlg_attr->dst_y_per_meta_row_nom_c);
908
909 REG_GET(NOM_PARAMETERS_7,
910 REFCYC_PER_META_CHUNK_NOM_C, &dlg_attr->refcyc_per_meta_chunk_nom_c);
911
912 /* TTU - per hubp */
913 REG_GET_2(DCN_TTU_QOS_WM,
914 QoS_LEVEL_LOW_WM, &ttu_attr->qos_level_low_wm,
915 QoS_LEVEL_HIGH_WM, &ttu_attr->qos_level_high_wm);
916
917 REG_GET_2(DCN_GLOBAL_TTU_CNTL,
918 MIN_TTU_VBLANK, &ttu_attr->min_ttu_vblank,
919 QoS_LEVEL_FLIP, &ttu_attr->qos_level_flip);
920
921 /* TTU - per luma/chroma */
922 /* Assumed surf0 is luma and 1 is chroma */
923
924 REG_GET_3(DCN_SURF0_TTU_CNTL0,
925 REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_l,
926 QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_l,
927 QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_l);
928
929 REG_GET(DCN_SURF0_TTU_CNTL1,
930 REFCYC_PER_REQ_DELIVERY_PRE,
931 &ttu_attr->refcyc_per_req_delivery_pre_l);
932
933 REG_GET_3(DCN_SURF1_TTU_CNTL0,
934 REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_c,
935 QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_c,
936 QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_c);
937
938 REG_GET(DCN_SURF1_TTU_CNTL1,
939 REFCYC_PER_REQ_DELIVERY_PRE,
940 &ttu_attr->refcyc_per_req_delivery_pre_c);
941
942 /* Rest of hubp */
758 REG_GET(DCSURF_SURFACE_CONFIG, 943 REG_GET(DCSURF_SURFACE_CONFIG,
759 SURFACE_PIXEL_FORMAT, &s->pixel_format); 944 SURFACE_PIXEL_FORMAT, &s->pixel_format);
760 945
@@ -890,14 +1075,14 @@ void hubp1_cursor_set_position(
890 ASSERT(param->h_scale_ratio.value); 1075 ASSERT(param->h_scale_ratio.value);
891 1076
892 if (param->h_scale_ratio.value) 1077 if (param->h_scale_ratio.value)
893 dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div( 1078 dst_x_offset = dc_fixpt_floor(dc_fixpt_div(
894 dal_fixed31_32_from_int(dst_x_offset), 1079 dc_fixpt_from_int(dst_x_offset),
895 param->h_scale_ratio)); 1080 param->h_scale_ratio));
896 1081
897 if (src_x_offset >= (int)param->viewport_width) 1082 if (src_x_offset >= (int)param->viewport_width)
898 cur_en = 0; /* not visible beyond right edge*/ 1083 cur_en = 0; /* not visible beyond right edge*/
899 1084
900 if (src_x_offset + (int)hubp->curs_attr.width < 0) 1085 if (src_x_offset + (int)hubp->curs_attr.width <= 0)
901 cur_en = 0; /* not visible beyond left edge*/ 1086 cur_en = 0; /* not visible beyond left edge*/
902 1087
903 if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) 1088 if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
@@ -952,6 +1137,10 @@ static struct hubp_funcs dcn10_hubp_funcs = {
952 .hubp_disconnect = hubp1_disconnect, 1137 .hubp_disconnect = hubp1_disconnect,
953 .hubp_clk_cntl = hubp1_clk_cntl, 1138 .hubp_clk_cntl = hubp1_clk_cntl,
954 .hubp_vtg_sel = hubp1_vtg_sel, 1139 .hubp_vtg_sel = hubp1_vtg_sel,
1140 .hubp_read_state = hubp1_read_state,
1141 .hubp_disable_control = hubp1_disable_control,
1142 .hubp_get_underflow_status = hubp1_get_underflow_status,
1143
955}; 1144};
956 1145
957/*****************************************/ 1146/*****************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index 4a3703e12ea1..af384034398f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -30,6 +30,7 @@
30#define TO_DCN10_HUBP(hubp)\ 30#define TO_DCN10_HUBP(hubp)\
31 container_of(hubp, struct dcn10_hubp, base) 31 container_of(hubp, struct dcn10_hubp, base)
32 32
33/* Register address initialization macro for all ASICs (including those with reduced functionality) */
33#define HUBP_REG_LIST_DCN(id)\ 34#define HUBP_REG_LIST_DCN(id)\
34 SRI(DCHUBP_CNTL, HUBP, id),\ 35 SRI(DCHUBP_CNTL, HUBP, id),\
35 SRI(HUBPREQ_DEBUG_DB, HUBP, id),\ 36 SRI(HUBPREQ_DEBUG_DB, HUBP, id),\
@@ -78,16 +79,12 @@
78 SRI(REF_FREQ_TO_PIX_FREQ, HUBPREQ, id),\ 79 SRI(REF_FREQ_TO_PIX_FREQ, HUBPREQ, id),\
79 SRI(VBLANK_PARAMETERS_1, HUBPREQ, id),\ 80 SRI(VBLANK_PARAMETERS_1, HUBPREQ, id),\
80 SRI(VBLANK_PARAMETERS_3, HUBPREQ, id),\ 81 SRI(VBLANK_PARAMETERS_3, HUBPREQ, id),\
81 SRI(NOM_PARAMETERS_0, HUBPREQ, id),\
82 SRI(NOM_PARAMETERS_1, HUBPREQ, id),\
83 SRI(NOM_PARAMETERS_4, HUBPREQ, id),\ 82 SRI(NOM_PARAMETERS_4, HUBPREQ, id),\
84 SRI(NOM_PARAMETERS_5, HUBPREQ, id),\ 83 SRI(NOM_PARAMETERS_5, HUBPREQ, id),\
85 SRI(PER_LINE_DELIVERY_PRE, HUBPREQ, id),\ 84 SRI(PER_LINE_DELIVERY_PRE, HUBPREQ, id),\
86 SRI(PER_LINE_DELIVERY, HUBPREQ, id),\ 85 SRI(PER_LINE_DELIVERY, HUBPREQ, id),\
87 SRI(VBLANK_PARAMETERS_2, HUBPREQ, id),\ 86 SRI(VBLANK_PARAMETERS_2, HUBPREQ, id),\
88 SRI(VBLANK_PARAMETERS_4, HUBPREQ, id),\ 87 SRI(VBLANK_PARAMETERS_4, HUBPREQ, id),\
89 SRI(NOM_PARAMETERS_2, HUBPREQ, id),\
90 SRI(NOM_PARAMETERS_3, HUBPREQ, id),\
91 SRI(NOM_PARAMETERS_6, HUBPREQ, id),\ 88 SRI(NOM_PARAMETERS_6, HUBPREQ, id),\
92 SRI(NOM_PARAMETERS_7, HUBPREQ, id),\ 89 SRI(NOM_PARAMETERS_7, HUBPREQ, id),\
93 SRI(DCN_TTU_QOS_WM, HUBPREQ, id),\ 90 SRI(DCN_TTU_QOS_WM, HUBPREQ, id),\
@@ -96,11 +93,21 @@
96 SRI(DCN_SURF0_TTU_CNTL1, HUBPREQ, id),\ 93 SRI(DCN_SURF0_TTU_CNTL1, HUBPREQ, id),\
97 SRI(DCN_SURF1_TTU_CNTL0, HUBPREQ, id),\ 94 SRI(DCN_SURF1_TTU_CNTL0, HUBPREQ, id),\
98 SRI(DCN_SURF1_TTU_CNTL1, HUBPREQ, id),\ 95 SRI(DCN_SURF1_TTU_CNTL1, HUBPREQ, id),\
99 SRI(DCN_VM_MX_L1_TLB_CNTL, HUBPREQ, id),\ 96 SRI(DCN_CUR0_TTU_CNTL0, HUBPREQ, id),\
97 SRI(DCN_CUR0_TTU_CNTL1, HUBPREQ, id),\
100 SRI(HUBP_CLK_CNTL, HUBP, id) 98 SRI(HUBP_CLK_CNTL, HUBP, id)
101 99
100/* Register address initialization macro for ASICs with VM */
101#define HUBP_REG_LIST_DCN_VM(id)\
102 SRI(NOM_PARAMETERS_0, HUBPREQ, id),\
103 SRI(NOM_PARAMETERS_1, HUBPREQ, id),\
104 SRI(NOM_PARAMETERS_2, HUBPREQ, id),\
105 SRI(NOM_PARAMETERS_3, HUBPREQ, id),\
106 SRI(DCN_VM_MX_L1_TLB_CNTL, HUBPREQ, id)
107
102#define HUBP_REG_LIST_DCN10(id)\ 108#define HUBP_REG_LIST_DCN10(id)\
103 HUBP_REG_LIST_DCN(id),\ 109 HUBP_REG_LIST_DCN(id),\
110 HUBP_REG_LIST_DCN_VM(id),\
104 SRI(PREFETCH_SETTINS, HUBPREQ, id),\ 111 SRI(PREFETCH_SETTINS, HUBPREQ, id),\
105 SRI(PREFETCH_SETTINS_C, HUBPREQ, id),\ 112 SRI(PREFETCH_SETTINS_C, HUBPREQ, id),\
106 SRI(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, HUBPREQ, id),\ 113 SRI(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, HUBPREQ, id),\
@@ -198,6 +205,8 @@
198 uint32_t DCN_SURF0_TTU_CNTL1; \ 205 uint32_t DCN_SURF0_TTU_CNTL1; \
199 uint32_t DCN_SURF1_TTU_CNTL0; \ 206 uint32_t DCN_SURF1_TTU_CNTL0; \
200 uint32_t DCN_SURF1_TTU_CNTL1; \ 207 uint32_t DCN_SURF1_TTU_CNTL1; \
208 uint32_t DCN_CUR0_TTU_CNTL0; \
209 uint32_t DCN_CUR0_TTU_CNTL1; \
201 uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB; \ 210 uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB; \
202 uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB; \ 211 uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB; \
203 uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB; \ 212 uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB; \
@@ -237,12 +246,14 @@
237#define HUBP_SF(reg_name, field_name, post_fix)\ 246#define HUBP_SF(reg_name, field_name, post_fix)\
238 .field_name = reg_name ## __ ## field_name ## post_fix 247 .field_name = reg_name ## __ ## field_name ## post_fix
239 248
249/* Mask/shift struct generation macro for all ASICs (including those with reduced functionality) */
240#define HUBP_MASK_SH_LIST_DCN(mask_sh)\ 250#define HUBP_MASK_SH_LIST_DCN(mask_sh)\
241 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_BLANK_EN, mask_sh),\ 251 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_BLANK_EN, mask_sh),\
242 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\ 252 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\
243 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_UNDERFLOW_STATUS, mask_sh),\ 253 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_UNDERFLOW_STATUS, mask_sh),\
244 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, mask_sh),\ 254 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, mask_sh),\
245 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_VTG_SEL, mask_sh),\ 255 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_VTG_SEL, mask_sh),\
256 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_DISABLE, mask_sh),\
246 HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_PIPES, mask_sh),\ 257 HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_PIPES, mask_sh),\
247 HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_BANKS, mask_sh),\ 258 HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_BANKS, mask_sh),\
248 HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, PIPE_INTERLEAVE, mask_sh),\ 259 HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, PIPE_INTERLEAVE, mask_sh),\
@@ -335,8 +346,6 @@
335 HUBP_SF(HUBPREQ0_REF_FREQ_TO_PIX_FREQ, REF_FREQ_TO_PIX_FREQ, mask_sh),\ 346 HUBP_SF(HUBPREQ0_REF_FREQ_TO_PIX_FREQ, REF_FREQ_TO_PIX_FREQ, mask_sh),\
336 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_1, REFCYC_PER_PTE_GROUP_VBLANK_L, mask_sh),\ 347 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_1, REFCYC_PER_PTE_GROUP_VBLANK_L, mask_sh),\
337 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_3, REFCYC_PER_META_CHUNK_VBLANK_L, mask_sh),\ 348 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_3, REFCYC_PER_META_CHUNK_VBLANK_L, mask_sh),\
338 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_0, DST_Y_PER_PTE_ROW_NOM_L, mask_sh),\
339 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_1, REFCYC_PER_PTE_GROUP_NOM_L, mask_sh),\
340 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_4, DST_Y_PER_META_ROW_NOM_L, mask_sh),\ 349 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_4, DST_Y_PER_META_ROW_NOM_L, mask_sh),\
341 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_5, REFCYC_PER_META_CHUNK_NOM_L, mask_sh),\ 350 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_5, REFCYC_PER_META_CHUNK_NOM_L, mask_sh),\
342 HUBP_SF(HUBPREQ0_PER_LINE_DELIVERY_PRE, REFCYC_PER_LINE_DELIVERY_PRE_L, mask_sh),\ 351 HUBP_SF(HUBPREQ0_PER_LINE_DELIVERY_PRE, REFCYC_PER_LINE_DELIVERY_PRE_L, mask_sh),\
@@ -345,8 +354,6 @@
345 HUBP_SF(HUBPREQ0_PER_LINE_DELIVERY, REFCYC_PER_LINE_DELIVERY_C, mask_sh),\ 354 HUBP_SF(HUBPREQ0_PER_LINE_DELIVERY, REFCYC_PER_LINE_DELIVERY_C, mask_sh),\
346 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_2, REFCYC_PER_PTE_GROUP_VBLANK_C, mask_sh),\ 355 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_2, REFCYC_PER_PTE_GROUP_VBLANK_C, mask_sh),\
347 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_4, REFCYC_PER_META_CHUNK_VBLANK_C, mask_sh),\ 356 HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_4, REFCYC_PER_META_CHUNK_VBLANK_C, mask_sh),\
348 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_2, DST_Y_PER_PTE_ROW_NOM_C, mask_sh),\
349 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_3, REFCYC_PER_PTE_GROUP_NOM_C, mask_sh),\
350 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_6, DST_Y_PER_META_ROW_NOM_C, mask_sh),\ 357 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_6, DST_Y_PER_META_ROW_NOM_C, mask_sh),\
351 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_7, REFCYC_PER_META_CHUNK_NOM_C, mask_sh),\ 358 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_7, REFCYC_PER_META_CHUNK_NOM_C, mask_sh),\
352 HUBP_SF(HUBPREQ0_DCN_TTU_QOS_WM, QoS_LEVEL_LOW_WM, mask_sh),\ 359 HUBP_SF(HUBPREQ0_DCN_TTU_QOS_WM, QoS_LEVEL_LOW_WM, mask_sh),\
@@ -357,12 +364,24 @@
357 HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_LEVEL_FIXED, mask_sh),\ 364 HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_LEVEL_FIXED, mask_sh),\
358 HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_RAMP_DISABLE, mask_sh),\ 365 HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_RAMP_DISABLE, mask_sh),\
359 HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh),\ 366 HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh),\
367 HUBP_SF(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh)
368
369/* Mask/shift struct generation macro for ASICs with VM */
370#define HUBP_MASK_SH_LIST_DCN_VM(mask_sh)\
371 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_0, DST_Y_PER_PTE_ROW_NOM_L, mask_sh),\
372 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_1, REFCYC_PER_PTE_GROUP_NOM_L, mask_sh),\
373 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_2, DST_Y_PER_PTE_ROW_NOM_C, mask_sh),\
374 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_3, REFCYC_PER_PTE_GROUP_NOM_C, mask_sh),\
360 HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, mask_sh),\ 375 HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, mask_sh),\
361 HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, mask_sh),\ 376 HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, mask_sh),\
362 HUBP_SF(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh) 377 HUBP_SF(HUBPREQ0_DCN_CUR0_TTU_CNTL0, REFCYC_PER_REQ_DELIVERY, mask_sh),\
378 HUBP_SF(HUBPREQ0_DCN_CUR0_TTU_CNTL0, QoS_LEVEL_FIXED, mask_sh),\
379 HUBP_SF(HUBPREQ0_DCN_CUR0_TTU_CNTL0, QoS_RAMP_DISABLE, mask_sh),\
380 HUBP_SF(HUBPREQ0_DCN_CUR0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh)
363 381
364#define HUBP_MASK_SH_LIST_DCN10(mask_sh)\ 382#define HUBP_MASK_SH_LIST_DCN10(mask_sh)\
365 HUBP_MASK_SH_LIST_DCN(mask_sh),\ 383 HUBP_MASK_SH_LIST_DCN(mask_sh),\
384 HUBP_MASK_SH_LIST_DCN_VM(mask_sh),\
366 HUBP_SF(HUBPREQ0_PREFETCH_SETTINS, DST_Y_PREFETCH, mask_sh),\ 385 HUBP_SF(HUBPREQ0_PREFETCH_SETTINS, DST_Y_PREFETCH, mask_sh),\
367 HUBP_SF(HUBPREQ0_PREFETCH_SETTINS, VRATIO_PREFETCH, mask_sh),\ 386 HUBP_SF(HUBPREQ0_PREFETCH_SETTINS, VRATIO_PREFETCH, mask_sh),\
368 HUBP_SF(HUBPREQ0_PREFETCH_SETTINS_C, VRATIO_PREFETCH_C, mask_sh),\ 387 HUBP_SF(HUBPREQ0_PREFETCH_SETTINS_C, VRATIO_PREFETCH_C, mask_sh),\
@@ -403,6 +422,7 @@
403 422
404#define DCN_HUBP_REG_FIELD_LIST(type) \ 423#define DCN_HUBP_REG_FIELD_LIST(type) \
405 type HUBP_BLANK_EN;\ 424 type HUBP_BLANK_EN;\
425 type HUBP_DISABLE;\
406 type HUBP_TTU_DISABLE;\ 426 type HUBP_TTU_DISABLE;\
407 type HUBP_NO_OUTSTANDING_REQ;\ 427 type HUBP_NO_OUTSTANDING_REQ;\
408 type HUBP_VTG_SEL;\ 428 type HUBP_VTG_SEL;\
@@ -601,8 +621,29 @@ struct dcn_mi_mask {
601 DCN_HUBP_REG_FIELD_LIST(uint32_t); 621 DCN_HUBP_REG_FIELD_LIST(uint32_t);
602}; 622};
603 623
624struct dcn_hubp_state {
625 struct _vcs_dpi_display_dlg_regs_st dlg_attr;
626 struct _vcs_dpi_display_ttu_regs_st ttu_attr;
627 struct _vcs_dpi_display_rq_regs_st rq_regs;
628 uint32_t pixel_format;
629 uint32_t inuse_addr_hi;
630 uint32_t viewport_width;
631 uint32_t viewport_height;
632 uint32_t rotation_angle;
633 uint32_t h_mirror_en;
634 uint32_t sw_mode;
635 uint32_t dcc_en;
636 uint32_t blank_en;
637 uint32_t underflow_status;
638 uint32_t ttu_disable;
639 uint32_t min_ttu_vblank;
640 uint32_t qos_level_low_wm;
641 uint32_t qos_level_high_wm;
642};
643
604struct dcn10_hubp { 644struct dcn10_hubp {
605 struct hubp base; 645 struct hubp base;
646 struct dcn_hubp_state state;
606 const struct dcn_mi_registers *hubp_regs; 647 const struct dcn_mi_registers *hubp_regs;
607 const struct dcn_mi_shift *hubp_shift; 648 const struct dcn_mi_shift *hubp_shift;
608 const struct dcn_mi_mask *hubp_mask; 649 const struct dcn_mi_mask *hubp_mask;
@@ -680,26 +721,9 @@ void dcn10_hubp_construct(
680 const struct dcn_mi_shift *hubp_shift, 721 const struct dcn_mi_shift *hubp_shift,
681 const struct dcn_mi_mask *hubp_mask); 722 const struct dcn_mi_mask *hubp_mask);
682 723
683 724void hubp1_read_state(struct hubp *hubp);
684struct dcn_hubp_state {
685 uint32_t pixel_format;
686 uint32_t inuse_addr_hi;
687 uint32_t viewport_width;
688 uint32_t viewport_height;
689 uint32_t rotation_angle;
690 uint32_t h_mirror_en;
691 uint32_t sw_mode;
692 uint32_t dcc_en;
693 uint32_t blank_en;
694 uint32_t underflow_status;
695 uint32_t ttu_disable;
696 uint32_t min_ttu_vblank;
697 uint32_t qos_level_low_wm;
698 uint32_t qos_level_high_wm;
699};
700void hubp1_read_state(struct dcn10_hubp *hubp1,
701 struct dcn_hubp_state *s);
702 725
703enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch); 726enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch);
704 727
728
705#endif 729#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 8b0f6b8a5627..f8e0576af6e0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -45,8 +45,8 @@
45#include "dcn10_hubbub.h" 45#include "dcn10_hubbub.h"
46#include "dcn10_cm_common.h" 46#include "dcn10_cm_common.h"
47 47
48#define DC_LOGGER \ 48#define DC_LOGGER_INIT(logger)
49 ctx->logger 49
50#define CTX \ 50#define CTX \
51 hws->ctx 51 hws->ctx
52#define REG(reg)\ 52#define REG(reg)\
@@ -56,16 +56,17 @@
56#define FN(reg_name, field_name) \ 56#define FN(reg_name, field_name) \
57 hws->shifts->field_name, hws->masks->field_name 57 hws->shifts->field_name, hws->masks->field_name
58 58
59/*print is 17 wide, first two characters are spaces*/
59#define DTN_INFO_MICRO_SEC(ref_cycle) \ 60#define DTN_INFO_MICRO_SEC(ref_cycle) \
60 print_microsec(dc_ctx, ref_cycle) 61 print_microsec(dc_ctx, ref_cycle)
61 62
62void print_microsec(struct dc_context *dc_ctx, uint32_t ref_cycle) 63void print_microsec(struct dc_context *dc_ctx, uint32_t ref_cycle)
63{ 64{
64 static const uint32_t ref_clk_mhz = 48; 65 const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clock_inKhz / 1000;
65 static const unsigned int frac = 10; 66 static const unsigned int frac = 1000;
66 uint32_t us_x10 = (ref_cycle * frac) / ref_clk_mhz; 67 uint32_t us_x10 = (ref_cycle * frac) / ref_clk_mhz;
67 68
68 DTN_INFO("%d.%d \t ", 69 DTN_INFO(" %11d.%03d",
69 us_x10 / frac, 70 us_x10 / frac,
70 us_x10 % frac); 71 us_x10 % frac);
71} 72}
@@ -92,14 +93,14 @@ void dcn10_log_hubbub_state(struct dc *dc)
92 93
93 hubbub1_wm_read_state(dc->res_pool->hubbub, &wm); 94 hubbub1_wm_read_state(dc->res_pool->hubbub, &wm);
94 95
95 DTN_INFO("HUBBUB WM: \t data_urgent \t pte_meta_urgent \t " 96 DTN_INFO("HUBBUB WM: data_urgent pte_meta_urgent"
96 "sr_enter \t sr_exit \t dram_clk_change \n"); 97 " sr_enter sr_exit dram_clk_change\n");
97 98
98 for (i = 0; i < 4; i++) { 99 for (i = 0; i < 4; i++) {
99 struct dcn_hubbub_wm_set *s; 100 struct dcn_hubbub_wm_set *s;
100 101
101 s = &wm.sets[i]; 102 s = &wm.sets[i];
102 DTN_INFO("WM_Set[%d]:\t ", s->wm_set); 103 DTN_INFO("WM_Set[%d]:", s->wm_set);
103 DTN_INFO_MICRO_SEC(s->data_urgent); 104 DTN_INFO_MICRO_SEC(s->data_urgent);
104 DTN_INFO_MICRO_SEC(s->pte_meta_urgent); 105 DTN_INFO_MICRO_SEC(s->pte_meta_urgent);
105 DTN_INFO_MICRO_SEC(s->sr_enter); 106 DTN_INFO_MICRO_SEC(s->sr_enter);
@@ -111,6 +112,121 @@ void dcn10_log_hubbub_state(struct dc *dc)
111 DTN_INFO("\n"); 112 DTN_INFO("\n");
112} 113}
113 114
115static void dcn10_log_hubp_states(struct dc *dc)
116{
117 struct dc_context *dc_ctx = dc->ctx;
118 struct resource_pool *pool = dc->res_pool;
119 int i;
120
121 DTN_INFO("HUBP: format addr_hi width height"
122 " rot mir sw_mode dcc_en blank_en ttu_dis underflow"
123 " min_ttu_vblank qos_low_wm qos_high_wm\n");
124 for (i = 0; i < pool->pipe_count; i++) {
125 struct hubp *hubp = pool->hubps[i];
126 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
127
128 hubp->funcs->hubp_read_state(hubp);
129
130 if (!s->blank_en) {
131 DTN_INFO("[%2d]: %5xh %6xh %5d %6d %2xh %2xh %6xh"
132 " %6d %8d %7d %8xh",
133 hubp->inst,
134 s->pixel_format,
135 s->inuse_addr_hi,
136 s->viewport_width,
137 s->viewport_height,
138 s->rotation_angle,
139 s->h_mirror_en,
140 s->sw_mode,
141 s->dcc_en,
142 s->blank_en,
143 s->ttu_disable,
144 s->underflow_status);
145 DTN_INFO_MICRO_SEC(s->min_ttu_vblank);
146 DTN_INFO_MICRO_SEC(s->qos_level_low_wm);
147 DTN_INFO_MICRO_SEC(s->qos_level_high_wm);
148 DTN_INFO("\n");
149 }
150 }
151
152 DTN_INFO("\n=========RQ========\n");
153 DTN_INFO("HUBP: drq_exp_m prq_exp_m mrq_exp_m crq_exp_m plane1_ba L:chunk_s min_chu_s meta_ch_s"
154 " min_m_c_s dpte_gr_s mpte_gr_s swath_hei pte_row_h C:chunk_s min_chu_s meta_ch_s"
155 " min_m_c_s dpte_gr_s mpte_gr_s swath_hei pte_row_h\n");
156 for (i = 0; i < pool->pipe_count; i++) {
157 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
158 struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
159
160 if (!s->blank_en)
161 DTN_INFO("[%2d]: %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh\n",
162 pool->hubps[i]->inst, rq_regs->drq_expansion_mode, rq_regs->prq_expansion_mode, rq_regs->mrq_expansion_mode,
163 rq_regs->crq_expansion_mode, rq_regs->plane1_base_address, rq_regs->rq_regs_l.chunk_size,
164 rq_regs->rq_regs_l.min_chunk_size, rq_regs->rq_regs_l.meta_chunk_size,
165 rq_regs->rq_regs_l.min_meta_chunk_size, rq_regs->rq_regs_l.dpte_group_size,
166 rq_regs->rq_regs_l.mpte_group_size, rq_regs->rq_regs_l.swath_height,
167 rq_regs->rq_regs_l.pte_row_height_linear, rq_regs->rq_regs_c.chunk_size, rq_regs->rq_regs_c.min_chunk_size,
168 rq_regs->rq_regs_c.meta_chunk_size, rq_regs->rq_regs_c.min_meta_chunk_size,
169 rq_regs->rq_regs_c.dpte_group_size, rq_regs->rq_regs_c.mpte_group_size,
170 rq_regs->rq_regs_c.swath_height, rq_regs->rq_regs_c.pte_row_height_linear);
171 }
172
173 DTN_INFO("========DLG========\n");
174 DTN_INFO("HUBP: rc_hbe dlg_vbe min_d_y_n rc_per_ht rc_x_a_s "
175 " dst_y_a_s dst_y_pf dst_y_vvb dst_y_rvb dst_y_vfl dst_y_rfl rf_pix_fq"
176 " vratio_pf vrat_pf_c rc_pg_vbl rc_pg_vbc rc_mc_vbl rc_mc_vbc rc_pg_fll"
177 " rc_pg_flc rc_mc_fll rc_mc_flc pr_nom_l pr_nom_c rc_pg_nl rc_pg_nc "
178 " mr_nom_l mr_nom_c rc_mc_nl rc_mc_nc rc_ld_pl rc_ld_pc rc_ld_l "
179 " rc_ld_c cha_cur0 ofst_cur1 cha_cur1 vr_af_vc0 ddrq_limt x_rt_dlay"
180 " x_rp_dlay x_rr_sfl\n");
181 for (i = 0; i < pool->pipe_count; i++) {
182 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
183 struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr;
184
185 if (!s->blank_en)
186 DTN_INFO("[%2d]: %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh"
187 "% 8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh"
188 " %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh\n",
189 pool->hubps[i]->inst, dlg_regs->refcyc_h_blank_end, dlg_regs->dlg_vblank_end, dlg_regs->min_dst_y_next_start,
190 dlg_regs->refcyc_per_htotal, dlg_regs->refcyc_x_after_scaler, dlg_regs->dst_y_after_scaler,
191 dlg_regs->dst_y_prefetch, dlg_regs->dst_y_per_vm_vblank, dlg_regs->dst_y_per_row_vblank,
192 dlg_regs->dst_y_per_vm_flip, dlg_regs->dst_y_per_row_flip, dlg_regs->ref_freq_to_pix_freq,
193 dlg_regs->vratio_prefetch, dlg_regs->vratio_prefetch_c, dlg_regs->refcyc_per_pte_group_vblank_l,
194 dlg_regs->refcyc_per_pte_group_vblank_c, dlg_regs->refcyc_per_meta_chunk_vblank_l,
195 dlg_regs->refcyc_per_meta_chunk_vblank_c, dlg_regs->refcyc_per_pte_group_flip_l,
196 dlg_regs->refcyc_per_pte_group_flip_c, dlg_regs->refcyc_per_meta_chunk_flip_l,
197 dlg_regs->refcyc_per_meta_chunk_flip_c, dlg_regs->dst_y_per_pte_row_nom_l,
198 dlg_regs->dst_y_per_pte_row_nom_c, dlg_regs->refcyc_per_pte_group_nom_l,
199 dlg_regs->refcyc_per_pte_group_nom_c, dlg_regs->dst_y_per_meta_row_nom_l,
200 dlg_regs->dst_y_per_meta_row_nom_c, dlg_regs->refcyc_per_meta_chunk_nom_l,
201 dlg_regs->refcyc_per_meta_chunk_nom_c, dlg_regs->refcyc_per_line_delivery_pre_l,
202 dlg_regs->refcyc_per_line_delivery_pre_c, dlg_regs->refcyc_per_line_delivery_l,
203 dlg_regs->refcyc_per_line_delivery_c, dlg_regs->chunk_hdl_adjust_cur0, dlg_regs->dst_y_offset_cur1,
204 dlg_regs->chunk_hdl_adjust_cur1, dlg_regs->vready_after_vcount0, dlg_regs->dst_y_delta_drq_limit,
205 dlg_regs->xfc_reg_transfer_delay, dlg_regs->xfc_reg_precharge_delay,
206 dlg_regs->xfc_reg_remote_surface_flip_latency);
207 }
208
209 DTN_INFO("========TTU========\n");
210 DTN_INFO("HUBP: qos_ll_wm qos_lh_wm mn_ttu_vb qos_l_flp rc_rd_p_l rc_rd_l rc_rd_p_c"
211 " rc_rd_c rc_rd_c0 rc_rd_pc0 rc_rd_c1 rc_rd_pc1 qos_lf_l qos_rds_l"
212 " qos_lf_c qos_rds_c qos_lf_c0 qos_rds_c0 qos_lf_c1 qos_rds_c1\n");
213 for (i = 0; i < pool->pipe_count; i++) {
214 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
215 struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &s->ttu_attr;
216
217 if (!s->blank_en)
218 DTN_INFO("[%2d]: %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh\n",
219 pool->hubps[i]->inst, ttu_regs->qos_level_low_wm, ttu_regs->qos_level_high_wm, ttu_regs->min_ttu_vblank,
220 ttu_regs->qos_level_flip, ttu_regs->refcyc_per_req_delivery_pre_l, ttu_regs->refcyc_per_req_delivery_l,
221 ttu_regs->refcyc_per_req_delivery_pre_c, ttu_regs->refcyc_per_req_delivery_c, ttu_regs->refcyc_per_req_delivery_cur0,
222 ttu_regs->refcyc_per_req_delivery_pre_cur0, ttu_regs->refcyc_per_req_delivery_cur1,
223 ttu_regs->refcyc_per_req_delivery_pre_cur1, ttu_regs->qos_level_fixed_l, ttu_regs->qos_ramp_disable_l,
224 ttu_regs->qos_level_fixed_c, ttu_regs->qos_ramp_disable_c, ttu_regs->qos_level_fixed_cur0,
225 ttu_regs->qos_ramp_disable_cur0, ttu_regs->qos_level_fixed_cur1, ttu_regs->qos_ramp_disable_cur1);
226 }
227 DTN_INFO("\n");
228}
229
114void dcn10_log_hw_state(struct dc *dc) 230void dcn10_log_hw_state(struct dc *dc)
115{ 231{
116 struct dc_context *dc_ctx = dc->ctx; 232 struct dc_context *dc_ctx = dc->ctx;
@@ -121,41 +237,64 @@ void dcn10_log_hw_state(struct dc *dc)
121 237
122 dcn10_log_hubbub_state(dc); 238 dcn10_log_hubbub_state(dc);
123 239
124 DTN_INFO("HUBP:\t format \t addr_hi \t width \t height \t " 240 dcn10_log_hubp_states(dc);
125 "rotation \t mirror \t sw_mode \t "
126 "dcc_en \t blank_en \t ttu_dis \t underflow \t "
127 "min_ttu_vblank \t qos_low_wm \t qos_high_wm \n");
128 241
242 DTN_INFO("DPP: IGAM format IGAM mode DGAM mode RGAM mode"
243 " GAMUT mode C11 C12 C13 C14 C21 C22 C23 C24 "
244 "C31 C32 C33 C34\n");
129 for (i = 0; i < pool->pipe_count; i++) { 245 for (i = 0; i < pool->pipe_count; i++) {
130 struct hubp *hubp = pool->hubps[i]; 246 struct dpp *dpp = pool->dpps[i];
131 struct dcn_hubp_state s; 247 struct dcn_dpp_state s;
132 248
133 hubp1_read_state(TO_DCN10_HUBP(hubp), &s); 249 dpp->funcs->dpp_read_state(dpp, &s);
134 250
135 DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t " 251 DTN_INFO("[%2d]: %11xh %-11s %-11s %-11s"
136 "%xh \t %xh \t %xh \t " 252 "%8x %08xh %08xh %08xh %08xh %08xh %08xh",
137 "%d \t %d \t %d \t %xh \t", 253 dpp->inst,
138 hubp->inst, 254 s.igam_input_format,
139 s.pixel_format, 255 (s.igam_lut_mode == 0) ? "BypassFixed" :
140 s.inuse_addr_hi, 256 ((s.igam_lut_mode == 1) ? "BypassFloat" :
141 s.viewport_width, 257 ((s.igam_lut_mode == 2) ? "RAM" :
142 s.viewport_height, 258 ((s.igam_lut_mode == 3) ? "RAM" :
143 s.rotation_angle, 259 "Unknown"))),
144 s.h_mirror_en, 260 (s.dgam_lut_mode == 0) ? "Bypass" :
145 s.sw_mode, 261 ((s.dgam_lut_mode == 1) ? "sRGB" :
146 s.dcc_en, 262 ((s.dgam_lut_mode == 2) ? "Ycc" :
147 s.blank_en, 263 ((s.dgam_lut_mode == 3) ? "RAM" :
148 s.ttu_disable, 264 ((s.dgam_lut_mode == 4) ? "RAM" :
149 s.underflow_status); 265 "Unknown")))),
150 DTN_INFO_MICRO_SEC(s.min_ttu_vblank); 266 (s.rgam_lut_mode == 0) ? "Bypass" :
151 DTN_INFO_MICRO_SEC(s.qos_level_low_wm); 267 ((s.rgam_lut_mode == 1) ? "sRGB" :
152 DTN_INFO_MICRO_SEC(s.qos_level_high_wm); 268 ((s.rgam_lut_mode == 2) ? "Ycc" :
269 ((s.rgam_lut_mode == 3) ? "RAM" :
270 ((s.rgam_lut_mode == 4) ? "RAM" :
271 "Unknown")))),
272 s.gamut_remap_mode,
273 s.gamut_remap_c11_c12,
274 s.gamut_remap_c13_c14,
275 s.gamut_remap_c21_c22,
276 s.gamut_remap_c23_c24,
277 s.gamut_remap_c31_c32,
278 s.gamut_remap_c33_c34);
153 DTN_INFO("\n"); 279 DTN_INFO("\n");
154 } 280 }
155 DTN_INFO("\n"); 281 DTN_INFO("\n");
156 282
157 DTN_INFO("OTG:\t v_bs \t v_be \t v_ss \t v_se \t vpol \t vmax \t vmin \t " 283 DTN_INFO("MPCC: OPP DPP MPCCBOT MODE ALPHA_MODE PREMULT OVERLAP_ONLY IDLE\n");
158 "h_bs \t h_be \t h_ss \t h_se \t hpol \t htot \t vtot \t underflow\n"); 284 for (i = 0; i < pool->pipe_count; i++) {
285 struct mpcc_state s = {0};
286
287 pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s);
288 if (s.opp_id != 0xf)
289 DTN_INFO("[%2d]: %2xh %2xh %6xh %4d %10d %7d %12d %4d\n",
290 i, s.opp_id, s.dpp_id, s.bot_mpcc_id,
291 s.mode, s.alpha_mode, s.pre_multiplied_alpha, s.overlap_only,
292 s.idle);
293 }
294 DTN_INFO("\n");
295
296 DTN_INFO("OTG: v_bs v_be v_ss v_se vpol vmax vmin vmax_sel vmin_sel"
297 " h_bs h_be h_ss h_se hpol htot vtot underflow\n");
159 298
160 for (i = 0; i < pool->timing_generator_count; i++) { 299 for (i = 0; i < pool->timing_generator_count; i++) {
161 struct timing_generator *tg = pool->timing_generators[i]; 300 struct timing_generator *tg = pool->timing_generators[i];
@@ -167,9 +306,8 @@ void dcn10_log_hw_state(struct dc *dc)
167 if ((s.otg_enabled & 1) == 0) 306 if ((s.otg_enabled & 1) == 0)
168 continue; 307 continue;
169 308
170 DTN_INFO("[%d]:\t %d \t %d \t %d \t %d \t " 309 DTN_INFO("[%d]: %5d %5d %5d %5d %5d %5d %5d %9d %9d %5d %5d %5d"
171 "%d \t %d \t %d \t %d \t %d \t %d \t " 310 " %5d %5d %5d %5d %9d\n",
172 "%d \t %d \t %d \t %d \t %d \t ",
173 tg->inst, 311 tg->inst,
174 s.v_blank_start, 312 s.v_blank_start,
175 s.v_blank_end, 313 s.v_blank_end,
@@ -178,6 +316,8 @@ void dcn10_log_hw_state(struct dc *dc)
178 s.v_sync_a_pol, 316 s.v_sync_a_pol,
179 s.v_total_max, 317 s.v_total_max,
180 s.v_total_min, 318 s.v_total_min,
319 s.v_total_max_sel,
320 s.v_total_min_sel,
181 s.h_blank_start, 321 s.h_blank_start,
182 s.h_blank_end, 322 s.h_blank_end,
183 s.h_sync_a_start, 323 s.h_sync_a_start,
@@ -186,10 +326,25 @@ void dcn10_log_hw_state(struct dc *dc)
186 s.h_total, 326 s.h_total,
187 s.v_total, 327 s.v_total,
188 s.underflow_occurred_status); 328 s.underflow_occurred_status);
189 DTN_INFO("\n"); 329
330 // Clear underflow for debug purposes
331 // We want to keep underflow sticky bit on for the longevity tests outside of test environment.
332 // This function is called only from Windows or Diags test environment, hence it's safe to clear
333 // it from here without affecting the original intent.
334 tg->funcs->clear_optc_underflow(tg);
190 } 335 }
191 DTN_INFO("\n"); 336 DTN_INFO("\n");
192 337
338 DTN_INFO("\nCALCULATED Clocks: dcfclk_khz:%d dcfclk_deep_sleep_khz:%d dispclk_khz:%d\n"
339 "dppclk_khz:%d max_supported_dppclk_khz:%d fclk_khz:%d socclk_khz:%d\n\n",
340 dc->current_state->bw.dcn.calc_clk.dcfclk_khz,
341 dc->current_state->bw.dcn.calc_clk.dcfclk_deep_sleep_khz,
342 dc->current_state->bw.dcn.calc_clk.dispclk_khz,
343 dc->current_state->bw.dcn.calc_clk.dppclk_khz,
344 dc->current_state->bw.dcn.calc_clk.max_supported_dppclk_khz,
345 dc->current_state->bw.dcn.calc_clk.fclk_khz,
346 dc->current_state->bw.dcn.calc_clk.socclk_khz);
347
193 log_mpc_crc(dc); 348 log_mpc_crc(dc);
194 349
195 DTN_INFO_END(); 350 DTN_INFO_END();
@@ -354,7 +509,7 @@ static void power_on_plane(
354 struct dce_hwseq *hws, 509 struct dce_hwseq *hws,
355 int plane_id) 510 int plane_id)
356{ 511{
357 struct dc_context *ctx = hws->ctx; 512 DC_LOGGER_INIT(hws->ctx->logger);
358 if (REG(DC_IP_REQUEST_CNTL)) { 513 if (REG(DC_IP_REQUEST_CNTL)) {
359 REG_SET(DC_IP_REQUEST_CNTL, 0, 514 REG_SET(DC_IP_REQUEST_CNTL, 0,
360 IP_REQUEST_EN, 1); 515 IP_REQUEST_EN, 1);
@@ -461,7 +616,7 @@ static void false_optc_underflow_wa(
461 tg->funcs->clear_optc_underflow(tg); 616 tg->funcs->clear_optc_underflow(tg);
462} 617}
463 618
464static enum dc_status dcn10_prog_pixclk_crtc_otg( 619static enum dc_status dcn10_enable_stream_timing(
465 struct pipe_ctx *pipe_ctx, 620 struct pipe_ctx *pipe_ctx,
466 struct dc_state *context, 621 struct dc_state *context,
467 struct dc *dc) 622 struct dc *dc)
@@ -553,7 +708,7 @@ static void reset_back_end_for_pipe(
553 struct dc_state *context) 708 struct dc_state *context)
554{ 709{
555 int i; 710 int i;
556 struct dc_context *ctx = dc->ctx; 711 DC_LOGGER_INIT(dc->ctx->logger);
557 if (pipe_ctx->stream_res.stream_enc == NULL) { 712 if (pipe_ctx->stream_res.stream_enc == NULL) {
558 pipe_ctx->stream = NULL; 713 pipe_ctx->stream = NULL;
559 return; 714 return;
@@ -603,6 +758,90 @@ static void reset_back_end_for_pipe(
603 pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst); 758 pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);
604} 759}
605 760
761static bool dcn10_hw_wa_force_recovery(struct dc *dc)
762{
763 struct hubp *hubp ;
764 unsigned int i;
765 bool need_recover = true;
766
767 if (!dc->debug.recovery_enabled)
768 return false;
769
770 for (i = 0; i < dc->res_pool->pipe_count; i++) {
771 struct pipe_ctx *pipe_ctx =
772 &dc->current_state->res_ctx.pipe_ctx[i];
773 if (pipe_ctx != NULL) {
774 hubp = pipe_ctx->plane_res.hubp;
775 if (hubp != NULL) {
776 if (hubp->funcs->hubp_get_underflow_status(hubp) != 0) {
777 /* one pipe underflow, we will reset all the pipes*/
778 need_recover = true;
779 }
780 }
781 }
782 }
783 if (!need_recover)
784 return false;
785 /*
786 DCHUBP_CNTL:HUBP_BLANK_EN=1
787 DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=1
788 DCHUBP_CNTL:HUBP_DISABLE=1
789 DCHUBP_CNTL:HUBP_DISABLE=0
790 DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=0
791 DCSURF_PRIMARY_SURFACE_ADDRESS
792 DCHUBP_CNTL:HUBP_BLANK_EN=0
793 */
794
795 for (i = 0; i < dc->res_pool->pipe_count; i++) {
796 struct pipe_ctx *pipe_ctx =
797 &dc->current_state->res_ctx.pipe_ctx[i];
798 if (pipe_ctx != NULL) {
799 hubp = pipe_ctx->plane_res.hubp;
800 /*DCHUBP_CNTL:HUBP_BLANK_EN=1*/
801 if (hubp != NULL)
802 hubp->funcs->set_hubp_blank_en(hubp, true);
803 }
804 }
805 /*DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=1*/
806 hubbub1_soft_reset(dc->res_pool->hubbub, true);
807
808 for (i = 0; i < dc->res_pool->pipe_count; i++) {
809 struct pipe_ctx *pipe_ctx =
810 &dc->current_state->res_ctx.pipe_ctx[i];
811 if (pipe_ctx != NULL) {
812 hubp = pipe_ctx->plane_res.hubp;
813 /*DCHUBP_CNTL:HUBP_DISABLE=1*/
814 if (hubp != NULL)
815 hubp->funcs->hubp_disable_control(hubp, true);
816 }
817 }
818 for (i = 0; i < dc->res_pool->pipe_count; i++) {
819 struct pipe_ctx *pipe_ctx =
820 &dc->current_state->res_ctx.pipe_ctx[i];
821 if (pipe_ctx != NULL) {
822 hubp = pipe_ctx->plane_res.hubp;
823 /*DCHUBP_CNTL:HUBP_DISABLE=0*/
824 if (hubp != NULL)
825 hubp->funcs->hubp_disable_control(hubp, true);
826 }
827 }
828 /*DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=0*/
829 hubbub1_soft_reset(dc->res_pool->hubbub, false);
830 for (i = 0; i < dc->res_pool->pipe_count; i++) {
831 struct pipe_ctx *pipe_ctx =
832 &dc->current_state->res_ctx.pipe_ctx[i];
833 if (pipe_ctx != NULL) {
834 hubp = pipe_ctx->plane_res.hubp;
835 /*DCHUBP_CNTL:HUBP_BLANK_EN=0*/
836 if (hubp != NULL)
837 hubp->funcs->set_hubp_blank_en(hubp, true);
838 }
839 }
840 return true;
841
842}
843
844
606static void dcn10_verify_allow_pstate_change_high(struct dc *dc) 845static void dcn10_verify_allow_pstate_change_high(struct dc *dc)
607{ 846{
608 static bool should_log_hw_state; /* prevent hw state log by default */ 847 static bool should_log_hw_state; /* prevent hw state log by default */
@@ -611,13 +850,17 @@ static void dcn10_verify_allow_pstate_change_high(struct dc *dc)
611 if (should_log_hw_state) { 850 if (should_log_hw_state) {
612 dcn10_log_hw_state(dc); 851 dcn10_log_hw_state(dc);
613 } 852 }
614
615 BREAK_TO_DEBUGGER(); 853 BREAK_TO_DEBUGGER();
854 if (dcn10_hw_wa_force_recovery(dc)) {
855 /*check again*/
856 if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub))
857 BREAK_TO_DEBUGGER();
858 }
616 } 859 }
617} 860}
618 861
619/* trigger HW to start disconnect plane from stream on the next vsync */ 862/* trigger HW to start disconnect plane from stream on the next vsync */
620static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx) 863void hwss1_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
621{ 864{
622 struct hubp *hubp = pipe_ctx->plane_res.hubp; 865 struct hubp *hubp = pipe_ctx->plane_res.hubp;
623 int dpp_id = pipe_ctx->plane_res.dpp->inst; 866 int dpp_id = pipe_ctx->plane_res.dpp->inst;
@@ -649,7 +892,7 @@ static void plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx)
649{ 892{
650 struct dce_hwseq *hws = dc->hwseq; 893 struct dce_hwseq *hws = dc->hwseq;
651 struct dpp *dpp = pipe_ctx->plane_res.dpp; 894 struct dpp *dpp = pipe_ctx->plane_res.dpp;
652 struct dc_context *ctx = dc->ctx; 895 DC_LOGGER_INIT(dc->ctx->logger);
653 896
654 if (REG(DC_IP_REQUEST_CNTL)) { 897 if (REG(DC_IP_REQUEST_CNTL)) {
655 REG_SET(DC_IP_REQUEST_CNTL, 0, 898 REG_SET(DC_IP_REQUEST_CNTL, 0,
@@ -699,7 +942,7 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
699 942
700static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) 943static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
701{ 944{
702 struct dc_context *ctx = dc->ctx; 945 DC_LOGGER_INIT(dc->ctx->logger);
703 946
704 if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated) 947 if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
705 return; 948 return;
@@ -800,7 +1043,7 @@ static void dcn10_init_hw(struct dc *dc)
800 dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; 1043 dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
801 pipe_ctx->stream_res.opp = dc->res_pool->opps[i]; 1044 pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
802 1045
803 plane_atomic_disconnect(dc, pipe_ctx); 1046 hwss1_plane_atomic_disconnect(dc, pipe_ctx);
804 } 1047 }
805 1048
806 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1049 for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -945,9 +1188,8 @@ static bool dcn10_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
945 tf = plane_state->in_transfer_func; 1188 tf = plane_state->in_transfer_func;
946 1189
947 if (plane_state->gamma_correction && 1190 if (plane_state->gamma_correction &&
948 plane_state->gamma_correction->is_identity) 1191 !plane_state->gamma_correction->is_identity
949 dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS); 1192 && dce_use_lut(plane_state->format))
950 else if (plane_state->gamma_correction && dce_use_lut(plane_state->format))
951 dpp_base->funcs->dpp_program_input_lut(dpp_base, plane_state->gamma_correction); 1193 dpp_base->funcs->dpp_program_input_lut(dpp_base, plane_state->gamma_correction);
952 1194
953 if (tf == NULL) 1195 if (tf == NULL)
@@ -1433,7 +1675,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
1433 } 1675 }
1434} 1676}
1435 1677
1436static void program_output_csc(struct dc *dc, 1678static void dcn10_program_output_csc(struct dc *dc,
1437 struct pipe_ctx *pipe_ctx, 1679 struct pipe_ctx *pipe_ctx,
1438 enum dc_color_space colorspace, 1680 enum dc_color_space colorspace,
1439 uint16_t *matrix, 1681 uint16_t *matrix,
@@ -1542,22 +1784,22 @@ static uint16_t fixed_point_to_int_frac(
1542 1784
1543 uint16_t result; 1785 uint16_t result;
1544 1786
1545 uint16_t d = (uint16_t)dal_fixed31_32_floor( 1787 uint16_t d = (uint16_t)dc_fixpt_floor(
1546 dal_fixed31_32_abs( 1788 dc_fixpt_abs(
1547 arg)); 1789 arg));
1548 1790
1549 if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor)) 1791 if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
1550 numerator = (uint16_t)dal_fixed31_32_floor( 1792 numerator = (uint16_t)dc_fixpt_floor(
1551 dal_fixed31_32_mul_int( 1793 dc_fixpt_mul_int(
1552 arg, 1794 arg,
1553 divisor)); 1795 divisor));
1554 else { 1796 else {
1555 numerator = dal_fixed31_32_floor( 1797 numerator = dc_fixpt_floor(
1556 dal_fixed31_32_sub( 1798 dc_fixpt_sub(
1557 dal_fixed31_32_from_int( 1799 dc_fixpt_from_int(
1558 1LL << integer_bits), 1800 1LL << integer_bits),
1559 dal_fixed31_32_recip( 1801 dc_fixpt_recip(
1560 dal_fixed31_32_from_int( 1802 dc_fixpt_from_int(
1561 divisor)))); 1803 divisor))));
1562 } 1804 }
1563 1805
@@ -1567,8 +1809,8 @@ static uint16_t fixed_point_to_int_frac(
1567 result = (uint16_t)( 1809 result = (uint16_t)(
1568 (1 << (integer_bits + fractional_bits + 1)) + numerator); 1810 (1 << (integer_bits + fractional_bits + 1)) + numerator);
1569 1811
1570 if ((result != 0) && dal_fixed31_32_lt( 1812 if ((result != 0) && dc_fixpt_lt(
1571 arg, dal_fixed31_32_zero)) 1813 arg, dc_fixpt_zero))
1572 result |= 1 << (integer_bits + fractional_bits); 1814 result |= 1 << (integer_bits + fractional_bits);
1573 1815
1574 return result; 1816 return result;
@@ -1582,8 +1824,8 @@ void build_prescale_params(struct dc_bias_and_scale *bias_and_scale,
1582 && plane_state->input_csc_color_matrix.enable_adjustment 1824 && plane_state->input_csc_color_matrix.enable_adjustment
1583 && plane_state->coeff_reduction_factor.value != 0) { 1825 && plane_state->coeff_reduction_factor.value != 0) {
1584 bias_and_scale->scale_blue = fixed_point_to_int_frac( 1826 bias_and_scale->scale_blue = fixed_point_to_int_frac(
1585 dal_fixed31_32_mul(plane_state->coeff_reduction_factor, 1827 dc_fixpt_mul(plane_state->coeff_reduction_factor,
1586 dal_fixed31_32_from_fraction(256, 255)), 1828 dc_fixpt_from_fraction(256, 255)),
1587 2, 1829 2,
1588 13); 1830 13);
1589 bias_and_scale->scale_red = bias_and_scale->scale_blue; 1831 bias_and_scale->scale_red = bias_and_scale->scale_blue;
@@ -1623,6 +1865,8 @@ static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
1623 struct mpc *mpc = dc->res_pool->mpc; 1865 struct mpc *mpc = dc->res_pool->mpc;
1624 struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params); 1866 struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
1625 1867
1868
1869
1626 /* TODO: proper fix once fpga works */ 1870 /* TODO: proper fix once fpga works */
1627 1871
1628 if (dc->debug.surface_visual_confirm) 1872 if (dc->debug.surface_visual_confirm)
@@ -1649,6 +1893,7 @@ static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
1649 pipe_ctx->stream->output_color_space) 1893 pipe_ctx->stream->output_color_space)
1650 && per_pixel_alpha; 1894 && per_pixel_alpha;
1651 1895
1896
1652 /* 1897 /*
1653 * TODO: remove hack 1898 * TODO: remove hack
1654 * Note: currently there is a bug in init_hw such that 1899 * Note: currently there is a bug in init_hw such that
@@ -1659,6 +1904,12 @@ static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
1659 */ 1904 */
1660 mpcc_id = hubp->inst; 1905 mpcc_id = hubp->inst;
1661 1906
1907 /* If there is no full update, don't need to touch MPC tree*/
1908 if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
1909 mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
1910 return;
1911 }
1912
1662 /* check if this MPCC is already being used */ 1913 /* check if this MPCC is already being used */
1663 new_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, mpcc_id); 1914 new_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, mpcc_id);
1664 /* remove MPCC if being used */ 1915 /* remove MPCC if being used */
@@ -1777,7 +2028,7 @@ static void update_dchubp_dpp(
1777 /*gamut remap*/ 2028 /*gamut remap*/
1778 program_gamut_remap(pipe_ctx); 2029 program_gamut_remap(pipe_ctx);
1779 2030
1780 program_output_csc(dc, 2031 dc->hwss.program_output_csc(dc,
1781 pipe_ctx, 2032 pipe_ctx,
1782 pipe_ctx->stream->output_color_space, 2033 pipe_ctx->stream->output_color_space,
1783 pipe_ctx->stream->csc_color_matrix.matrix, 2034 pipe_ctx->stream->csc_color_matrix.matrix,
@@ -1810,9 +2061,9 @@ static void update_dchubp_dpp(
1810 hubp->funcs->set_blank(hubp, false); 2061 hubp->funcs->set_blank(hubp, false);
1811} 2062}
1812 2063
1813static void dcn10_otg_blank( 2064static void dcn10_blank_pixel_data(
1814 struct dc *dc, 2065 struct dc *dc,
1815 struct stream_resource stream_res, 2066 struct stream_resource *stream_res,
1816 struct dc_stream_state *stream, 2067 struct dc_stream_state *stream,
1817 bool blank) 2068 bool blank)
1818{ 2069{
@@ -1823,27 +2074,27 @@ static void dcn10_otg_blank(
1823 color_space = stream->output_color_space; 2074 color_space = stream->output_color_space;
1824 color_space_to_black_color(dc, color_space, &black_color); 2075 color_space_to_black_color(dc, color_space, &black_color);
1825 2076
1826 if (stream_res.tg->funcs->set_blank_color) 2077 if (stream_res->tg->funcs->set_blank_color)
1827 stream_res.tg->funcs->set_blank_color( 2078 stream_res->tg->funcs->set_blank_color(
1828 stream_res.tg, 2079 stream_res->tg,
1829 &black_color); 2080 &black_color);
1830 2081
1831 if (!blank) { 2082 if (!blank) {
1832 if (stream_res.tg->funcs->set_blank) 2083 if (stream_res->tg->funcs->set_blank)
1833 stream_res.tg->funcs->set_blank(stream_res.tg, blank); 2084 stream_res->tg->funcs->set_blank(stream_res->tg, blank);
1834 if (stream_res.abm) 2085 if (stream_res->abm)
1835 stream_res.abm->funcs->set_abm_level(stream_res.abm, stream->abm_level); 2086 stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
1836 } else if (blank) { 2087 } else if (blank) {
1837 if (stream_res.abm) 2088 if (stream_res->abm)
1838 stream_res.abm->funcs->set_abm_immediate_disable(stream_res.abm); 2089 stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm);
1839 if (stream_res.tg->funcs->set_blank) 2090 if (stream_res->tg->funcs->set_blank)
1840 stream_res.tg->funcs->set_blank(stream_res.tg, blank); 2091 stream_res->tg->funcs->set_blank(stream_res->tg, blank);
1841 } 2092 }
1842} 2093}
1843 2094
1844static void set_hdr_multiplier(struct pipe_ctx *pipe_ctx) 2095static void set_hdr_multiplier(struct pipe_ctx *pipe_ctx)
1845{ 2096{
1846 struct fixed31_32 multiplier = dal_fixed31_32_from_fraction( 2097 struct fixed31_32 multiplier = dc_fixpt_from_fraction(
1847 pipe_ctx->plane_state->sdr_white_level, 80); 2098 pipe_ctx->plane_state->sdr_white_level, 80);
1848 uint32_t hw_mult = 0x1f000; // 1.0 default multiplier 2099 uint32_t hw_mult = 0x1f000; // 1.0 default multiplier
1849 struct custom_float_format fmt; 2100 struct custom_float_format fmt;
@@ -1876,7 +2127,7 @@ static void program_all_pipe_in_tree(
1876 pipe_ctx->stream_res.tg->funcs->program_global_sync( 2127 pipe_ctx->stream_res.tg->funcs->program_global_sync(
1877 pipe_ctx->stream_res.tg); 2128 pipe_ctx->stream_res.tg);
1878 2129
1879 dcn10_otg_blank(dc, pipe_ctx->stream_res, 2130 dc->hwss.blank_pixel_data(dc, &pipe_ctx->stream_res,
1880 pipe_ctx->stream, blank); 2131 pipe_ctx->stream, blank);
1881 } 2132 }
1882 2133
@@ -1983,9 +2234,9 @@ static void dcn10_apply_ctx_for_surface(
1983 bool removed_pipe[4] = { false }; 2234 bool removed_pipe[4] = { false };
1984 unsigned int ref_clk_mhz = dc->res_pool->ref_clock_inKhz/1000; 2235 unsigned int ref_clk_mhz = dc->res_pool->ref_clock_inKhz/1000;
1985 bool program_water_mark = false; 2236 bool program_water_mark = false;
1986 struct dc_context *ctx = dc->ctx;
1987 struct pipe_ctx *top_pipe_to_program = 2237 struct pipe_ctx *top_pipe_to_program =
1988 find_top_pipe_for_stream(dc, context, stream); 2238 find_top_pipe_for_stream(dc, context, stream);
2239 DC_LOGGER_INIT(dc->ctx->logger);
1989 2240
1990 if (!top_pipe_to_program) 2241 if (!top_pipe_to_program)
1991 return; 2242 return;
@@ -1996,7 +2247,7 @@ static void dcn10_apply_ctx_for_surface(
1996 2247
1997 if (num_planes == 0) { 2248 if (num_planes == 0) {
1998 /* OTG blank before remove all front end */ 2249 /* OTG blank before remove all front end */
1999 dcn10_otg_blank(dc, top_pipe_to_program->stream_res, top_pipe_to_program->stream, true); 2250 dc->hwss.blank_pixel_data(dc, &top_pipe_to_program->stream_res, top_pipe_to_program->stream, true);
2000 } 2251 }
2001 2252
2002 /* Disconnect unused mpcc */ 2253 /* Disconnect unused mpcc */
@@ -2027,7 +2278,7 @@ static void dcn10_apply_ctx_for_surface(
2027 old_pipe_ctx->plane_state && 2278 old_pipe_ctx->plane_state &&
2028 old_pipe_ctx->stream_res.tg == tg) { 2279 old_pipe_ctx->stream_res.tg == tg) {
2029 2280
2030 plane_atomic_disconnect(dc, old_pipe_ctx); 2281 hwss1_plane_atomic_disconnect(dc, old_pipe_ctx);
2031 removed_pipe[i] = true; 2282 removed_pipe[i] = true;
2032 2283
2033 DC_LOG_DC( 2284 DC_LOG_DC(
@@ -2335,15 +2586,6 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
2335 set_static_screen_control(pipe_ctx[i]->stream_res.tg, value); 2586 set_static_screen_control(pipe_ctx[i]->stream_res.tg, value);
2336} 2587}
2337 2588
2338static void set_plane_config(
2339 const struct dc *dc,
2340 struct pipe_ctx *pipe_ctx,
2341 struct resource_context *res_ctx)
2342{
2343 /* TODO */
2344 program_gamut_remap(pipe_ctx);
2345}
2346
2347static void dcn10_config_stereo_parameters( 2589static void dcn10_config_stereo_parameters(
2348 struct dc_stream_state *stream, struct crtc_stereo_flags *flags) 2590 struct dc_stream_state *stream, struct crtc_stereo_flags *flags)
2349{ 2591{
@@ -2521,12 +2763,12 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
2521 .init_hw = dcn10_init_hw, 2763 .init_hw = dcn10_init_hw,
2522 .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 2764 .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
2523 .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, 2765 .apply_ctx_for_surface = dcn10_apply_ctx_for_surface,
2524 .set_plane_config = set_plane_config,
2525 .update_plane_addr = dcn10_update_plane_addr, 2766 .update_plane_addr = dcn10_update_plane_addr,
2526 .update_dchub = dcn10_update_dchub, 2767 .update_dchub = dcn10_update_dchub,
2527 .update_pending_status = dcn10_update_pending_status, 2768 .update_pending_status = dcn10_update_pending_status,
2528 .set_input_transfer_func = dcn10_set_input_transfer_func, 2769 .set_input_transfer_func = dcn10_set_input_transfer_func,
2529 .set_output_transfer_func = dcn10_set_output_transfer_func, 2770 .set_output_transfer_func = dcn10_set_output_transfer_func,
2771 .program_output_csc = dcn10_program_output_csc,
2530 .power_down = dce110_power_down, 2772 .power_down = dce110_power_down,
2531 .enable_accelerated_mode = dce110_enable_accelerated_mode, 2773 .enable_accelerated_mode = dce110_enable_accelerated_mode,
2532 .enable_timing_synchronization = dcn10_enable_timing_synchronization, 2774 .enable_timing_synchronization = dcn10_enable_timing_synchronization,
@@ -2538,10 +2780,11 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
2538 .blank_stream = dce110_blank_stream, 2780 .blank_stream = dce110_blank_stream,
2539 .enable_display_power_gating = dcn10_dummy_display_power_gating, 2781 .enable_display_power_gating = dcn10_dummy_display_power_gating,
2540 .disable_plane = dcn10_disable_plane, 2782 .disable_plane = dcn10_disable_plane,
2783 .blank_pixel_data = dcn10_blank_pixel_data,
2541 .pipe_control_lock = dcn10_pipe_control_lock, 2784 .pipe_control_lock = dcn10_pipe_control_lock,
2542 .set_bandwidth = dcn10_set_bandwidth, 2785 .set_bandwidth = dcn10_set_bandwidth,
2543 .reset_hw_ctx_wrap = reset_hw_ctx_wrap, 2786 .reset_hw_ctx_wrap = reset_hw_ctx_wrap,
2544 .prog_pixclk_crtc_otg = dcn10_prog_pixclk_crtc_otg, 2787 .enable_stream_timing = dcn10_enable_stream_timing,
2545 .set_drr = set_drr, 2788 .set_drr = set_drr,
2546 .get_position = get_position, 2789 .get_position = get_position,
2547 .set_static_screen_control = set_static_screen_control, 2790 .set_static_screen_control = set_static_screen_control,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
index 6c526b5095d9..44f734b73f9e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
@@ -37,4 +37,6 @@ extern void fill_display_configs(
37 37
38bool is_rgb_cspace(enum dc_color_space output_color_space); 38bool is_rgb_cspace(enum dc_color_space output_color_space);
39 39
40void hwss1_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx);
41
40#endif /* __DC_HWSS_DCN10_H__ */ 42#endif /* __DC_HWSS_DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
new file mode 100644
index 000000000000..21fa40ac0786
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
@@ -0,0 +1,1362 @@
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#include "reg_helper.h"
27
28#include "core_types.h"
29#include "link_encoder.h"
30#include "dcn10_link_encoder.h"
31#include "stream_encoder.h"
32#include "i2caux_interface.h"
33#include "dc_bios_types.h"
34
35#include "gpio_service_interface.h"
36
37#define CTX \
38 enc10->base.ctx
39#define DC_LOGGER \
40 enc10->base.ctx->logger
41
42#define REG(reg)\
43 (enc10->link_regs->reg)
44
45#undef FN
46#define FN(reg_name, field_name) \
47 enc10->link_shift->field_name, enc10->link_mask->field_name
48
49
50/*
51 * @brief
52 * Trigger Source Select
53 * ASIC-dependent, actual values for register programming
54 */
55#define DCN10_DIG_FE_SOURCE_SELECT_INVALID 0x0
56#define DCN10_DIG_FE_SOURCE_SELECT_DIGA 0x1
57#define DCN10_DIG_FE_SOURCE_SELECT_DIGB 0x2
58#define DCN10_DIG_FE_SOURCE_SELECT_DIGC 0x4
59#define DCN10_DIG_FE_SOURCE_SELECT_DIGD 0x08
60#define DCN10_DIG_FE_SOURCE_SELECT_DIGE 0x10
61#define DCN10_DIG_FE_SOURCE_SELECT_DIGF 0x20
62#define DCN10_DIG_FE_SOURCE_SELECT_DIGG 0x40
63
64enum {
65 DP_MST_UPDATE_MAX_RETRY = 50
66};
67
68
69
70static void aux_initialize(struct dcn10_link_encoder *enc10);
71
72
73static const struct link_encoder_funcs dcn10_lnk_enc_funcs = {
74 .validate_output_with_stream =
75 dcn10_link_encoder_validate_output_with_stream,
76 .hw_init = dcn10_link_encoder_hw_init,
77 .setup = dcn10_link_encoder_setup,
78 .enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
79 .enable_dp_output = dcn10_link_encoder_enable_dp_output,
80 .enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output,
81 .disable_output = dcn10_link_encoder_disable_output,
82 .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
83 .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
84 .update_mst_stream_allocation_table =
85 dcn10_link_encoder_update_mst_stream_allocation_table,
86 .psr_program_dp_dphy_fast_training =
87 dcn10_psr_program_dp_dphy_fast_training,
88 .psr_program_secondary_packet = dcn10_psr_program_secondary_packet,
89 .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe,
90 .enable_hpd = dcn10_link_encoder_enable_hpd,
91 .disable_hpd = dcn10_link_encoder_disable_hpd,
92 .is_dig_enabled = dcn10_is_dig_enabled,
93 .destroy = dcn10_link_encoder_destroy
94};
95
96static enum bp_result link_transmitter_control(
97 struct dcn10_link_encoder *enc10,
98 struct bp_transmitter_control *cntl)
99{
100 enum bp_result result;
101 struct dc_bios *bp = enc10->base.ctx->dc_bios;
102
103 result = bp->funcs->transmitter_control(bp, cntl);
104
105 return result;
106}
107
108static void enable_phy_bypass_mode(
109 struct dcn10_link_encoder *enc10,
110 bool enable)
111{
112 /* This register resides in DP back end block;
113 * transmitter is used for the offset
114 */
115 REG_UPDATE(DP_DPHY_CNTL, DPHY_BYPASS, enable);
116
117}
118
119static void disable_prbs_symbols(
120 struct dcn10_link_encoder *enc10,
121 bool disable)
122{
123 /* This register resides in DP back end block;
124 * transmitter is used for the offset
125 */
126 REG_UPDATE_4(DP_DPHY_CNTL,
127 DPHY_ATEST_SEL_LANE0, disable,
128 DPHY_ATEST_SEL_LANE1, disable,
129 DPHY_ATEST_SEL_LANE2, disable,
130 DPHY_ATEST_SEL_LANE3, disable);
131}
132
133static void disable_prbs_mode(
134 struct dcn10_link_encoder *enc10)
135{
136 REG_UPDATE(DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN, 0);
137}
138
139static void program_pattern_symbols(
140 struct dcn10_link_encoder *enc10,
141 uint16_t pattern_symbols[8])
142{
143 /* This register resides in DP back end block;
144 * transmitter is used for the offset
145 */
146 REG_SET_3(DP_DPHY_SYM0, 0,
147 DPHY_SYM1, pattern_symbols[0],
148 DPHY_SYM2, pattern_symbols[1],
149 DPHY_SYM3, pattern_symbols[2]);
150
151 /* This register resides in DP back end block;
152 * transmitter is used for the offset
153 */
154 REG_SET_3(DP_DPHY_SYM1, 0,
155 DPHY_SYM4, pattern_symbols[3],
156 DPHY_SYM5, pattern_symbols[4],
157 DPHY_SYM6, pattern_symbols[5]);
158
159 /* This register resides in DP back end block;
160 * transmitter is used for the offset
161 */
162 REG_SET_2(DP_DPHY_SYM2, 0,
163 DPHY_SYM7, pattern_symbols[6],
164 DPHY_SYM8, pattern_symbols[7]);
165}
166
167static void set_dp_phy_pattern_d102(
168 struct dcn10_link_encoder *enc10)
169{
170 /* Disable PHY Bypass mode to setup the test pattern */
171 enable_phy_bypass_mode(enc10, false);
172
173 /* For 10-bit PRBS or debug symbols
174 * please use the following sequence:
175 *
176 * Enable debug symbols on the lanes
177 */
178 disable_prbs_symbols(enc10, true);
179
180 /* Disable PRBS mode */
181 disable_prbs_mode(enc10);
182
183 /* Program debug symbols to be output */
184 {
185 uint16_t pattern_symbols[8] = {
186 0x2AA, 0x2AA, 0x2AA, 0x2AA,
187 0x2AA, 0x2AA, 0x2AA, 0x2AA
188 };
189
190 program_pattern_symbols(enc10, pattern_symbols);
191 }
192
193 /* Enable phy bypass mode to enable the test pattern */
194
195 enable_phy_bypass_mode(enc10, true);
196}
197
198static void set_link_training_complete(
199 struct dcn10_link_encoder *enc10,
200 bool complete)
201{
202 /* This register resides in DP back end block;
203 * transmitter is used for the offset
204 */
205 REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, complete);
206
207}
208
209void dcn10_link_encoder_set_dp_phy_pattern_training_pattern(
210 struct link_encoder *enc,
211 uint32_t index)
212{
213 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
214 /* Write Training Pattern */
215
216 REG_WRITE(DP_DPHY_TRAINING_PATTERN_SEL, index);
217
218 /* Set HW Register Training Complete to false */
219
220 set_link_training_complete(enc10, false);
221
222 /* Disable PHY Bypass mode to output Training Pattern */
223
224 enable_phy_bypass_mode(enc10, false);
225
226 /* Disable PRBS mode */
227 disable_prbs_mode(enc10);
228}
229
230static void setup_panel_mode(
231 struct dcn10_link_encoder *enc10,
232 enum dp_panel_mode panel_mode)
233{
234 uint32_t value;
235
236 ASSERT(REG(DP_DPHY_INTERNAL_CTRL));
237 value = REG_READ(DP_DPHY_INTERNAL_CTRL);
238
239 switch (panel_mode) {
240 case DP_PANEL_MODE_EDP:
241 value = 0x1;
242 break;
243 case DP_PANEL_MODE_SPECIAL:
244 value = 0x11;
245 break;
246 default:
247 value = 0x0;
248 break;
249 }
250
251 REG_WRITE(DP_DPHY_INTERNAL_CTRL, value);
252}
253
254static void set_dp_phy_pattern_symbol_error(
255 struct dcn10_link_encoder *enc10)
256{
257 /* Disable PHY Bypass mode to setup the test pattern */
258 enable_phy_bypass_mode(enc10, false);
259
260 /* program correct panel mode*/
261 setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
262
263 /* A PRBS23 pattern is used for most DP electrical measurements. */
264
265 /* Enable PRBS symbols on the lanes */
266 disable_prbs_symbols(enc10, false);
267
268 /* For PRBS23 Set bit DPHY_PRBS_SEL=1 and Set bit DPHY_PRBS_EN=1 */
269 REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
270 DPHY_PRBS_SEL, 1,
271 DPHY_PRBS_EN, 1);
272
273 /* Enable phy bypass mode to enable the test pattern */
274 enable_phy_bypass_mode(enc10, true);
275}
276
277static void set_dp_phy_pattern_prbs7(
278 struct dcn10_link_encoder *enc10)
279{
280 /* Disable PHY Bypass mode to setup the test pattern */
281 enable_phy_bypass_mode(enc10, false);
282
283 /* A PRBS7 pattern is used for most DP electrical measurements. */
284
285 /* Enable PRBS symbols on the lanes */
286 disable_prbs_symbols(enc10, false);
287
288 /* For PRBS7 Set bit DPHY_PRBS_SEL=0 and Set bit DPHY_PRBS_EN=1 */
289 REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
290 DPHY_PRBS_SEL, 0,
291 DPHY_PRBS_EN, 1);
292
293 /* Enable phy bypass mode to enable the test pattern */
294 enable_phy_bypass_mode(enc10, true);
295}
296
297static void set_dp_phy_pattern_80bit_custom(
298 struct dcn10_link_encoder *enc10,
299 const uint8_t *pattern)
300{
301 /* Disable PHY Bypass mode to setup the test pattern */
302 enable_phy_bypass_mode(enc10, false);
303
304 /* Enable debug symbols on the lanes */
305
306 disable_prbs_symbols(enc10, true);
307
308 /* Enable PHY bypass mode to enable the test pattern */
309 /* TODO is it really needed ? */
310
311 enable_phy_bypass_mode(enc10, true);
312
313 /* Program 80 bit custom pattern */
314 {
315 uint16_t pattern_symbols[8];
316
317 pattern_symbols[0] =
318 ((pattern[1] & 0x03) << 8) | pattern[0];
319 pattern_symbols[1] =
320 ((pattern[2] & 0x0f) << 6) | ((pattern[1] >> 2) & 0x3f);
321 pattern_symbols[2] =
322 ((pattern[3] & 0x3f) << 4) | ((pattern[2] >> 4) & 0x0f);
323 pattern_symbols[3] =
324 (pattern[4] << 2) | ((pattern[3] >> 6) & 0x03);
325 pattern_symbols[4] =
326 ((pattern[6] & 0x03) << 8) | pattern[5];
327 pattern_symbols[5] =
328 ((pattern[7] & 0x0f) << 6) | ((pattern[6] >> 2) & 0x3f);
329 pattern_symbols[6] =
330 ((pattern[8] & 0x3f) << 4) | ((pattern[7] >> 4) & 0x0f);
331 pattern_symbols[7] =
332 (pattern[9] << 2) | ((pattern[8] >> 6) & 0x03);
333
334 program_pattern_symbols(enc10, pattern_symbols);
335 }
336
337 /* Enable phy bypass mode to enable the test pattern */
338
339 enable_phy_bypass_mode(enc10, true);
340}
341
342static void set_dp_phy_pattern_hbr2_compliance_cp2520_2(
343 struct dcn10_link_encoder *enc10,
344 unsigned int cp2520_pattern)
345{
346
347 /* previously there is a register DP_HBR2_EYE_PATTERN
348 * that is enabled to get the pattern.
349 * But it does not work with the latest spec change,
350 * so we are programming the following registers manually.
351 *
352 * The following settings have been confirmed
353 * by Nick Chorney and Sandra Liu
354 */
355
356 /* Disable PHY Bypass mode to setup the test pattern */
357
358 enable_phy_bypass_mode(enc10, false);
359
360 /* Setup DIG encoder in DP SST mode */
361 enc10->base.funcs->setup(&enc10->base, SIGNAL_TYPE_DISPLAY_PORT);
362
363 /* ensure normal panel mode. */
364 setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
365
366 /* no vbid after BS (SR)
367 * DP_LINK_FRAMING_CNTL changed history Sandra Liu
368 * 11000260 / 11000104 / 110000FC
369 */
370 REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
371 DP_IDLE_BS_INTERVAL, 0xFC,
372 DP_VBID_DISABLE, 1,
373 DP_VID_ENHANCED_FRAME_MODE, 1);
374
375 /* swap every BS with SR */
376 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0);
377
378 /* select cp2520 patterns */
379 if (REG(DP_DPHY_HBR2_PATTERN_CONTROL))
380 REG_UPDATE(DP_DPHY_HBR2_PATTERN_CONTROL,
381 DP_DPHY_HBR2_PATTERN_CONTROL, cp2520_pattern);
382 else
383 /* pre-DCE11 can only generate CP2520 pattern 2 */
384 ASSERT(cp2520_pattern == 2);
385
386 /* set link training complete */
387 set_link_training_complete(enc10, true);
388
389 /* disable video stream */
390 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
391
392 /* Disable PHY Bypass mode to setup the test pattern */
393 enable_phy_bypass_mode(enc10, false);
394}
395
396static void set_dp_phy_pattern_passthrough_mode(
397 struct dcn10_link_encoder *enc10,
398 enum dp_panel_mode panel_mode)
399{
400 /* program correct panel mode */
401 setup_panel_mode(enc10, panel_mode);
402
403 /* restore LINK_FRAMING_CNTL and DPHY_SCRAMBLER_BS_COUNT
404 * in case we were doing HBR2 compliance pattern before
405 */
406 REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
407 DP_IDLE_BS_INTERVAL, 0x2000,
408 DP_VBID_DISABLE, 0,
409 DP_VID_ENHANCED_FRAME_MODE, 1);
410
411 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0x1FF);
412
413 /* set link training complete */
414 set_link_training_complete(enc10, true);
415
416 /* Disable PHY Bypass mode to setup the test pattern */
417 enable_phy_bypass_mode(enc10, false);
418
419 /* Disable PRBS mode */
420 disable_prbs_mode(enc10);
421}
422
423/* return value is bit-vector */
424static uint8_t get_frontend_source(
425 enum engine_id engine)
426{
427 switch (engine) {
428 case ENGINE_ID_DIGA:
429 return DCN10_DIG_FE_SOURCE_SELECT_DIGA;
430 case ENGINE_ID_DIGB:
431 return DCN10_DIG_FE_SOURCE_SELECT_DIGB;
432 case ENGINE_ID_DIGC:
433 return DCN10_DIG_FE_SOURCE_SELECT_DIGC;
434 case ENGINE_ID_DIGD:
435 return DCN10_DIG_FE_SOURCE_SELECT_DIGD;
436 case ENGINE_ID_DIGE:
437 return DCN10_DIG_FE_SOURCE_SELECT_DIGE;
438 case ENGINE_ID_DIGF:
439 return DCN10_DIG_FE_SOURCE_SELECT_DIGF;
440 case ENGINE_ID_DIGG:
441 return DCN10_DIG_FE_SOURCE_SELECT_DIGG;
442 default:
443 ASSERT_CRITICAL(false);
444 return DCN10_DIG_FE_SOURCE_SELECT_INVALID;
445 }
446}
447
448static void configure_encoder(
449 struct dcn10_link_encoder *enc10,
450 const struct dc_link_settings *link_settings)
451{
452 /* set number of lanes */
453
454 REG_SET(DP_CONFIG, 0,
455 DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE);
456
457 /* setup scrambler */
458 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
459}
460
461void dcn10_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
462 bool exit_link_training_required)
463{
464 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
465
466 if (exit_link_training_required)
467 REG_UPDATE(DP_DPHY_FAST_TRAINING,
468 DPHY_RX_FAST_TRAINING_CAPABLE, 1);
469 else {
470 REG_UPDATE(DP_DPHY_FAST_TRAINING,
471 DPHY_RX_FAST_TRAINING_CAPABLE, 0);
472 /*In DCE 11, we are able to pre-program a Force SR register
473 * to be able to trigger SR symbol after 5 idle patterns
474 * transmitted. Upon PSR Exit, DMCU can trigger
475 * DPHY_LOAD_BS_COUNT_START = 1. Upon writing 1 to
476 * DPHY_LOAD_BS_COUNT_START and the internal counter
477 * reaches DPHY_LOAD_BS_COUNT, the next BS symbol will be
478 * replaced by SR symbol once.
479 */
480
481 REG_UPDATE(DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, 0x5);
482 }
483}
484
485void dcn10_psr_program_secondary_packet(struct link_encoder *enc,
486 unsigned int sdp_transmit_line_num_deadline)
487{
488 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
489
490 REG_UPDATE_2(DP_SEC_CNTL1,
491 DP_SEC_GSP0_LINE_NUM, sdp_transmit_line_num_deadline,
492 DP_SEC_GSP0_PRIORITY, 1);
493}
494
495bool dcn10_is_dig_enabled(struct link_encoder *enc)
496{
497 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
498 uint32_t value;
499
500 REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value);
501 return value;
502}
503
504static void link_encoder_disable(struct dcn10_link_encoder *enc10)
505{
506 /* reset training pattern */
507 REG_SET(DP_DPHY_TRAINING_PATTERN_SEL, 0,
508 DPHY_TRAINING_PATTERN_SEL, 0);
509
510 /* reset training complete */
511 REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
512
513 /* reset panel mode */
514 setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
515}
516
517static void hpd_initialize(
518 struct dcn10_link_encoder *enc10)
519{
520 /* Associate HPD with DIG_BE */
521 enum hpd_source_id hpd_source = enc10->base.hpd_source;
522
523 REG_UPDATE(DIG_BE_CNTL, DIG_HPD_SELECT, hpd_source);
524}
525
526bool dcn10_link_encoder_validate_dvi_output(
527 const struct dcn10_link_encoder *enc10,
528 enum signal_type connector_signal,
529 enum signal_type signal,
530 const struct dc_crtc_timing *crtc_timing)
531{
532 uint32_t max_pixel_clock = TMDS_MAX_PIXEL_CLOCK;
533
534 if (signal == SIGNAL_TYPE_DVI_DUAL_LINK)
535 max_pixel_clock *= 2;
536
537 /* This handles the case of HDMI downgrade to DVI we don't want to
538 * we don't want to cap the pixel clock if the DDI is not DVI.
539 */
540 if (connector_signal != SIGNAL_TYPE_DVI_DUAL_LINK &&
541 connector_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
542 max_pixel_clock = enc10->base.features.max_hdmi_pixel_clock;
543
544 /* DVI only support RGB pixel encoding */
545 if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB)
546 return false;
547
548 /*connect DVI via adpater's HDMI connector*/
549 if ((connector_signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
550 connector_signal == SIGNAL_TYPE_HDMI_TYPE_A) &&
551 signal != SIGNAL_TYPE_HDMI_TYPE_A &&
552 crtc_timing->pix_clk_khz > TMDS_MAX_PIXEL_CLOCK)
553 return false;
554 if (crtc_timing->pix_clk_khz < TMDS_MIN_PIXEL_CLOCK)
555 return false;
556
557 if (crtc_timing->pix_clk_khz > max_pixel_clock)
558 return false;
559
560 /* DVI supports 6/8bpp single-link and 10/16bpp dual-link */
561 switch (crtc_timing->display_color_depth) {
562 case COLOR_DEPTH_666:
563 case COLOR_DEPTH_888:
564 break;
565 case COLOR_DEPTH_101010:
566 case COLOR_DEPTH_161616:
567 if (signal != SIGNAL_TYPE_DVI_DUAL_LINK)
568 return false;
569 break;
570 default:
571 return false;
572 }
573
574 return true;
575}
576
577static bool dcn10_link_encoder_validate_hdmi_output(
578 const struct dcn10_link_encoder *enc10,
579 const struct dc_crtc_timing *crtc_timing,
580 int adjusted_pix_clk_khz)
581{
582 enum dc_color_depth max_deep_color =
583 enc10->base.features.max_hdmi_deep_color;
584
585 if (max_deep_color < crtc_timing->display_color_depth)
586 return false;
587
588 if (crtc_timing->display_color_depth < COLOR_DEPTH_888)
589 return false;
590 if (adjusted_pix_clk_khz < TMDS_MIN_PIXEL_CLOCK)
591 return false;
592
593 if ((adjusted_pix_clk_khz == 0) ||
594 (adjusted_pix_clk_khz > enc10->base.features.max_hdmi_pixel_clock))
595 return false;
596
597 /* DCE11 HW does not support 420 */
598 if (!enc10->base.features.ycbcr420_supported &&
599 crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
600 return false;
601
602 if (!enc10->base.features.flags.bits.HDMI_6GB_EN &&
603 adjusted_pix_clk_khz >= 300000)
604 return false;
605 return true;
606}
607
608bool dcn10_link_encoder_validate_dp_output(
609 const struct dcn10_link_encoder *enc10,
610 const struct dc_crtc_timing *crtc_timing)
611{
612 /* default RGB only */
613 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB)
614 return true;
615
616 if (enc10->base.features.flags.bits.IS_YCBCR_CAPABLE)
617 return true;
618
619 /* for DCE 8.x or later DP Y-only feature,
620 * we need ASIC cap + FeatureSupportDPYonly, not support 666
621 */
622 if (crtc_timing->flags.Y_ONLY &&
623 enc10->base.features.flags.bits.IS_YCBCR_CAPABLE &&
624 crtc_timing->display_color_depth != COLOR_DEPTH_666)
625 return true;
626
627 return false;
628}
629
630void dcn10_link_encoder_construct(
631 struct dcn10_link_encoder *enc10,
632 const struct encoder_init_data *init_data,
633 const struct encoder_feature_support *enc_features,
634 const struct dcn10_link_enc_registers *link_regs,
635 const struct dcn10_link_enc_aux_registers *aux_regs,
636 const struct dcn10_link_enc_hpd_registers *hpd_regs,
637 const struct dcn10_link_enc_shift *link_shift,
638 const struct dcn10_link_enc_mask *link_mask)
639{
640 struct bp_encoder_cap_info bp_cap_info = {0};
641 const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
642 enum bp_result result = BP_RESULT_OK;
643
644 enc10->base.funcs = &dcn10_lnk_enc_funcs;
645 enc10->base.ctx = init_data->ctx;
646 enc10->base.id = init_data->encoder;
647
648 enc10->base.hpd_source = init_data->hpd_source;
649 enc10->base.connector = init_data->connector;
650
651 enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
652
653 enc10->base.features = *enc_features;
654
655 enc10->base.transmitter = init_data->transmitter;
656
657 /* set the flag to indicate whether driver poll the I2C data pin
658 * while doing the DP sink detect
659 */
660
661/* if (dal_adapter_service_is_feature_supported(as,
662 FEATURE_DP_SINK_DETECT_POLL_DATA_PIN))
663 enc10->base.features.flags.bits.
664 DP_SINK_DETECT_POLL_DATA_PIN = true;*/
665
666 enc10->base.output_signals =
667 SIGNAL_TYPE_DVI_SINGLE_LINK |
668 SIGNAL_TYPE_DVI_DUAL_LINK |
669 SIGNAL_TYPE_LVDS |
670 SIGNAL_TYPE_DISPLAY_PORT |
671 SIGNAL_TYPE_DISPLAY_PORT_MST |
672 SIGNAL_TYPE_EDP |
673 SIGNAL_TYPE_HDMI_TYPE_A;
674
675 /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE.
676 * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY.
677 * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer
678 * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS.
679 * Prefer DIG assignment is decided by board design.
680 * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design
681 * and VBIOS will filter out 7 UNIPHY for DCE 8.0.
682 * By this, adding DIGG should not hurt DCE 8.0.
683 * This will let DCE 8.1 share DCE 8.0 as much as possible
684 */
685
686 enc10->link_regs = link_regs;
687 enc10->aux_regs = aux_regs;
688 enc10->hpd_regs = hpd_regs;
689 enc10->link_shift = link_shift;
690 enc10->link_mask = link_mask;
691
692 switch (enc10->base.transmitter) {
693 case TRANSMITTER_UNIPHY_A:
694 enc10->base.preferred_engine = ENGINE_ID_DIGA;
695 break;
696 case TRANSMITTER_UNIPHY_B:
697 enc10->base.preferred_engine = ENGINE_ID_DIGB;
698 break;
699 case TRANSMITTER_UNIPHY_C:
700 enc10->base.preferred_engine = ENGINE_ID_DIGC;
701 break;
702 case TRANSMITTER_UNIPHY_D:
703 enc10->base.preferred_engine = ENGINE_ID_DIGD;
704 break;
705 case TRANSMITTER_UNIPHY_E:
706 enc10->base.preferred_engine = ENGINE_ID_DIGE;
707 break;
708 case TRANSMITTER_UNIPHY_F:
709 enc10->base.preferred_engine = ENGINE_ID_DIGF;
710 break;
711 case TRANSMITTER_UNIPHY_G:
712 enc10->base.preferred_engine = ENGINE_ID_DIGG;
713 break;
714 default:
715 ASSERT_CRITICAL(false);
716 enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
717 }
718
719 /* default to one to mirror Windows behavior */
720 enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
721
722 result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios,
723 enc10->base.id, &bp_cap_info);
724
725 /* Override features with DCE-specific values */
726 if (result == BP_RESULT_OK) {
727 enc10->base.features.flags.bits.IS_HBR2_CAPABLE =
728 bp_cap_info.DP_HBR2_EN;
729 enc10->base.features.flags.bits.IS_HBR3_CAPABLE =
730 bp_cap_info.DP_HBR3_EN;
731 enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
732 } else {
733 DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
734 __func__,
735 result);
736 }
737}
738
739bool dcn10_link_encoder_validate_output_with_stream(
740 struct link_encoder *enc,
741 const struct dc_stream_state *stream)
742{
743 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
744 bool is_valid;
745
746 switch (stream->signal) {
747 case SIGNAL_TYPE_DVI_SINGLE_LINK:
748 case SIGNAL_TYPE_DVI_DUAL_LINK:
749 is_valid = dcn10_link_encoder_validate_dvi_output(
750 enc10,
751 stream->sink->link->connector_signal,
752 stream->signal,
753 &stream->timing);
754 break;
755 case SIGNAL_TYPE_HDMI_TYPE_A:
756 is_valid = dcn10_link_encoder_validate_hdmi_output(
757 enc10,
758 &stream->timing,
759 stream->phy_pix_clk);
760 break;
761 case SIGNAL_TYPE_DISPLAY_PORT:
762 case SIGNAL_TYPE_DISPLAY_PORT_MST:
763 is_valid = dcn10_link_encoder_validate_dp_output(
764 enc10, &stream->timing);
765 break;
766 case SIGNAL_TYPE_EDP:
767 is_valid = (stream->timing.pixel_encoding == PIXEL_ENCODING_RGB) ? true : false;
768 break;
769 case SIGNAL_TYPE_VIRTUAL:
770 is_valid = true;
771 break;
772 default:
773 is_valid = false;
774 break;
775 }
776
777 return is_valid;
778}
779
780void dcn10_link_encoder_hw_init(
781 struct link_encoder *enc)
782{
783 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
784 struct bp_transmitter_control cntl = { 0 };
785 enum bp_result result;
786
787 cntl.action = TRANSMITTER_CONTROL_INIT;
788 cntl.engine_id = ENGINE_ID_UNKNOWN;
789 cntl.transmitter = enc10->base.transmitter;
790 cntl.connector_obj_id = enc10->base.connector;
791 cntl.lanes_number = LANE_COUNT_FOUR;
792 cntl.coherent = false;
793 cntl.hpd_sel = enc10->base.hpd_source;
794
795 if (enc10->base.connector.id == CONNECTOR_ID_EDP)
796 cntl.signal = SIGNAL_TYPE_EDP;
797
798 result = link_transmitter_control(enc10, &cntl);
799
800 if (result != BP_RESULT_OK) {
801 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
802 __func__);
803 BREAK_TO_DEBUGGER();
804 return;
805 }
806
807 if (enc10->base.connector.id == CONNECTOR_ID_LVDS) {
808 cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS;
809
810 result = link_transmitter_control(enc10, &cntl);
811
812 ASSERT(result == BP_RESULT_OK);
813
814 }
815 aux_initialize(enc10);
816
817 /* reinitialize HPD.
818 * hpd_initialize() will pass DIG_FE id to HW context.
819 * All other routine within HW context will use fe_engine_offset
820 * as DIG_FE id even caller pass DIG_FE id.
821 * So this routine must be called first.
822 */
823 hpd_initialize(enc10);
824}
825
826void dcn10_link_encoder_destroy(struct link_encoder **enc)
827{
828 kfree(TO_DCN10_LINK_ENC(*enc));
829 *enc = NULL;
830}
831
832void dcn10_link_encoder_setup(
833 struct link_encoder *enc,
834 enum signal_type signal)
835{
836 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
837
838 switch (signal) {
839 case SIGNAL_TYPE_EDP:
840 case SIGNAL_TYPE_DISPLAY_PORT:
841 /* DP SST */
842 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 0);
843 break;
844 case SIGNAL_TYPE_LVDS:
845 /* LVDS */
846 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 1);
847 break;
848 case SIGNAL_TYPE_DVI_SINGLE_LINK:
849 case SIGNAL_TYPE_DVI_DUAL_LINK:
850 /* TMDS-DVI */
851 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 2);
852 break;
853 case SIGNAL_TYPE_HDMI_TYPE_A:
854 /* TMDS-HDMI */
855 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 3);
856 break;
857 case SIGNAL_TYPE_DISPLAY_PORT_MST:
858 /* DP MST */
859 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 5);
860 break;
861 default:
862 ASSERT_CRITICAL(false);
863 /* invalid mode ! */
864 break;
865 }
866
867}
868
869/* TODO: still need depth or just pass in adjusted pixel clock? */
870void dcn10_link_encoder_enable_tmds_output(
871 struct link_encoder *enc,
872 enum clock_source_id clock_source,
873 enum dc_color_depth color_depth,
874 enum signal_type signal,
875 uint32_t pixel_clock)
876{
877 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
878 struct bp_transmitter_control cntl = { 0 };
879 enum bp_result result;
880
881 /* Enable the PHY */
882
883 cntl.action = TRANSMITTER_CONTROL_ENABLE;
884 cntl.engine_id = enc->preferred_engine;
885 cntl.transmitter = enc10->base.transmitter;
886 cntl.pll_id = clock_source;
887 cntl.signal = signal;
888 if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK)
889 cntl.lanes_number = 8;
890 else
891 cntl.lanes_number = 4;
892
893 cntl.hpd_sel = enc10->base.hpd_source;
894
895 cntl.pixel_clock = pixel_clock;
896 cntl.color_depth = color_depth;
897
898 result = link_transmitter_control(enc10, &cntl);
899
900 if (result != BP_RESULT_OK) {
901 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
902 __func__);
903 BREAK_TO_DEBUGGER();
904 }
905}
906
907/* enables DP PHY output */
908void dcn10_link_encoder_enable_dp_output(
909 struct link_encoder *enc,
910 const struct dc_link_settings *link_settings,
911 enum clock_source_id clock_source)
912{
913 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
914 struct bp_transmitter_control cntl = { 0 };
915 enum bp_result result;
916
917 /* Enable the PHY */
918
919 /* number_of_lanes is used for pixel clock adjust,
920 * but it's not passed to asic_control.
921 * We need to set number of lanes manually.
922 */
923 configure_encoder(enc10, link_settings);
924
925 cntl.action = TRANSMITTER_CONTROL_ENABLE;
926 cntl.engine_id = enc->preferred_engine;
927 cntl.transmitter = enc10->base.transmitter;
928 cntl.pll_id = clock_source;
929 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
930 cntl.lanes_number = link_settings->lane_count;
931 cntl.hpd_sel = enc10->base.hpd_source;
932 cntl.pixel_clock = link_settings->link_rate
933 * LINK_RATE_REF_FREQ_IN_KHZ;
934 /* TODO: check if undefined works */
935 cntl.color_depth = COLOR_DEPTH_UNDEFINED;
936
937 result = link_transmitter_control(enc10, &cntl);
938
939 if (result != BP_RESULT_OK) {
940 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
941 __func__);
942 BREAK_TO_DEBUGGER();
943 }
944}
945
946/* enables DP PHY output in MST mode */
947void dcn10_link_encoder_enable_dp_mst_output(
948 struct link_encoder *enc,
949 const struct dc_link_settings *link_settings,
950 enum clock_source_id clock_source)
951{
952 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
953 struct bp_transmitter_control cntl = { 0 };
954 enum bp_result result;
955
956 /* Enable the PHY */
957
958 /* number_of_lanes is used for pixel clock adjust,
959 * but it's not passed to asic_control.
960 * We need to set number of lanes manually.
961 */
962 configure_encoder(enc10, link_settings);
963
964 cntl.action = TRANSMITTER_CONTROL_ENABLE;
965 cntl.engine_id = ENGINE_ID_UNKNOWN;
966 cntl.transmitter = enc10->base.transmitter;
967 cntl.pll_id = clock_source;
968 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
969 cntl.lanes_number = link_settings->lane_count;
970 cntl.hpd_sel = enc10->base.hpd_source;
971 cntl.pixel_clock = link_settings->link_rate
972 * LINK_RATE_REF_FREQ_IN_KHZ;
973 /* TODO: check if undefined works */
974 cntl.color_depth = COLOR_DEPTH_UNDEFINED;
975
976 result = link_transmitter_control(enc10, &cntl);
977
978 if (result != BP_RESULT_OK) {
979 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
980 __func__);
981 BREAK_TO_DEBUGGER();
982 }
983}
984/*
985 * @brief
986 * Disable transmitter and its encoder
987 */
988void dcn10_link_encoder_disable_output(
989 struct link_encoder *enc,
990 enum signal_type signal)
991{
992 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
993 struct bp_transmitter_control cntl = { 0 };
994 enum bp_result result;
995
996 if (!dcn10_is_dig_enabled(enc)) {
997 /* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */
998 return;
999 }
1000 /* Power-down RX and disable GPU PHY should be paired.
1001 * Disabling PHY without powering down RX may cause
1002 * symbol lock loss, on which we will get DP Sink interrupt.
1003 */
1004
1005 /* There is a case for the DP active dongles
1006 * where we want to disable the PHY but keep RX powered,
1007 * for those we need to ignore DP Sink interrupt
1008 * by checking lane count that has been set
1009 * on the last do_enable_output().
1010 */
1011
1012 /* disable transmitter */
1013 cntl.action = TRANSMITTER_CONTROL_DISABLE;
1014 cntl.transmitter = enc10->base.transmitter;
1015 cntl.hpd_sel = enc10->base.hpd_source;
1016 cntl.signal = signal;
1017 cntl.connector_obj_id = enc10->base.connector;
1018
1019 result = link_transmitter_control(enc10, &cntl);
1020
1021 if (result != BP_RESULT_OK) {
1022 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1023 __func__);
1024 BREAK_TO_DEBUGGER();
1025 return;
1026 }
1027
1028 /* disable encoder */
1029 if (dc_is_dp_signal(signal))
1030 link_encoder_disable(enc10);
1031}
1032
1033void dcn10_link_encoder_dp_set_lane_settings(
1034 struct link_encoder *enc,
1035 const struct link_training_settings *link_settings)
1036{
1037 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1038 union dpcd_training_lane_set training_lane_set = { { 0 } };
1039 int32_t lane = 0;
1040 struct bp_transmitter_control cntl = { 0 };
1041
1042 if (!link_settings) {
1043 BREAK_TO_DEBUGGER();
1044 return;
1045 }
1046
1047 cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
1048 cntl.transmitter = enc10->base.transmitter;
1049 cntl.connector_obj_id = enc10->base.connector;
1050 cntl.lanes_number = link_settings->link_settings.lane_count;
1051 cntl.hpd_sel = enc10->base.hpd_source;
1052 cntl.pixel_clock = link_settings->link_settings.link_rate *
1053 LINK_RATE_REF_FREQ_IN_KHZ;
1054
1055 for (lane = 0; lane < link_settings->link_settings.lane_count; lane++) {
1056 /* translate lane settings */
1057
1058 training_lane_set.bits.VOLTAGE_SWING_SET =
1059 link_settings->lane_settings[lane].VOLTAGE_SWING;
1060 training_lane_set.bits.PRE_EMPHASIS_SET =
1061 link_settings->lane_settings[lane].PRE_EMPHASIS;
1062
1063 /* post cursor 2 setting only applies to HBR2 link rate */
1064 if (link_settings->link_settings.link_rate == LINK_RATE_HIGH2) {
1065 /* this is passed to VBIOS
1066 * to program post cursor 2 level
1067 */
1068 training_lane_set.bits.POST_CURSOR2_SET =
1069 link_settings->lane_settings[lane].POST_CURSOR2;
1070 }
1071
1072 cntl.lane_select = lane;
1073 cntl.lane_settings = training_lane_set.raw;
1074
1075 /* call VBIOS table to set voltage swing and pre-emphasis */
1076 link_transmitter_control(enc10, &cntl);
1077 }
1078}
1079
1080/* set DP PHY test and training patterns */
1081void dcn10_link_encoder_dp_set_phy_pattern(
1082 struct link_encoder *enc,
1083 const struct encoder_set_dp_phy_pattern_param *param)
1084{
1085 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1086
1087 switch (param->dp_phy_pattern) {
1088 case DP_TEST_PATTERN_TRAINING_PATTERN1:
1089 dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0);
1090 break;
1091 case DP_TEST_PATTERN_TRAINING_PATTERN2:
1092 dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1);
1093 break;
1094 case DP_TEST_PATTERN_TRAINING_PATTERN3:
1095 dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2);
1096 break;
1097 case DP_TEST_PATTERN_TRAINING_PATTERN4:
1098 dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3);
1099 break;
1100 case DP_TEST_PATTERN_D102:
1101 set_dp_phy_pattern_d102(enc10);
1102 break;
1103 case DP_TEST_PATTERN_SYMBOL_ERROR:
1104 set_dp_phy_pattern_symbol_error(enc10);
1105 break;
1106 case DP_TEST_PATTERN_PRBS7:
1107 set_dp_phy_pattern_prbs7(enc10);
1108 break;
1109 case DP_TEST_PATTERN_80BIT_CUSTOM:
1110 set_dp_phy_pattern_80bit_custom(
1111 enc10, param->custom_pattern);
1112 break;
1113 case DP_TEST_PATTERN_CP2520_1:
1114 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 1);
1115 break;
1116 case DP_TEST_PATTERN_CP2520_2:
1117 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 2);
1118 break;
1119 case DP_TEST_PATTERN_CP2520_3:
1120 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 3);
1121 break;
1122 case DP_TEST_PATTERN_VIDEO_MODE: {
1123 set_dp_phy_pattern_passthrough_mode(
1124 enc10, param->dp_panel_mode);
1125 break;
1126 }
1127
1128 default:
1129 /* invalid phy pattern */
1130 ASSERT_CRITICAL(false);
1131 break;
1132 }
1133}
1134
1135static void fill_stream_allocation_row_info(
1136 const struct link_mst_stream_allocation *stream_allocation,
1137 uint32_t *src,
1138 uint32_t *slots)
1139{
1140 const struct stream_encoder *stream_enc = stream_allocation->stream_enc;
1141
1142 if (stream_enc) {
1143 *src = stream_enc->id;
1144 *slots = stream_allocation->slot_count;
1145 } else {
1146 *src = 0;
1147 *slots = 0;
1148 }
1149}
1150
1151/* programs DP MST VC payload allocation */
1152void dcn10_link_encoder_update_mst_stream_allocation_table(
1153 struct link_encoder *enc,
1154 const struct link_mst_stream_allocation_table *table)
1155{
1156 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1157 uint32_t value0 = 0;
1158 uint32_t value1 = 0;
1159 uint32_t value2 = 0;
1160 uint32_t slots = 0;
1161 uint32_t src = 0;
1162 uint32_t retries = 0;
1163
1164 /* For CZ, there are only 3 pipes. So Virtual channel is up 3.*/
1165
1166 /* --- Set MSE Stream Attribute -
1167 * Setup VC Payload Table on Tx Side,
1168 * Issue allocation change trigger
1169 * to commit payload on both tx and rx side
1170 */
1171
1172 /* we should clean-up table each time */
1173
1174 if (table->stream_count >= 1) {
1175 fill_stream_allocation_row_info(
1176 &table->stream_allocations[0],
1177 &src,
1178 &slots);
1179 } else {
1180 src = 0;
1181 slots = 0;
1182 }
1183
1184 REG_UPDATE_2(DP_MSE_SAT0,
1185 DP_MSE_SAT_SRC0, src,
1186 DP_MSE_SAT_SLOT_COUNT0, slots);
1187
1188 if (table->stream_count >= 2) {
1189 fill_stream_allocation_row_info(
1190 &table->stream_allocations[1],
1191 &src,
1192 &slots);
1193 } else {
1194 src = 0;
1195 slots = 0;
1196 }
1197
1198 REG_UPDATE_2(DP_MSE_SAT0,
1199 DP_MSE_SAT_SRC1, src,
1200 DP_MSE_SAT_SLOT_COUNT1, slots);
1201
1202 if (table->stream_count >= 3) {
1203 fill_stream_allocation_row_info(
1204 &table->stream_allocations[2],
1205 &src,
1206 &slots);
1207 } else {
1208 src = 0;
1209 slots = 0;
1210 }
1211
1212 REG_UPDATE_2(DP_MSE_SAT1,
1213 DP_MSE_SAT_SRC2, src,
1214 DP_MSE_SAT_SLOT_COUNT2, slots);
1215
1216 if (table->stream_count >= 4) {
1217 fill_stream_allocation_row_info(
1218 &table->stream_allocations[3],
1219 &src,
1220 &slots);
1221 } else {
1222 src = 0;
1223 slots = 0;
1224 }
1225
1226 REG_UPDATE_2(DP_MSE_SAT1,
1227 DP_MSE_SAT_SRC3, src,
1228 DP_MSE_SAT_SLOT_COUNT3, slots);
1229
1230 /* --- wait for transaction finish */
1231
1232 /* send allocation change trigger (ACT) ?
1233 * this step first sends the ACT,
1234 * then double buffers the SAT into the hardware
1235 * making the new allocation active on the DP MST mode link
1236 */
1237
1238 /* DP_MSE_SAT_UPDATE:
1239 * 0 - No Action
1240 * 1 - Update SAT with trigger
1241 * 2 - Update SAT without trigger
1242 */
1243 REG_UPDATE(DP_MSE_SAT_UPDATE,
1244 DP_MSE_SAT_UPDATE, 1);
1245
1246 /* wait for update to complete
1247 * (i.e. DP_MSE_SAT_UPDATE field is reset to 0)
1248 * then wait for the transmission
1249 * of at least 16 MTP headers on immediate local link.
1250 * i.e. DP_MSE_16_MTP_KEEPOUT field (read only) is reset to 0
1251 * a value of 1 indicates that DP MST mode
1252 * is in the 16 MTP keepout region after a VC has been added.
1253 * MST stream bandwidth (VC rate) can be configured
1254 * after this bit is cleared
1255 */
1256 do {
1257 udelay(10);
1258
1259 value0 = REG_READ(DP_MSE_SAT_UPDATE);
1260
1261 REG_GET(DP_MSE_SAT_UPDATE,
1262 DP_MSE_SAT_UPDATE, &value1);
1263
1264 REG_GET(DP_MSE_SAT_UPDATE,
1265 DP_MSE_16_MTP_KEEPOUT, &value2);
1266
1267 /* bit field DP_MSE_SAT_UPDATE is set to 1 already */
1268 if (!value1 && !value2)
1269 break;
1270 ++retries;
1271 } while (retries < DP_MST_UPDATE_MAX_RETRY);
1272}
1273
1274void dcn10_link_encoder_connect_dig_be_to_fe(
1275 struct link_encoder *enc,
1276 enum engine_id engine,
1277 bool connect)
1278{
1279 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1280 uint32_t field;
1281
1282 if (engine != ENGINE_ID_UNKNOWN) {
1283
1284 REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &field);
1285
1286 if (connect)
1287 field |= get_frontend_source(engine);
1288 else
1289 field &= ~get_frontend_source(engine);
1290
1291 REG_UPDATE(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, field);
1292 }
1293}
1294
1295
1296#define HPD_REG(reg)\
1297 (enc10->hpd_regs->reg)
1298
1299#define HPD_REG_READ(reg_name) \
1300 dm_read_reg(CTX, HPD_REG(reg_name))
1301
1302#define HPD_REG_UPDATE_N(reg_name, n, ...) \
1303 generic_reg_update_ex(CTX, \
1304 HPD_REG(reg_name), \
1305 HPD_REG_READ(reg_name), \
1306 n, __VA_ARGS__)
1307
1308#define HPD_REG_UPDATE(reg_name, field, val) \
1309 HPD_REG_UPDATE_N(reg_name, 1, \
1310 FN(reg_name, field), val)
1311
1312void dcn10_link_encoder_enable_hpd(struct link_encoder *enc)
1313{
1314 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1315
1316 HPD_REG_UPDATE(DC_HPD_CONTROL,
1317 DC_HPD_EN, 1);
1318}
1319
1320void dcn10_link_encoder_disable_hpd(struct link_encoder *enc)
1321{
1322 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1323
1324 HPD_REG_UPDATE(DC_HPD_CONTROL,
1325 DC_HPD_EN, 0);
1326}
1327
1328
1329#define AUX_REG(reg)\
1330 (enc10->aux_regs->reg)
1331
1332#define AUX_REG_READ(reg_name) \
1333 dm_read_reg(CTX, AUX_REG(reg_name))
1334
1335#define AUX_REG_UPDATE_N(reg_name, n, ...) \
1336 generic_reg_update_ex(CTX, \
1337 AUX_REG(reg_name), \
1338 AUX_REG_READ(reg_name), \
1339 n, __VA_ARGS__)
1340
1341#define AUX_REG_UPDATE(reg_name, field, val) \
1342 AUX_REG_UPDATE_N(reg_name, 1, \
1343 FN(reg_name, field), val)
1344
1345#define AUX_REG_UPDATE_2(reg, f1, v1, f2, v2) \
1346 AUX_REG_UPDATE_N(reg, 2,\
1347 FN(reg, f1), v1,\
1348 FN(reg, f2), v2)
1349
1350static void aux_initialize(
1351 struct dcn10_link_encoder *enc10)
1352{
1353 enum hpd_source_id hpd_source = enc10->base.hpd_source;
1354
1355 AUX_REG_UPDATE_2(AUX_CONTROL,
1356 AUX_HPD_SEL, hpd_source,
1357 AUX_LS_READ_EN, 0);
1358
1359 /* 1/4 window (the maximum allowed) */
1360 AUX_REG_UPDATE(AUX_DPHY_RX_CONTROL0,
1361 AUX_RX_RECEIVE_WINDOW, 1);
1362}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
new file mode 100644
index 000000000000..2a97cdb2cfbb
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
@@ -0,0 +1,330 @@
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#ifndef __DC_LINK_ENCODER__DCN10_H__
27#define __DC_LINK_ENCODER__DCN10_H__
28
29#include "link_encoder.h"
30
31#define TO_DCN10_LINK_ENC(link_encoder)\
32 container_of(link_encoder, struct dcn10_link_encoder, base)
33
34
35#define AUX_REG_LIST(id)\
36 SRI(AUX_CONTROL, DP_AUX, id), \
37 SRI(AUX_DPHY_RX_CONTROL0, DP_AUX, id)
38
39#define HPD_REG_LIST(id)\
40 SRI(DC_HPD_CONTROL, HPD, id)
41
42#define LE_DCN_COMMON_REG_LIST(id) \
43 SRI(DIG_BE_CNTL, DIG, id), \
44 SRI(DIG_BE_EN_CNTL, DIG, id), \
45 SRI(DP_CONFIG, DP, id), \
46 SRI(DP_DPHY_CNTL, DP, id), \
47 SRI(DP_DPHY_PRBS_CNTL, DP, id), \
48 SRI(DP_DPHY_SCRAM_CNTL, DP, id),\
49 SRI(DP_DPHY_SYM0, DP, id), \
50 SRI(DP_DPHY_SYM1, DP, id), \
51 SRI(DP_DPHY_SYM2, DP, id), \
52 SRI(DP_DPHY_TRAINING_PATTERN_SEL, DP, id), \
53 SRI(DP_LINK_CNTL, DP, id), \
54 SRI(DP_LINK_FRAMING_CNTL, DP, id), \
55 SRI(DP_MSE_SAT0, DP, id), \
56 SRI(DP_MSE_SAT1, DP, id), \
57 SRI(DP_MSE_SAT2, DP, id), \
58 SRI(DP_MSE_SAT_UPDATE, DP, id), \
59 SRI(DP_SEC_CNTL, DP, id), \
60 SRI(DP_VID_STREAM_CNTL, DP, id), \
61 SRI(DP_DPHY_FAST_TRAINING, DP, id), \
62 SRI(DP_SEC_CNTL1, DP, id), \
63 SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
64 SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
65 SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id)
66
67#define LE_DCN10_REG_LIST(id)\
68 LE_DCN_COMMON_REG_LIST(id)
69
70struct dcn10_link_enc_aux_registers {
71 uint32_t AUX_CONTROL;
72 uint32_t AUX_DPHY_RX_CONTROL0;
73};
74
75struct dcn10_link_enc_hpd_registers {
76 uint32_t DC_HPD_CONTROL;
77};
78
79struct dcn10_link_enc_registers {
80 uint32_t DIG_BE_CNTL;
81 uint32_t DIG_BE_EN_CNTL;
82 uint32_t DP_CONFIG;
83 uint32_t DP_DPHY_CNTL;
84 uint32_t DP_DPHY_INTERNAL_CTRL;
85 uint32_t DP_DPHY_PRBS_CNTL;
86 uint32_t DP_DPHY_SCRAM_CNTL;
87 uint32_t DP_DPHY_SYM0;
88 uint32_t DP_DPHY_SYM1;
89 uint32_t DP_DPHY_SYM2;
90 uint32_t DP_DPHY_TRAINING_PATTERN_SEL;
91 uint32_t DP_LINK_CNTL;
92 uint32_t DP_LINK_FRAMING_CNTL;
93 uint32_t DP_MSE_SAT0;
94 uint32_t DP_MSE_SAT1;
95 uint32_t DP_MSE_SAT2;
96 uint32_t DP_MSE_SAT_UPDATE;
97 uint32_t DP_SEC_CNTL;
98 uint32_t DP_VID_STREAM_CNTL;
99 uint32_t DP_DPHY_FAST_TRAINING;
100 uint32_t DP_DPHY_BS_SR_SWAP_CNTL;
101 uint32_t DP_DPHY_HBR2_PATTERN_CONTROL;
102 uint32_t DP_SEC_CNTL1;
103};
104
105#define LE_SF(reg_name, field_name, post_fix)\
106 .field_name = reg_name ## __ ## field_name ## post_fix
107
108#define LINK_ENCODER_MASK_SH_LIST_DCN10(mask_sh)\
109 LE_SF(DIG0_DIG_BE_EN_CNTL, DIG_ENABLE, mask_sh),\
110 LE_SF(DIG0_DIG_BE_CNTL, DIG_HPD_SELECT, mask_sh),\
111 LE_SF(DIG0_DIG_BE_CNTL, DIG_MODE, mask_sh),\
112 LE_SF(DIG0_DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, mask_sh),\
113 LE_SF(DP0_DP_DPHY_CNTL, DPHY_BYPASS, mask_sh),\
114 LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE0, mask_sh),\
115 LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE1, mask_sh),\
116 LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE2, mask_sh),\
117 LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE3, mask_sh),\
118 LE_SF(DP0_DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN, mask_sh),\
119 LE_SF(DP0_DP_DPHY_PRBS_CNTL, DPHY_PRBS_SEL, mask_sh),\
120 LE_SF(DP0_DP_DPHY_SYM0, DPHY_SYM1, mask_sh),\
121 LE_SF(DP0_DP_DPHY_SYM0, DPHY_SYM2, mask_sh),\
122 LE_SF(DP0_DP_DPHY_SYM0, DPHY_SYM3, mask_sh),\
123 LE_SF(DP0_DP_DPHY_SYM1, DPHY_SYM4, mask_sh),\
124 LE_SF(DP0_DP_DPHY_SYM1, DPHY_SYM5, mask_sh),\
125 LE_SF(DP0_DP_DPHY_SYM1, DPHY_SYM6, mask_sh),\
126 LE_SF(DP0_DP_DPHY_SYM2, DPHY_SYM7, mask_sh),\
127 LE_SF(DP0_DP_DPHY_SYM2, DPHY_SYM8, mask_sh),\
128 LE_SF(DP0_DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, mask_sh),\
129 LE_SF(DP0_DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, mask_sh),\
130 LE_SF(DP0_DP_DPHY_FAST_TRAINING, DPHY_RX_FAST_TRAINING_CAPABLE, mask_sh),\
131 LE_SF(DP0_DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, mask_sh),\
132 LE_SF(DP0_DP_DPHY_TRAINING_PATTERN_SEL, DPHY_TRAINING_PATTERN_SEL, mask_sh),\
133 LE_SF(DP0_DP_DPHY_HBR2_PATTERN_CONTROL, DP_DPHY_HBR2_PATTERN_CONTROL, mask_sh),\
134 LE_SF(DP0_DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, mask_sh),\
135 LE_SF(DP0_DP_LINK_FRAMING_CNTL, DP_IDLE_BS_INTERVAL, mask_sh),\
136 LE_SF(DP0_DP_LINK_FRAMING_CNTL, DP_VBID_DISABLE, mask_sh),\
137 LE_SF(DP0_DP_LINK_FRAMING_CNTL, DP_VID_ENHANCED_FRAME_MODE, mask_sh),\
138 LE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, mask_sh),\
139 LE_SF(DP0_DP_CONFIG, DP_UDI_LANES, mask_sh),\
140 LE_SF(DP0_DP_SEC_CNTL1, DP_SEC_GSP0_LINE_NUM, mask_sh),\
141 LE_SF(DP0_DP_SEC_CNTL1, DP_SEC_GSP0_PRIORITY, mask_sh),\
142 LE_SF(DP0_DP_MSE_SAT0, DP_MSE_SAT_SRC0, mask_sh),\
143 LE_SF(DP0_DP_MSE_SAT0, DP_MSE_SAT_SRC1, mask_sh),\
144 LE_SF(DP0_DP_MSE_SAT0, DP_MSE_SAT_SLOT_COUNT0, mask_sh),\
145 LE_SF(DP0_DP_MSE_SAT0, DP_MSE_SAT_SLOT_COUNT1, mask_sh),\
146 LE_SF(DP0_DP_MSE_SAT1, DP_MSE_SAT_SRC2, mask_sh),\
147 LE_SF(DP0_DP_MSE_SAT1, DP_MSE_SAT_SRC3, mask_sh),\
148 LE_SF(DP0_DP_MSE_SAT1, DP_MSE_SAT_SLOT_COUNT2, mask_sh),\
149 LE_SF(DP0_DP_MSE_SAT1, DP_MSE_SAT_SLOT_COUNT3, mask_sh),\
150 LE_SF(DP0_DP_MSE_SAT_UPDATE, DP_MSE_SAT_UPDATE, mask_sh),\
151 LE_SF(DP0_DP_MSE_SAT_UPDATE, DP_MSE_16_MTP_KEEPOUT, mask_sh),\
152 LE_SF(DP_AUX0_AUX_CONTROL, AUX_HPD_SEL, mask_sh),\
153 LE_SF(DP_AUX0_AUX_CONTROL, AUX_LS_READ_EN, mask_sh),\
154 LE_SF(DP_AUX0_AUX_DPHY_RX_CONTROL0, AUX_RX_RECEIVE_WINDOW, mask_sh),\
155 LE_SF(HPD0_DC_HPD_CONTROL, DC_HPD_EN, mask_sh)
156
157#define DCN_LINK_ENCODER_REG_FIELD_LIST(type) \
158 type DIG_ENABLE;\
159 type DIG_HPD_SELECT;\
160 type DIG_MODE;\
161 type DIG_FE_SOURCE_SELECT;\
162 type DPHY_BYPASS;\
163 type DPHY_ATEST_SEL_LANE0;\
164 type DPHY_ATEST_SEL_LANE1;\
165 type DPHY_ATEST_SEL_LANE2;\
166 type DPHY_ATEST_SEL_LANE3;\
167 type DPHY_PRBS_EN;\
168 type DPHY_PRBS_SEL;\
169 type DPHY_SYM1;\
170 type DPHY_SYM2;\
171 type DPHY_SYM3;\
172 type DPHY_SYM4;\
173 type DPHY_SYM5;\
174 type DPHY_SYM6;\
175 type DPHY_SYM7;\
176 type DPHY_SYM8;\
177 type DPHY_SCRAMBLER_BS_COUNT;\
178 type DPHY_SCRAMBLER_ADVANCE;\
179 type DPHY_RX_FAST_TRAINING_CAPABLE;\
180 type DPHY_LOAD_BS_COUNT;\
181 type DPHY_TRAINING_PATTERN_SEL;\
182 type DP_DPHY_HBR2_PATTERN_CONTROL;\
183 type DP_LINK_TRAINING_COMPLETE;\
184 type DP_IDLE_BS_INTERVAL;\
185 type DP_VBID_DISABLE;\
186 type DP_VID_ENHANCED_FRAME_MODE;\
187 type DP_VID_STREAM_ENABLE;\
188 type DP_UDI_LANES;\
189 type DP_SEC_GSP0_LINE_NUM;\
190 type DP_SEC_GSP0_PRIORITY;\
191 type DP_MSE_SAT_SRC0;\
192 type DP_MSE_SAT_SRC1;\
193 type DP_MSE_SAT_SRC2;\
194 type DP_MSE_SAT_SRC3;\
195 type DP_MSE_SAT_SLOT_COUNT0;\
196 type DP_MSE_SAT_SLOT_COUNT1;\
197 type DP_MSE_SAT_SLOT_COUNT2;\
198 type DP_MSE_SAT_SLOT_COUNT3;\
199 type DP_MSE_SAT_UPDATE;\
200 type DP_MSE_16_MTP_KEEPOUT;\
201 type AUX_HPD_SEL;\
202 type AUX_LS_READ_EN;\
203 type AUX_RX_RECEIVE_WINDOW;\
204 type DC_HPD_EN
205
206struct dcn10_link_enc_shift {
207 DCN_LINK_ENCODER_REG_FIELD_LIST(uint8_t);
208};
209
210struct dcn10_link_enc_mask {
211 DCN_LINK_ENCODER_REG_FIELD_LIST(uint32_t);
212};
213
214struct dcn10_link_encoder {
215 struct link_encoder base;
216 const struct dcn10_link_enc_registers *link_regs;
217 const struct dcn10_link_enc_aux_registers *aux_regs;
218 const struct dcn10_link_enc_hpd_registers *hpd_regs;
219 const struct dcn10_link_enc_shift *link_shift;
220 const struct dcn10_link_enc_mask *link_mask;
221};
222
223
224void dcn10_link_encoder_construct(
225 struct dcn10_link_encoder *enc10,
226 const struct encoder_init_data *init_data,
227 const struct encoder_feature_support *enc_features,
228 const struct dcn10_link_enc_registers *link_regs,
229 const struct dcn10_link_enc_aux_registers *aux_regs,
230 const struct dcn10_link_enc_hpd_registers *hpd_regs,
231 const struct dcn10_link_enc_shift *link_shift,
232 const struct dcn10_link_enc_mask *link_mask);
233
234bool dcn10_link_encoder_validate_dvi_output(
235 const struct dcn10_link_encoder *enc10,
236 enum signal_type connector_signal,
237 enum signal_type signal,
238 const struct dc_crtc_timing *crtc_timing);
239
240bool dcn10_link_encoder_validate_rgb_output(
241 const struct dcn10_link_encoder *enc10,
242 const struct dc_crtc_timing *crtc_timing);
243
244bool dcn10_link_encoder_validate_dp_output(
245 const struct dcn10_link_encoder *enc10,
246 const struct dc_crtc_timing *crtc_timing);
247
248bool dcn10_link_encoder_validate_wireless_output(
249 const struct dcn10_link_encoder *enc10,
250 const struct dc_crtc_timing *crtc_timing);
251
252bool dcn10_link_encoder_validate_output_with_stream(
253 struct link_encoder *enc,
254 const struct dc_stream_state *stream);
255
256/****************** HW programming ************************/
257
258/* initialize HW */ /* why do we initialze aux in here? */
259void dcn10_link_encoder_hw_init(struct link_encoder *enc);
260
261void dcn10_link_encoder_destroy(struct link_encoder **enc);
262
263/* program DIG_MODE in DIG_BE */
264/* TODO can this be combined with enable_output? */
265void dcn10_link_encoder_setup(
266 struct link_encoder *enc,
267 enum signal_type signal);
268
269/* enables TMDS PHY output */
270/* TODO: still need depth or just pass in adjusted pixel clock? */
271void dcn10_link_encoder_enable_tmds_output(
272 struct link_encoder *enc,
273 enum clock_source_id clock_source,
274 enum dc_color_depth color_depth,
275 enum signal_type signal,
276 uint32_t pixel_clock);
277
278/* enables DP PHY output */
279void dcn10_link_encoder_enable_dp_output(
280 struct link_encoder *enc,
281 const struct dc_link_settings *link_settings,
282 enum clock_source_id clock_source);
283
284/* enables DP PHY output in MST mode */
285void dcn10_link_encoder_enable_dp_mst_output(
286 struct link_encoder *enc,
287 const struct dc_link_settings *link_settings,
288 enum clock_source_id clock_source);
289
290/* disable PHY output */
291void dcn10_link_encoder_disable_output(
292 struct link_encoder *enc,
293 enum signal_type signal);
294
295/* set DP lane settings */
296void dcn10_link_encoder_dp_set_lane_settings(
297 struct link_encoder *enc,
298 const struct link_training_settings *link_settings);
299
300void dcn10_link_encoder_dp_set_phy_pattern(
301 struct link_encoder *enc,
302 const struct encoder_set_dp_phy_pattern_param *param);
303
304/* programs DP MST VC payload allocation */
305void dcn10_link_encoder_update_mst_stream_allocation_table(
306 struct link_encoder *enc,
307 const struct link_mst_stream_allocation_table *table);
308
309void dcn10_link_encoder_connect_dig_be_to_fe(
310 struct link_encoder *enc,
311 enum engine_id engine,
312 bool connect);
313
314void dcn10_link_encoder_set_dp_phy_pattern_training_pattern(
315 struct link_encoder *enc,
316 uint32_t index);
317
318void dcn10_link_encoder_enable_hpd(struct link_encoder *enc);
319
320void dcn10_link_encoder_disable_hpd(struct link_encoder *enc);
321
322void dcn10_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
323 bool exit_link_training_required);
324
325void dcn10_psr_program_secondary_packet(struct link_encoder *enc,
326 unsigned int sdp_transmit_line_num_deadline);
327
328bool dcn10_is_dig_enabled(struct link_encoder *enc);
329
330#endif /* __DC_LINK_ENCODER__DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
index 179890b1a8c4..9ca51ae46de7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
@@ -65,6 +65,7 @@ static void mpc1_update_blending(
65 int mpcc_id) 65 int mpcc_id)
66{ 66{
67 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); 67 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
68 struct mpcc *mpcc = mpc1_get_mpcc(mpc, mpcc_id);
68 69
69 REG_UPDATE_5(MPCC_CONTROL[mpcc_id], 70 REG_UPDATE_5(MPCC_CONTROL[mpcc_id],
70 MPCC_ALPHA_BLND_MODE, blnd_cfg->alpha_mode, 71 MPCC_ALPHA_BLND_MODE, blnd_cfg->alpha_mode,
@@ -74,6 +75,7 @@ static void mpc1_update_blending(
74 MPCC_GLOBAL_GAIN, blnd_cfg->global_gain); 75 MPCC_GLOBAL_GAIN, blnd_cfg->global_gain);
75 76
76 mpc1_set_bg_color(mpc, &blnd_cfg->black_color, mpcc_id); 77 mpc1_set_bg_color(mpc, &blnd_cfg->black_color, mpcc_id);
78 mpcc->blnd_cfg = *blnd_cfg;
77} 79}
78 80
79void mpc1_update_stereo_mix( 81void mpc1_update_stereo_mix(
@@ -235,8 +237,7 @@ struct mpcc *mpc1_insert_plane(
235 } 237 }
236 238
237 /* update the blending configuration */ 239 /* update the blending configuration */
238 new_mpcc->blnd_cfg = *blnd_cfg; 240 mpc->funcs->update_blending(mpc, blnd_cfg, mpcc_id);
239 mpc->funcs->update_blending(mpc, &new_mpcc->blnd_cfg, mpcc_id);
240 241
241 /* update the stereo mix settings, if provided */ 242 /* update the stereo mix settings, if provided */
242 if (sm_cfg != NULL) { 243 if (sm_cfg != NULL) {
@@ -409,7 +410,26 @@ void mpc1_init_mpcc_list_from_hw(
409 } 410 }
410} 411}
411 412
413void mpc1_read_mpcc_state(
414 struct mpc *mpc,
415 int mpcc_inst,
416 struct mpcc_state *s)
417{
418 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
419
420 REG_GET(MPCC_OPP_ID[mpcc_inst], MPCC_OPP_ID, &s->opp_id);
421 REG_GET(MPCC_TOP_SEL[mpcc_inst], MPCC_TOP_SEL, &s->dpp_id);
422 REG_GET(MPCC_BOT_SEL[mpcc_inst], MPCC_BOT_SEL, &s->bot_mpcc_id);
423 REG_GET_4(MPCC_CONTROL[mpcc_inst], MPCC_MODE, &s->mode,
424 MPCC_ALPHA_BLND_MODE, &s->alpha_mode,
425 MPCC_ALPHA_MULTIPLIED_MODE, &s->pre_multiplied_alpha,
426 MPCC_BLND_ACTIVE_OVERLAP_ONLY, &s->overlap_only);
427 REG_GET_2(MPCC_STATUS[mpcc_inst], MPCC_IDLE, &s->idle,
428 MPCC_BUSY, &s->busy);
429}
430
412const struct mpc_funcs dcn10_mpc_funcs = { 431const struct mpc_funcs dcn10_mpc_funcs = {
432 .read_mpcc_state = mpc1_read_mpcc_state,
413 .insert_plane = mpc1_insert_plane, 433 .insert_plane = mpc1_insert_plane,
414 .remove_mpcc = mpc1_remove_mpcc, 434 .remove_mpcc = mpc1_remove_mpcc,
415 .mpc_init = mpc1_mpc_init, 435 .mpc_init = mpc1_mpc_init,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
index 267a2995ef6e..d3d16c4cbea3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
@@ -183,4 +183,9 @@ struct mpcc *mpc1_get_mpcc_for_dpp(
183 struct mpc_tree *tree, 183 struct mpc_tree *tree,
184 int dpp_id); 184 int dpp_id);
185 185
186void mpc1_read_mpcc_state(
187 struct mpc *mpc,
188 int mpcc_inst,
189 struct mpcc_state *s);
190
186#endif 191#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
index 4bf64d1b2c60..f2fbce0e3fc5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
@@ -93,6 +93,81 @@ static void optc1_disable_stereo(struct timing_generator *optc)
93 OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); 93 OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
94} 94}
95 95
96static uint32_t get_start_vline(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing)
97{
98 struct dc_crtc_timing patched_crtc_timing;
99 int vesa_sync_start;
100 int asic_blank_end;
101 int interlace_factor;
102 int vertical_line_start;
103
104 patched_crtc_timing = *dc_crtc_timing;
105 optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);
106
107 vesa_sync_start = patched_crtc_timing.h_addressable +
108 patched_crtc_timing.h_border_right +
109 patched_crtc_timing.h_front_porch;
110
111 asic_blank_end = patched_crtc_timing.h_total -
112 vesa_sync_start -
113 patched_crtc_timing.h_border_left;
114
115 interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1;
116
117 vesa_sync_start = patched_crtc_timing.v_addressable +
118 patched_crtc_timing.v_border_bottom +
119 patched_crtc_timing.v_front_porch;
120
121 asic_blank_end = (patched_crtc_timing.v_total -
122 vesa_sync_start -
123 patched_crtc_timing.v_border_top)
124 * interlace_factor;
125
126 vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
127 if (vertical_line_start < 0) {
128 ASSERT(0);
129 vertical_line_start = 0;
130 }
131
132 return vertical_line_start;
133}
134
135void optc1_program_vline_interrupt(
136 struct timing_generator *optc,
137 const struct dc_crtc_timing *dc_crtc_timing,
138 unsigned long long vsync_delta)
139{
140
141 struct optc *optc1 = DCN10TG_FROM_TG(optc);
142
143 unsigned long long req_delta_tens_of_usec = div64_u64((vsync_delta + 9999), 10000);
144 unsigned long long pix_clk_hundreds_khz = div64_u64((dc_crtc_timing->pix_clk_khz + 99), 100);
145 uint32_t req_delta_lines = (uint32_t) div64_u64(
146 (req_delta_tens_of_usec * pix_clk_hundreds_khz + dc_crtc_timing->h_total - 1),
147 dc_crtc_timing->h_total);
148
149 uint32_t vsync_line = get_start_vline(optc, dc_crtc_timing);
150 uint32_t start_line = 0;
151 uint32_t endLine = 0;
152
153 if (req_delta_lines != 0)
154 req_delta_lines--;
155
156 if (req_delta_lines > vsync_line)
157 start_line = dc_crtc_timing->v_total - (req_delta_lines - vsync_line) - 1;
158 else
159 start_line = vsync_line - req_delta_lines;
160
161 endLine = start_line + 2;
162
163 if (endLine >= dc_crtc_timing->v_total)
164 endLine = 2;
165
166 REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0,
167 OTG_VERTICAL_INTERRUPT0_LINE_START, start_line,
168 OTG_VERTICAL_INTERRUPT0_LINE_END, endLine);
169}
170
96/** 171/**
97 * program_timing_generator used by mode timing set 172 * program_timing_generator used by mode timing set
98 * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition. 173 * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition.
@@ -285,7 +360,7 @@ void optc1_program_timing(
285 360
286} 361}
287 362
288static void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable) 363void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable)
289{ 364{
290 struct optc *optc1 = DCN10TG_FROM_TG(optc); 365 struct optc *optc1 = DCN10TG_FROM_TG(optc);
291 366
@@ -780,17 +855,17 @@ void optc1_set_drr(
780 OTG_SET_V_TOTAL_MIN_MASK_EN, 0, 855 OTG_SET_V_TOTAL_MIN_MASK_EN, 0,
781 OTG_SET_V_TOTAL_MIN_MASK, 0); 856 OTG_SET_V_TOTAL_MIN_MASK, 0);
782 } else { 857 } else {
783 REG_SET(OTG_V_TOTAL_MIN, 0,
784 OTG_V_TOTAL_MIN, 0);
785
786 REG_SET(OTG_V_TOTAL_MAX, 0,
787 OTG_V_TOTAL_MAX, 0);
788
789 REG_UPDATE_4(OTG_V_TOTAL_CONTROL, 858 REG_UPDATE_4(OTG_V_TOTAL_CONTROL,
790 OTG_SET_V_TOTAL_MIN_MASK, 0, 859 OTG_SET_V_TOTAL_MIN_MASK, 0,
791 OTG_V_TOTAL_MIN_SEL, 0, 860 OTG_V_TOTAL_MIN_SEL, 0,
792 OTG_V_TOTAL_MAX_SEL, 0, 861 OTG_V_TOTAL_MAX_SEL, 0,
793 OTG_FORCE_LOCK_ON_EVENT, 0); 862 OTG_FORCE_LOCK_ON_EVENT, 0);
863
864 REG_SET(OTG_V_TOTAL_MIN, 0,
865 OTG_V_TOTAL_MIN, 0);
866
867 REG_SET(OTG_V_TOTAL_MAX, 0,
868 OTG_V_TOTAL_MAX, 0);
794 } 869 }
795} 870}
796 871
@@ -1154,6 +1229,12 @@ void optc1_read_otg_state(struct optc *optc1,
1154 REG_GET(OTG_V_TOTAL_MIN, 1229 REG_GET(OTG_V_TOTAL_MIN,
1155 OTG_V_TOTAL_MIN, &s->v_total_min); 1230 OTG_V_TOTAL_MIN, &s->v_total_min);
1156 1231
1232 REG_GET(OTG_V_TOTAL_CONTROL,
1233 OTG_V_TOTAL_MAX_SEL, &s->v_total_max_sel);
1234
1235 REG_GET(OTG_V_TOTAL_CONTROL,
1236 OTG_V_TOTAL_MIN_SEL, &s->v_total_min_sel);
1237
1157 REG_GET_2(OTG_V_SYNC_A, 1238 REG_GET_2(OTG_V_SYNC_A,
1158 OTG_V_SYNC_A_START, &s->v_sync_a_start, 1239 OTG_V_SYNC_A_START, &s->v_sync_a_start,
1159 OTG_V_SYNC_A_END, &s->v_sync_a_end); 1240 OTG_V_SYNC_A_END, &s->v_sync_a_end);
@@ -1176,20 +1257,20 @@ void optc1_read_otg_state(struct optc *optc1,
1176 OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status); 1257 OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status);
1177} 1258}
1178 1259
1179static void optc1_clear_optc_underflow(struct timing_generator *optc) 1260void optc1_clear_optc_underflow(struct timing_generator *optc)
1180{ 1261{
1181 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1262 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1182 1263
1183 REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1); 1264 REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1);
1184} 1265}
1185 1266
1186static void optc1_tg_init(struct timing_generator *optc) 1267void optc1_tg_init(struct timing_generator *optc)
1187{ 1268{
1188 optc1_set_blank_data_double_buffer(optc, true); 1269 optc1_set_blank_data_double_buffer(optc, true);
1189 optc1_clear_optc_underflow(optc); 1270 optc1_clear_optc_underflow(optc);
1190} 1271}
1191 1272
1192static bool optc1_is_tg_enabled(struct timing_generator *optc) 1273bool optc1_is_tg_enabled(struct timing_generator *optc)
1193{ 1274{
1194 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1275 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1195 uint32_t otg_enabled = 0; 1276 uint32_t otg_enabled = 0;
@@ -1200,7 +1281,7 @@ static bool optc1_is_tg_enabled(struct timing_generator *optc)
1200 1281
1201} 1282}
1202 1283
1203static bool optc1_is_optc_underflow_occurred(struct timing_generator *optc) 1284bool optc1_is_optc_underflow_occurred(struct timing_generator *optc)
1204{ 1285{
1205 struct optc *optc1 = DCN10TG_FROM_TG(optc); 1286 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1206 uint32_t underflow_occurred = 0; 1287 uint32_t underflow_occurred = 0;
@@ -1215,6 +1296,7 @@ static bool optc1_is_optc_underflow_occurred(struct timing_generator *optc)
1215static const struct timing_generator_funcs dcn10_tg_funcs = { 1296static const struct timing_generator_funcs dcn10_tg_funcs = {
1216 .validate_timing = optc1_validate_timing, 1297 .validate_timing = optc1_validate_timing,
1217 .program_timing = optc1_program_timing, 1298 .program_timing = optc1_program_timing,
1299 .program_vline_interrupt = optc1_program_vline_interrupt,
1218 .program_global_sync = optc1_program_global_sync, 1300 .program_global_sync = optc1_program_global_sync,
1219 .enable_crtc = optc1_enable_crtc, 1301 .enable_crtc = optc1_enable_crtc,
1220 .disable_crtc = optc1_disable_crtc, 1302 .disable_crtc = optc1_disable_crtc,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
index d25e7bf0d0d7..c62052f46460 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
@@ -65,6 +65,8 @@
65 SRI(OTG_NOM_VERT_POSITION, OTG, inst),\ 65 SRI(OTG_NOM_VERT_POSITION, OTG, inst),\
66 SRI(OTG_BLACK_COLOR, OTG, inst),\ 66 SRI(OTG_BLACK_COLOR, OTG, inst),\
67 SRI(OTG_CLOCK_CONTROL, OTG, inst),\ 67 SRI(OTG_CLOCK_CONTROL, OTG, inst),\
68 SRI(OTG_VERTICAL_INTERRUPT0_CONTROL, OTG, inst),\
69 SRI(OTG_VERTICAL_INTERRUPT0_POSITION, OTG, inst),\
68 SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\ 70 SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
69 SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\ 71 SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
70 SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\ 72 SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
@@ -124,6 +126,8 @@ struct dcn_optc_registers {
124 uint32_t OTG_TEST_PATTERN_CONTROL; 126 uint32_t OTG_TEST_PATTERN_CONTROL;
125 uint32_t OTG_TEST_PATTERN_COLOR; 127 uint32_t OTG_TEST_PATTERN_COLOR;
126 uint32_t OTG_CLOCK_CONTROL; 128 uint32_t OTG_CLOCK_CONTROL;
129 uint32_t OTG_VERTICAL_INTERRUPT0_CONTROL;
130 uint32_t OTG_VERTICAL_INTERRUPT0_POSITION;
127 uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL; 131 uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL;
128 uint32_t OTG_VERTICAL_INTERRUPT2_POSITION; 132 uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
129 uint32_t OPTC_INPUT_CLOCK_CONTROL; 133 uint32_t OPTC_INPUT_CLOCK_CONTROL;
@@ -206,6 +210,9 @@ struct dcn_optc_registers {
206 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\ 210 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\
207 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\ 211 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\
208 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\ 212 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\
213 SF(OTG0_OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE, mask_sh),\
214 SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_START, mask_sh),\
215 SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_END, mask_sh),\
209 SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\ 216 SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\
210 SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\ 217 SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\
211 SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\ 218 SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\
@@ -323,6 +330,9 @@ struct dcn_optc_registers {
323 type OTG_CLOCK_EN;\ 330 type OTG_CLOCK_EN;\
324 type OTG_CLOCK_ON;\ 331 type OTG_CLOCK_ON;\
325 type OTG_CLOCK_GATE_DIS;\ 332 type OTG_CLOCK_GATE_DIS;\
333 type OTG_VERTICAL_INTERRUPT0_INT_ENABLE;\
334 type OTG_VERTICAL_INTERRUPT0_LINE_START;\
335 type OTG_VERTICAL_INTERRUPT0_LINE_END;\
326 type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\ 336 type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\
327 type OTG_VERTICAL_INTERRUPT2_LINE_START;\ 337 type OTG_VERTICAL_INTERRUPT2_LINE_START;\
328 type OPTC_INPUT_CLK_EN;\ 338 type OPTC_INPUT_CLK_EN;\
@@ -396,6 +406,8 @@ struct dcn_otg_state {
396 uint32_t v_total; 406 uint32_t v_total;
397 uint32_t v_total_max; 407 uint32_t v_total_max;
398 uint32_t v_total_min; 408 uint32_t v_total_min;
409 uint32_t v_total_min_sel;
410 uint32_t v_total_max_sel;
399 uint32_t v_sync_a_start; 411 uint32_t v_sync_a_start;
400 uint32_t v_sync_a_end; 412 uint32_t v_sync_a_end;
401 uint32_t h_blank_start; 413 uint32_t h_blank_start;
@@ -420,6 +432,10 @@ void optc1_program_timing(
420 const struct dc_crtc_timing *dc_crtc_timing, 432 const struct dc_crtc_timing *dc_crtc_timing,
421 bool use_vbios); 433 bool use_vbios);
422 434
435void optc1_program_vline_interrupt(struct timing_generator *optc,
436 const struct dc_crtc_timing *dc_crtc_timing,
437 unsigned long long vsync_delta);
438
423void optc1_program_global_sync( 439void optc1_program_global_sync(
424 struct timing_generator *optc); 440 struct timing_generator *optc);
425 441
@@ -481,4 +497,14 @@ void optc1_program_stereo(struct timing_generator *optc,
481 497
482bool optc1_is_stereo_left_eye(struct timing_generator *optc); 498bool optc1_is_stereo_left_eye(struct timing_generator *optc);
483 499
500void optc1_clear_optc_underflow(struct timing_generator *optc);
501
502void optc1_tg_init(struct timing_generator *optc);
503
504bool optc1_is_tg_enabled(struct timing_generator *optc);
505
506bool optc1_is_optc_underflow_occurred(struct timing_generator *optc);
507
508void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable);
509
484#endif /* __DC_TIMING_GENERATOR_DCN10_H__ */ 510#endif /* __DC_TIMING_GENERATOR_DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 02bd664aed3e..df5cb2d1d164 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -38,8 +38,8 @@
38#include "dcn10/dcn10_hw_sequencer.h" 38#include "dcn10/dcn10_hw_sequencer.h"
39#include "dce110/dce110_hw_sequencer.h" 39#include "dce110/dce110_hw_sequencer.h"
40#include "dcn10/dcn10_opp.h" 40#include "dcn10/dcn10_opp.h"
41#include "dce/dce_link_encoder.h" 41#include "dcn10/dcn10_link_encoder.h"
42#include "dce/dce_stream_encoder.h" 42#include "dcn10/dcn10_stream_encoder.h"
43#include "dce/dce_clocks.h" 43#include "dce/dce_clocks.h"
44#include "dce/dce_clock_source.h" 44#include "dce/dce_clock_source.h"
45#include "dce/dce_audio.h" 45#include "dce/dce_audio.h"
@@ -166,36 +166,22 @@ static const struct dce_abm_mask abm_mask = {
166 166
167#define stream_enc_regs(id)\ 167#define stream_enc_regs(id)\
168[id] = {\ 168[id] = {\
169 SE_DCN_REG_LIST(id),\ 169 SE_DCN_REG_LIST(id)\
170 .TMDS_CNTL = 0,\
171 .AFMT_AVI_INFO0 = 0,\
172 .AFMT_AVI_INFO1 = 0,\
173 .AFMT_AVI_INFO2 = 0,\
174 .AFMT_AVI_INFO3 = 0,\
175} 170}
176 171
177static const struct dce110_stream_enc_registers stream_enc_regs[] = { 172static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
178 stream_enc_regs(0), 173 stream_enc_regs(0),
179 stream_enc_regs(1), 174 stream_enc_regs(1),
180 stream_enc_regs(2), 175 stream_enc_regs(2),
181 stream_enc_regs(3), 176 stream_enc_regs(3),
182}; 177};
183 178
184static const struct dce_stream_encoder_shift se_shift = { 179static const struct dcn10_stream_encoder_shift se_shift = {
185 SE_COMMON_MASK_SH_LIST_DCN10(__SHIFT) 180 SE_COMMON_MASK_SH_LIST_DCN10(__SHIFT)
186}; 181};
187 182
188static const struct dce_stream_encoder_mask se_mask = { 183static const struct dcn10_stream_encoder_mask se_mask = {
189 SE_COMMON_MASK_SH_LIST_DCN10(_MASK), 184 SE_COMMON_MASK_SH_LIST_DCN10(_MASK)
190 .AFMT_GENERIC0_UPDATE = 0,
191 .AFMT_GENERIC2_UPDATE = 0,
192 .DP_DYN_RANGE = 0,
193 .DP_YCBCR_RANGE = 0,
194 .HDMI_AVI_INFO_SEND = 0,
195 .HDMI_AVI_INFO_CONT = 0,
196 .HDMI_AVI_INFO_LINE = 0,
197 .DP_SEC_AVI_ENABLE = 0,
198 .AFMT_AVI_INFO_VERSION = 0
199}; 185};
200 186
201#define audio_regs(id)\ 187#define audio_regs(id)\
@@ -228,13 +214,11 @@ static const struct dce_aduio_mask audio_mask = {
228 AUX_REG_LIST(id)\ 214 AUX_REG_LIST(id)\
229} 215}
230 216
231static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = { 217static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
232 aux_regs(0), 218 aux_regs(0),
233 aux_regs(1), 219 aux_regs(1),
234 aux_regs(2), 220 aux_regs(2),
235 aux_regs(3), 221 aux_regs(3)
236 aux_regs(4),
237 aux_regs(5)
238}; 222};
239 223
240#define hpd_regs(id)\ 224#define hpd_regs(id)\
@@ -242,13 +226,11 @@ static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
242 HPD_REG_LIST(id)\ 226 HPD_REG_LIST(id)\
243} 227}
244 228
245static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = { 229static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
246 hpd_regs(0), 230 hpd_regs(0),
247 hpd_regs(1), 231 hpd_regs(1),
248 hpd_regs(2), 232 hpd_regs(2),
249 hpd_regs(3), 233 hpd_regs(3)
250 hpd_regs(4),
251 hpd_regs(5)
252}; 234};
253 235
254#define link_regs(id)\ 236#define link_regs(id)\
@@ -257,14 +239,19 @@ static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
257 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \ 239 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
258} 240}
259 241
260static const struct dce110_link_enc_registers link_enc_regs[] = { 242static const struct dcn10_link_enc_registers link_enc_regs[] = {
261 link_regs(0), 243 link_regs(0),
262 link_regs(1), 244 link_regs(1),
263 link_regs(2), 245 link_regs(2),
264 link_regs(3), 246 link_regs(3)
265 link_regs(4), 247};
266 link_regs(5), 248
267 link_regs(6), 249static const struct dcn10_link_enc_shift le_shift = {
250 LINK_ENCODER_MASK_SH_LIST_DCN10(__SHIFT)
251};
252
253static const struct dcn10_link_enc_mask le_mask = {
254 LINK_ENCODER_MASK_SH_LIST_DCN10(_MASK)
268}; 255};
269 256
270#define ipp_regs(id)\ 257#define ipp_regs(id)\
@@ -320,11 +307,14 @@ static const struct dcn_dpp_registers tf_regs[] = {
320}; 307};
321 308
322static const struct dcn_dpp_shift tf_shift = { 309static const struct dcn_dpp_shift tf_shift = {
323 TF_REG_LIST_SH_MASK_DCN10(__SHIFT) 310 TF_REG_LIST_SH_MASK_DCN10(__SHIFT),
311 TF_DEBUG_REG_LIST_SH_DCN10
312
324}; 313};
325 314
326static const struct dcn_dpp_mask tf_mask = { 315static const struct dcn_dpp_mask tf_mask = {
327 TF_REG_LIST_SH_MASK_DCN10(_MASK), 316 TF_REG_LIST_SH_MASK_DCN10(_MASK),
317 TF_DEBUG_REG_LIST_MASK_DCN10
328}; 318};
329 319
330static const struct dcn_mpc_registers mpc_regs = { 320static const struct dcn_mpc_registers mpc_regs = {
@@ -457,6 +447,8 @@ static const struct dc_debug debug_defaults_drv = {
457 .vsr_support = true, 447 .vsr_support = true,
458 .performance_trace = false, 448 .performance_trace = false,
459 .az_endpoint_mute_only = true, 449 .az_endpoint_mute_only = true,
450 .recovery_enabled = false, /*enable this by default after testing.*/
451 .max_downscale_src_width = 3840,
460}; 452};
461 453
462static const struct dc_debug debug_defaults_diags = { 454static const struct dc_debug debug_defaults_diags = {
@@ -592,20 +584,22 @@ static const struct encoder_feature_support link_enc_feature = {
592struct link_encoder *dcn10_link_encoder_create( 584struct link_encoder *dcn10_link_encoder_create(
593 const struct encoder_init_data *enc_init_data) 585 const struct encoder_init_data *enc_init_data)
594{ 586{
595 struct dce110_link_encoder *enc110 = 587 struct dcn10_link_encoder *enc10 =
596 kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); 588 kzalloc(sizeof(struct dcn10_link_encoder), GFP_KERNEL);
597 589
598 if (!enc110) 590 if (!enc10)
599 return NULL; 591 return NULL;
600 592
601 dce110_link_encoder_construct(enc110, 593 dcn10_link_encoder_construct(enc10,
602 enc_init_data, 594 enc_init_data,
603 &link_enc_feature, 595 &link_enc_feature,
604 &link_enc_regs[enc_init_data->transmitter], 596 &link_enc_regs[enc_init_data->transmitter],
605 &link_enc_aux_regs[enc_init_data->channel - 1], 597 &link_enc_aux_regs[enc_init_data->channel - 1],
606 &link_enc_hpd_regs[enc_init_data->hpd_source]); 598 &link_enc_hpd_regs[enc_init_data->hpd_source],
599 &le_shift,
600 &le_mask);
607 601
608 return &enc110->base; 602 return &enc10->base;
609} 603}
610 604
611struct clock_source *dcn10_clock_source_create( 605struct clock_source *dcn10_clock_source_create(
@@ -650,16 +644,16 @@ static struct stream_encoder *dcn10_stream_encoder_create(
650 enum engine_id eng_id, 644 enum engine_id eng_id,
651 struct dc_context *ctx) 645 struct dc_context *ctx)
652{ 646{
653 struct dce110_stream_encoder *enc110 = 647 struct dcn10_stream_encoder *enc1 =
654 kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); 648 kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
655 649
656 if (!enc110) 650 if (!enc1)
657 return NULL; 651 return NULL;
658 652
659 dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, 653 dcn10_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id,
660 &stream_enc_regs[eng_id], 654 &stream_enc_regs[eng_id],
661 &se_shift, &se_mask); 655 &se_shift, &se_mask);
662 return &enc110->base; 656 return &enc1->base;
663} 657}
664 658
665static const struct dce_hwseq_registers hwseq_reg = { 659static const struct dce_hwseq_registers hwseq_reg = {
@@ -918,36 +912,6 @@ enum dc_status dcn10_add_stream_to_ctx(
918 return result; 912 return result;
919} 913}
920 914
921enum dc_status dcn10_validate_guaranteed(
922 struct dc *dc,
923 struct dc_stream_state *dc_stream,
924 struct dc_state *context)
925{
926 enum dc_status result = DC_ERROR_UNEXPECTED;
927
928 context->streams[0] = dc_stream;
929 dc_stream_retain(context->streams[0]);
930 context->stream_count++;
931
932 result = resource_map_pool_resources(dc, context, dc_stream);
933
934 if (result == DC_OK)
935 result = resource_map_phy_clock_resources(dc, context, dc_stream);
936
937 if (result == DC_OK)
938 result = build_mapped_resource(dc, context, dc_stream);
939
940 if (result == DC_OK) {
941 validate_guaranteed_copy_streams(
942 context, dc->caps.max_streams);
943 result = resource_build_scaling_params_for_context(dc, context);
944 }
945 if (result == DC_OK && !dcn_validate_bandwidth(dc, context))
946 return DC_FAIL_BANDWIDTH_VALIDATE;
947
948 return result;
949}
950
951static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer( 915static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
952 struct dc_state *context, 916 struct dc_state *context,
953 const struct resource_pool *pool, 917 const struct resource_pool *pool,
@@ -978,235 +942,16 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
978 return idle_pipe; 942 return idle_pipe;
979} 943}
980 944
981enum dcc_control { 945static bool dcn10_get_dcc_compression_cap(const struct dc *dc,
982 dcc_control__256_256_xxx,
983 dcc_control__128_128_xxx,
984 dcc_control__256_64_64,
985};
986
987enum segment_order {
988 segment_order__na,
989 segment_order__contiguous,
990 segment_order__non_contiguous,
991};
992
993static bool dcc_support_pixel_format(
994 enum surface_pixel_format format,
995 unsigned int *bytes_per_element)
996{
997 /* DML: get_bytes_per_element */
998 switch (format) {
999 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
1000 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
1001 *bytes_per_element = 2;
1002 return true;
1003 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
1004 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
1005 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
1006 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
1007 *bytes_per_element = 4;
1008 return true;
1009 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
1010 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
1011 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
1012 *bytes_per_element = 8;
1013 return true;
1014 default:
1015 return false;
1016 }
1017}
1018
1019static bool dcc_support_swizzle(
1020 enum swizzle_mode_values swizzle,
1021 unsigned int bytes_per_element,
1022 enum segment_order *segment_order_horz,
1023 enum segment_order *segment_order_vert)
1024{
1025 bool standard_swizzle = false;
1026 bool display_swizzle = false;
1027
1028 switch (swizzle) {
1029 case DC_SW_4KB_S:
1030 case DC_SW_64KB_S:
1031 case DC_SW_VAR_S:
1032 case DC_SW_4KB_S_X:
1033 case DC_SW_64KB_S_X:
1034 case DC_SW_VAR_S_X:
1035 standard_swizzle = true;
1036 break;
1037 case DC_SW_4KB_D:
1038 case DC_SW_64KB_D:
1039 case DC_SW_VAR_D:
1040 case DC_SW_4KB_D_X:
1041 case DC_SW_64KB_D_X:
1042 case DC_SW_VAR_D_X:
1043 display_swizzle = true;
1044 break;
1045 default:
1046 break;
1047 }
1048
1049 if (bytes_per_element == 1 && standard_swizzle) {
1050 *segment_order_horz = segment_order__contiguous;
1051 *segment_order_vert = segment_order__na;
1052 return true;
1053 }
1054 if (bytes_per_element == 2 && standard_swizzle) {
1055 *segment_order_horz = segment_order__non_contiguous;
1056 *segment_order_vert = segment_order__contiguous;
1057 return true;
1058 }
1059 if (bytes_per_element == 4 && standard_swizzle) {
1060 *segment_order_horz = segment_order__non_contiguous;
1061 *segment_order_vert = segment_order__contiguous;
1062 return true;
1063 }
1064 if (bytes_per_element == 8 && standard_swizzle) {
1065 *segment_order_horz = segment_order__na;
1066 *segment_order_vert = segment_order__contiguous;
1067 return true;
1068 }
1069 if (bytes_per_element == 8 && display_swizzle) {
1070 *segment_order_horz = segment_order__contiguous;
1071 *segment_order_vert = segment_order__non_contiguous;
1072 return true;
1073 }
1074
1075 return false;
1076}
1077
1078static void get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height,
1079 unsigned int bytes_per_element)
1080{
1081 /* copied from DML. might want to refactor DML to leverage from DML */
1082 /* DML : get_blk256_size */
1083 if (bytes_per_element == 1) {
1084 *blk256_width = 16;
1085 *blk256_height = 16;
1086 } else if (bytes_per_element == 2) {
1087 *blk256_width = 16;
1088 *blk256_height = 8;
1089 } else if (bytes_per_element == 4) {
1090 *blk256_width = 8;
1091 *blk256_height = 8;
1092 } else if (bytes_per_element == 8) {
1093 *blk256_width = 8;
1094 *blk256_height = 4;
1095 }
1096}
1097
1098static void det_request_size(
1099 unsigned int height,
1100 unsigned int width,
1101 unsigned int bpe,
1102 bool *req128_horz_wc,
1103 bool *req128_vert_wc)
1104{
1105 unsigned int detile_buf_size = 164 * 1024; /* 164KB for DCN1.0 */
1106
1107 unsigned int blk256_height = 0;
1108 unsigned int blk256_width = 0;
1109 unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc;
1110
1111 get_blk256_size(&blk256_width, &blk256_height, bpe);
1112
1113 swath_bytes_horz_wc = height * blk256_height * bpe;
1114 swath_bytes_vert_wc = width * blk256_width * bpe;
1115
1116 *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ?
1117 false : /* full 256B request */
1118 true; /* half 128b request */
1119
1120 *req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ?
1121 false : /* full 256B request */
1122 true; /* half 128b request */
1123}
1124
1125static bool get_dcc_compression_cap(const struct dc *dc,
1126 const struct dc_dcc_surface_param *input, 946 const struct dc_dcc_surface_param *input,
1127 struct dc_surface_dcc_cap *output) 947 struct dc_surface_dcc_cap *output)
1128{ 948{
1129 /* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */ 949 return dc->res_pool->hubbub->funcs->get_dcc_compression_cap(
1130 enum dcc_control dcc_control; 950 dc->res_pool->hubbub,
1131 unsigned int bpe; 951 input,
1132 enum segment_order segment_order_horz, segment_order_vert; 952 output);
1133 bool req128_horz_wc, req128_vert_wc;
1134
1135 memset(output, 0, sizeof(*output));
1136
1137 if (dc->debug.disable_dcc == DCC_DISABLE)
1138 return false;
1139
1140 if (!dcc_support_pixel_format(input->format,
1141 &bpe))
1142 return false;
1143
1144 if (!dcc_support_swizzle(input->swizzle_mode, bpe,
1145 &segment_order_horz, &segment_order_vert))
1146 return false;
1147
1148 det_request_size(input->surface_size.height, input->surface_size.width,
1149 bpe, &req128_horz_wc, &req128_vert_wc);
1150
1151 if (!req128_horz_wc && !req128_vert_wc) {
1152 dcc_control = dcc_control__256_256_xxx;
1153 } else if (input->scan == SCAN_DIRECTION_HORIZONTAL) {
1154 if (!req128_horz_wc)
1155 dcc_control = dcc_control__256_256_xxx;
1156 else if (segment_order_horz == segment_order__contiguous)
1157 dcc_control = dcc_control__128_128_xxx;
1158 else
1159 dcc_control = dcc_control__256_64_64;
1160 } else if (input->scan == SCAN_DIRECTION_VERTICAL) {
1161 if (!req128_vert_wc)
1162 dcc_control = dcc_control__256_256_xxx;
1163 else if (segment_order_vert == segment_order__contiguous)
1164 dcc_control = dcc_control__128_128_xxx;
1165 else
1166 dcc_control = dcc_control__256_64_64;
1167 } else {
1168 if ((req128_horz_wc &&
1169 segment_order_horz == segment_order__non_contiguous) ||
1170 (req128_vert_wc &&
1171 segment_order_vert == segment_order__non_contiguous))
1172 /* access_dir not known, must use most constraining */
1173 dcc_control = dcc_control__256_64_64;
1174 else
1175 /* reg128 is true for either horz and vert
1176 * but segment_order is contiguous
1177 */
1178 dcc_control = dcc_control__128_128_xxx;
1179 }
1180
1181 if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
1182 dcc_control != dcc_control__256_256_xxx)
1183 return false;
1184
1185 switch (dcc_control) {
1186 case dcc_control__256_256_xxx:
1187 output->grph.rgb.max_uncompressed_blk_size = 256;
1188 output->grph.rgb.max_compressed_blk_size = 256;
1189 output->grph.rgb.independent_64b_blks = false;
1190 break;
1191 case dcc_control__128_128_xxx:
1192 output->grph.rgb.max_uncompressed_blk_size = 128;
1193 output->grph.rgb.max_compressed_blk_size = 128;
1194 output->grph.rgb.independent_64b_blks = false;
1195 break;
1196 case dcc_control__256_64_64:
1197 output->grph.rgb.max_uncompressed_blk_size = 256;
1198 output->grph.rgb.max_compressed_blk_size = 64;
1199 output->grph.rgb.independent_64b_blks = true;
1200 break;
1201 }
1202
1203 output->capable = true;
1204 output->const_color_support = false;
1205
1206 return true;
1207} 953}
1208 954
1209
1210static void dcn10_destroy_resource_pool(struct resource_pool **pool) 955static void dcn10_destroy_resource_pool(struct resource_pool **pool)
1211{ 956{
1212 struct dcn10_resource_pool *dcn10_pool = TO_DCN10_RES_POOL(*pool); 957 struct dcn10_resource_pool *dcn10_pool = TO_DCN10_RES_POOL(*pool);
@@ -1227,13 +972,12 @@ static enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_st
1227} 972}
1228 973
1229static struct dc_cap_funcs cap_funcs = { 974static struct dc_cap_funcs cap_funcs = {
1230 .get_dcc_compression_cap = get_dcc_compression_cap 975 .get_dcc_compression_cap = dcn10_get_dcc_compression_cap
1231}; 976};
1232 977
1233static struct resource_funcs dcn10_res_pool_funcs = { 978static struct resource_funcs dcn10_res_pool_funcs = {
1234 .destroy = dcn10_destroy_resource_pool, 979 .destroy = dcn10_destroy_resource_pool,
1235 .link_enc_create = dcn10_link_encoder_create, 980 .link_enc_create = dcn10_link_encoder_create,
1236 .validate_guaranteed = dcn10_validate_guaranteed,
1237 .validate_bandwidth = dcn_validate_bandwidth, 981 .validate_bandwidth = dcn_validate_bandwidth,
1238 .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer, 982 .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
1239 .validate_plane = dcn10_validate_plane, 983 .validate_plane = dcn10_validate_plane,
@@ -1282,6 +1026,7 @@ static bool construct(
1282 dc->caps.max_cursor_size = 256; 1026 dc->caps.max_cursor_size = 256;
1283 dc->caps.max_slave_planes = 1; 1027 dc->caps.max_slave_planes = 1;
1284 dc->caps.is_apu = true; 1028 dc->caps.is_apu = true;
1029 dc->caps.post_blend_color_processing = false;
1285 1030
1286 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) 1031 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
1287 dc->debug = debug_defaults_drv; 1032 dc->debug = debug_defaults_drv;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
new file mode 100644
index 000000000000..653b7b2efe2e
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
@@ -0,0 +1,1490 @@
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26
27#include "dc_bios_types.h"
28#include "dcn10_stream_encoder.h"
29#include "reg_helper.h"
30#include "hw_shared.h"
31
32#define DC_LOGGER \
33 enc1->base.ctx->logger
34
35
36#define REG(reg)\
37 (enc1->regs->reg)
38
39#undef FN
40#define FN(reg_name, field_name) \
41 enc1->se_shift->field_name, enc1->se_mask->field_name
42
43#define VBI_LINE_0 0
44#define DP_BLANK_MAX_RETRY 20
45#define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000
46
47
48enum {
49 DP_MST_UPDATE_MAX_RETRY = 50
50};
51
52#define CTX \
53 enc1->base.ctx
54
55void enc1_update_generic_info_packet(
56 struct dcn10_stream_encoder *enc1,
57 uint32_t packet_index,
58 const struct dc_info_packet *info_packet)
59{
60 uint32_t regval;
61 /* TODOFPGA Figure out a proper number for max_retries polling for lock
62 * use 50 for now.
63 */
64 uint32_t max_retries = 50;
65
66 /*we need turn on clock before programming AFMT block*/
67 REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);
68
69 if (packet_index >= 8)
70 ASSERT(0);
71
72 /* poll dig_update_lock is not locked -> asic internal signal
73 * assume otg master lock will unlock it
74 */
75/* REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS,
76 0, 10, max_retries);*/
77
78 /* check if HW reading GSP memory */
79 REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT,
80 0, 10, max_retries);
81
82 /* HW does is not reading GSP memory not reading too long ->
83 * something wrong. clear GPS memory access and notify?
84 * hw SW is writing to GSP memory
85 */
86 REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, 1);
87
88 /* choose which generic packet to use */
89 regval = REG_READ(AFMT_VBI_PACKET_CONTROL);
90 REG_UPDATE(AFMT_VBI_PACKET_CONTROL,
91 AFMT_GENERIC_INDEX, packet_index);
92
93 /* write generic packet header
94 * (4th byte is for GENERIC0 only)
95 */
96 REG_SET_4(AFMT_GENERIC_HDR, 0,
97 AFMT_GENERIC_HB0, info_packet->hb0,
98 AFMT_GENERIC_HB1, info_packet->hb1,
99 AFMT_GENERIC_HB2, info_packet->hb2,
100 AFMT_GENERIC_HB3, info_packet->hb3);
101
102 /* write generic packet contents
103 * (we never use last 4 bytes)
104 * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers
105 */
106 {
107 const uint32_t *content =
108 (const uint32_t *) &info_packet->sb[0];
109
110 REG_WRITE(AFMT_GENERIC_0, *content++);
111 REG_WRITE(AFMT_GENERIC_1, *content++);
112 REG_WRITE(AFMT_GENERIC_2, *content++);
113 REG_WRITE(AFMT_GENERIC_3, *content++);
114 REG_WRITE(AFMT_GENERIC_4, *content++);
115 REG_WRITE(AFMT_GENERIC_5, *content++);
116 REG_WRITE(AFMT_GENERIC_6, *content++);
117 REG_WRITE(AFMT_GENERIC_7, *content);
118 }
119
120 switch (packet_index) {
121 case 0:
122 REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
123 AFMT_GENERIC0_FRAME_UPDATE, 1);
124 break;
125 case 1:
126 REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
127 AFMT_GENERIC1_FRAME_UPDATE, 1);
128 break;
129 case 2:
130 REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
131 AFMT_GENERIC2_FRAME_UPDATE, 1);
132 break;
133 case 3:
134 REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
135 AFMT_GENERIC3_FRAME_UPDATE, 1);
136 break;
137 case 4:
138 REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
139 AFMT_GENERIC4_FRAME_UPDATE, 1);
140 break;
141 case 5:
142 REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
143 AFMT_GENERIC5_FRAME_UPDATE, 1);
144 break;
145 case 6:
146 REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
147 AFMT_GENERIC6_FRAME_UPDATE, 1);
148 break;
149 case 7:
150 REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
151 AFMT_GENERIC7_FRAME_UPDATE, 1);
152 break;
153 default:
154 break;
155 }
156}
157
158static void enc1_update_hdmi_info_packet(
159 struct dcn10_stream_encoder *enc1,
160 uint32_t packet_index,
161 const struct dc_info_packet *info_packet)
162{
163 uint32_t cont, send, line;
164
165 if (info_packet->valid) {
166 enc1_update_generic_info_packet(
167 enc1,
168 packet_index,
169 info_packet);
170
171 /* enable transmission of packet(s) -
172 * packet transmission begins on the next frame
173 */
174 cont = 1;
175 /* send packet(s) every frame */
176 send = 1;
177 /* select line number to send packets on */
178 line = 2;
179 } else {
180 cont = 0;
181 send = 0;
182 line = 0;
183 }
184
185 /* choose which generic packet control to use */
186 switch (packet_index) {
187 case 0:
188 REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0,
189 HDMI_GENERIC0_CONT, cont,
190 HDMI_GENERIC0_SEND, send,
191 HDMI_GENERIC0_LINE, line);
192 break;
193 case 1:
194 REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0,
195 HDMI_GENERIC1_CONT, cont,
196 HDMI_GENERIC1_SEND, send,
197 HDMI_GENERIC1_LINE, line);
198 break;
199 case 2:
200 REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1,
201 HDMI_GENERIC0_CONT, cont,
202 HDMI_GENERIC0_SEND, send,
203 HDMI_GENERIC0_LINE, line);
204 break;
205 case 3:
206 REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1,
207 HDMI_GENERIC1_CONT, cont,
208 HDMI_GENERIC1_SEND, send,
209 HDMI_GENERIC1_LINE, line);
210 break;
211 case 4:
212 REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2,
213 HDMI_GENERIC0_CONT, cont,
214 HDMI_GENERIC0_SEND, send,
215 HDMI_GENERIC0_LINE, line);
216 break;
217 case 5:
218 REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2,
219 HDMI_GENERIC1_CONT, cont,
220 HDMI_GENERIC1_SEND, send,
221 HDMI_GENERIC1_LINE, line);
222 break;
223 case 6:
224 REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3,
225 HDMI_GENERIC0_CONT, cont,
226 HDMI_GENERIC0_SEND, send,
227 HDMI_GENERIC0_LINE, line);
228 break;
229 case 7:
230 REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3,
231 HDMI_GENERIC1_CONT, cont,
232 HDMI_GENERIC1_SEND, send,
233 HDMI_GENERIC1_LINE, line);
234 break;
235 default:
236 /* invalid HW packet index */
237 DC_LOG_WARNING(
238 "Invalid HW packet index: %s()\n",
239 __func__);
240 return;
241 }
242}
243
244/* setup stream encoder in dp mode */
245void enc1_stream_encoder_dp_set_stream_attribute(
246 struct stream_encoder *enc,
247 struct dc_crtc_timing *crtc_timing,
248 enum dc_color_space output_color_space)
249{
250 uint32_t h_active_start;
251 uint32_t v_active_start;
252 uint32_t misc0 = 0;
253 uint32_t misc1 = 0;
254 uint32_t h_blank;
255 uint32_t h_back_porch;
256 uint8_t synchronous_clock = 0; /* asynchronous mode */
257 uint8_t colorimetry_bpc;
258 uint8_t dynamic_range_rgb = 0; /*full range*/
259 uint8_t dynamic_range_ycbcr = 1; /*bt709*/
260
261 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
262
263 REG_UPDATE(DP_DB_CNTL, DP_DB_DISABLE, 1);
264
265 /* set pixel encoding */
266 switch (crtc_timing->pixel_encoding) {
267 case PIXEL_ENCODING_YCBCR422:
268 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
269 DP_PIXEL_ENCODING_TYPE_YCBCR422);
270 break;
271 case PIXEL_ENCODING_YCBCR444:
272 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
273 DP_PIXEL_ENCODING_TYPE_YCBCR444);
274
275 if (crtc_timing->flags.Y_ONLY)
276 if (crtc_timing->display_color_depth != COLOR_DEPTH_666)
277 /* HW testing only, no use case yet.
278 * Color depth of Y-only could be
279 * 8, 10, 12, 16 bits
280 */
281 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
282 DP_PIXEL_ENCODING_TYPE_Y_ONLY);
283 /* Note: DP_MSA_MISC1 bit 7 is the indicator
284 * of Y-only mode.
285 * This bit is set in HW if register
286 * DP_PIXEL_ENCODING is programmed to 0x4
287 */
288 break;
289 case PIXEL_ENCODING_YCBCR420:
290 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
291 DP_PIXEL_ENCODING_TYPE_YCBCR420);
292 REG_UPDATE(DP_VID_TIMING, DP_VID_N_MUL, 1);
293 break;
294 default:
295 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,
296 DP_PIXEL_ENCODING_TYPE_RGB444);
297 break;
298 }
299
300 misc1 = REG_READ(DP_MSA_MISC);
301
302 /* set color depth */
303
304 switch (crtc_timing->display_color_depth) {
305 case COLOR_DEPTH_666:
306 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,
307 0);
308 break;
309 case COLOR_DEPTH_888:
310 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,
311 DP_COMPONENT_PIXEL_DEPTH_8BPC);
312 break;
313 case COLOR_DEPTH_101010:
314 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,
315 DP_COMPONENT_PIXEL_DEPTH_10BPC);
316
317 break;
318 case COLOR_DEPTH_121212:
319 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,
320 DP_COMPONENT_PIXEL_DEPTH_12BPC);
321 break;
322 default:
323 REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,
324 DP_COMPONENT_PIXEL_DEPTH_6BPC);
325 break;
326 }
327
328 /* set dynamic range and YCbCr range */
329
330 switch (crtc_timing->display_color_depth) {
331 case COLOR_DEPTH_666:
332 colorimetry_bpc = 0;
333 break;
334 case COLOR_DEPTH_888:
335 colorimetry_bpc = 1;
336 break;
337 case COLOR_DEPTH_101010:
338 colorimetry_bpc = 2;
339 break;
340 case COLOR_DEPTH_121212:
341 colorimetry_bpc = 3;
342 break;
343 default:
344 colorimetry_bpc = 0;
345 break;
346 }
347
348 misc0 = misc0 | synchronous_clock;
349 misc0 = colorimetry_bpc << 5;
350
351 switch (output_color_space) {
352 case COLOR_SPACE_SRGB:
353 misc0 = misc0 | 0x0;
354 misc1 = misc1 & ~0x80; /* bit7 = 0*/
355 dynamic_range_rgb = 0; /*full range*/
356 break;
357 case COLOR_SPACE_SRGB_LIMITED:
358 misc0 = misc0 | 0x8; /* bit3=1 */
359 misc1 = misc1 & ~0x80; /* bit7 = 0*/
360 dynamic_range_rgb = 1; /*limited range*/
361 break;
362 case COLOR_SPACE_YCBCR601:
363 case COLOR_SPACE_YCBCR601_LIMITED:
364 misc0 = misc0 | 0x8; /* bit3=1, bit4=0 */
365 misc1 = misc1 & ~0x80; /* bit7 = 0*/
366 dynamic_range_ycbcr = 0; /*bt601*/
367 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
368 misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */
369 else if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR444)
370 misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */
371 break;
372 case COLOR_SPACE_YCBCR709:
373 case COLOR_SPACE_YCBCR709_LIMITED:
374 misc0 = misc0 | 0x18; /* bit3=1, bit4=1 */
375 misc1 = misc1 & ~0x80; /* bit7 = 0*/
376 dynamic_range_ycbcr = 1; /*bt709*/
377 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
378 misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */
379 else if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR444)
380 misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */
381 break;
382 case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
383 dynamic_range_rgb = 1; /*limited range*/
384 break;
385 case COLOR_SPACE_2020_RGB_FULLRANGE:
386 case COLOR_SPACE_2020_YCBCR:
387 case COLOR_SPACE_XR_RGB:
388 case COLOR_SPACE_MSREF_SCRGB:
389 case COLOR_SPACE_ADOBERGB:
390 case COLOR_SPACE_DCIP3:
391 case COLOR_SPACE_XV_YCC_709:
392 case COLOR_SPACE_XV_YCC_601:
393 case COLOR_SPACE_DISPLAYNATIVE:
394 case COLOR_SPACE_DOLBYVISION:
395 case COLOR_SPACE_APPCTRL:
396 case COLOR_SPACE_CUSTOMPOINTS:
397 case COLOR_SPACE_UNKNOWN:
398 /* do nothing */
399 break;
400 }
401
402 REG_SET(DP_MSA_COLORIMETRY, 0, DP_MSA_MISC0, misc0);
403 REG_WRITE(DP_MSA_MISC, misc1); /* MSA_MISC1 */
404
405 /* dcn new register
406 * dc_crtc_timing is vesa dmt struct. data from edid
407 */
408 REG_SET_2(DP_MSA_TIMING_PARAM1, 0,
409 DP_MSA_HTOTAL, crtc_timing->h_total,
410 DP_MSA_VTOTAL, crtc_timing->v_total);
411
412 /* calculate from vesa timing parameters
413 * h_active_start related to leading edge of sync
414 */
415
416 h_blank = crtc_timing->h_total - crtc_timing->h_border_left -
417 crtc_timing->h_addressable - crtc_timing->h_border_right;
418
419 h_back_porch = h_blank - crtc_timing->h_front_porch -
420 crtc_timing->h_sync_width;
421
422 /* start at beginning of left border */
423 h_active_start = crtc_timing->h_sync_width + h_back_porch;
424
425
426 v_active_start = crtc_timing->v_total - crtc_timing->v_border_top -
427 crtc_timing->v_addressable - crtc_timing->v_border_bottom -
428 crtc_timing->v_front_porch;
429
430
431 /* start at beginning of left border */
432 REG_SET_2(DP_MSA_TIMING_PARAM2, 0,
433 DP_MSA_HSTART, h_active_start,
434 DP_MSA_VSTART, v_active_start);
435
436 REG_SET_4(DP_MSA_TIMING_PARAM3, 0,
437 DP_MSA_HSYNCWIDTH,
438 crtc_timing->h_sync_width,
439 DP_MSA_HSYNCPOLARITY,
440 !crtc_timing->flags.HSYNC_POSITIVE_POLARITY,
441 DP_MSA_VSYNCWIDTH,
442 crtc_timing->v_sync_width,
443 DP_MSA_VSYNCPOLARITY,
444 !crtc_timing->flags.VSYNC_POSITIVE_POLARITY);
445
446 /* HWDITH include border or overscan */
447 REG_SET_2(DP_MSA_TIMING_PARAM4, 0,
448 DP_MSA_HWIDTH, crtc_timing->h_border_left +
449 crtc_timing->h_addressable + crtc_timing->h_border_right,
450 DP_MSA_VHEIGHT, crtc_timing->v_border_top +
451 crtc_timing->v_addressable + crtc_timing->v_border_bottom);
452}
453
454static void enc1_stream_encoder_set_stream_attribute_helper(
455 struct dcn10_stream_encoder *enc1,
456 struct dc_crtc_timing *crtc_timing)
457{
458 switch (crtc_timing->pixel_encoding) {
459 case PIXEL_ENCODING_YCBCR422:
460 REG_UPDATE(DIG_FE_CNTL, TMDS_PIXEL_ENCODING, 1);
461 break;
462 default:
463 REG_UPDATE(DIG_FE_CNTL, TMDS_PIXEL_ENCODING, 0);
464 break;
465 }
466 REG_UPDATE(DIG_FE_CNTL, TMDS_COLOR_FORMAT, 0);
467}
468
469/* setup stream encoder in hdmi mode */
470void enc1_stream_encoder_hdmi_set_stream_attribute(
471 struct stream_encoder *enc,
472 struct dc_crtc_timing *crtc_timing,
473 int actual_pix_clk_khz,
474 bool enable_audio)
475{
476 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
477 struct bp_encoder_control cntl = {0};
478
479 cntl.action = ENCODER_CONTROL_SETUP;
480 cntl.engine_id = enc1->base.id;
481 cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
482 cntl.enable_dp_audio = enable_audio;
483 cntl.pixel_clock = actual_pix_clk_khz;
484 cntl.lanes_number = LANE_COUNT_FOUR;
485
486 if (enc1->base.bp->funcs->encoder_control(
487 enc1->base.bp, &cntl) != BP_RESULT_OK)
488 return;
489
490 enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
491
492 /* setup HDMI engine */
493 REG_UPDATE_5(HDMI_CONTROL,
494 HDMI_PACKET_GEN_VERSION, 1,
495 HDMI_KEEPOUT_MODE, 1,
496 HDMI_DEEP_COLOR_ENABLE, 0,
497 HDMI_DATA_SCRAMBLE_EN, 0,
498 HDMI_CLOCK_CHANNEL_RATE, 0);
499
500
501 switch (crtc_timing->display_color_depth) {
502 case COLOR_DEPTH_888:
503 REG_UPDATE(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, 0);
504 break;
505 case COLOR_DEPTH_101010:
506 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
507 REG_UPDATE_2(HDMI_CONTROL,
508 HDMI_DEEP_COLOR_DEPTH, 1,
509 HDMI_DEEP_COLOR_ENABLE, 0);
510 } else {
511 REG_UPDATE_2(HDMI_CONTROL,
512 HDMI_DEEP_COLOR_DEPTH, 1,
513 HDMI_DEEP_COLOR_ENABLE, 1);
514 }
515 break;
516 case COLOR_DEPTH_121212:
517 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
518 REG_UPDATE_2(HDMI_CONTROL,
519 HDMI_DEEP_COLOR_DEPTH, 2,
520 HDMI_DEEP_COLOR_ENABLE, 0);
521 } else {
522 REG_UPDATE_2(HDMI_CONTROL,
523 HDMI_DEEP_COLOR_DEPTH, 2,
524 HDMI_DEEP_COLOR_ENABLE, 1);
525 }
526 break;
527 case COLOR_DEPTH_161616:
528 REG_UPDATE_2(HDMI_CONTROL,
529 HDMI_DEEP_COLOR_DEPTH, 3,
530 HDMI_DEEP_COLOR_ENABLE, 1);
531 break;
532 default:
533 break;
534 }
535
536 if (actual_pix_clk_khz >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) {
537 /* enable HDMI data scrambler
538 * HDMI_CLOCK_CHANNEL_RATE_MORE_340M
539 * Clock channel frequency is 1/4 of character rate.
540 */
541 REG_UPDATE_2(HDMI_CONTROL,
542 HDMI_DATA_SCRAMBLE_EN, 1,
543 HDMI_CLOCK_CHANNEL_RATE, 1);
544 } else if (crtc_timing->flags.LTE_340MCSC_SCRAMBLE) {
545
546 /* TODO: New feature for DCE11, still need to implement */
547
548 /* enable HDMI data scrambler
549 * HDMI_CLOCK_CHANNEL_FREQ_EQUAL_TO_CHAR_RATE
550 * Clock channel frequency is the same
551 * as character rate
552 */
553 REG_UPDATE_2(HDMI_CONTROL,
554 HDMI_DATA_SCRAMBLE_EN, 1,
555 HDMI_CLOCK_CHANNEL_RATE, 0);
556 }
557
558
559 REG_UPDATE_3(HDMI_VBI_PACKET_CONTROL,
560 HDMI_GC_CONT, 1,
561 HDMI_GC_SEND, 1,
562 HDMI_NULL_SEND, 1);
563
564 /* following belongs to audio */
565 REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, 1);
566
567 REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
568
569 REG_UPDATE(HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE,
570 VBI_LINE_0 + 2);
571
572 REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0);
573}
574
575/* setup stream encoder in dvi mode */
576void enc1_stream_encoder_dvi_set_stream_attribute(
577 struct stream_encoder *enc,
578 struct dc_crtc_timing *crtc_timing,
579 bool is_dual_link)
580{
581 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
582 struct bp_encoder_control cntl = {0};
583
584 cntl.action = ENCODER_CONTROL_SETUP;
585 cntl.engine_id = enc1->base.id;
586 cntl.signal = is_dual_link ?
587 SIGNAL_TYPE_DVI_DUAL_LINK : SIGNAL_TYPE_DVI_SINGLE_LINK;
588 cntl.enable_dp_audio = false;
589 cntl.pixel_clock = crtc_timing->pix_clk_khz;
590 cntl.lanes_number = (is_dual_link) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR;
591
592 if (enc1->base.bp->funcs->encoder_control(
593 enc1->base.bp, &cntl) != BP_RESULT_OK)
594 return;
595
596 ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB);
597 ASSERT(crtc_timing->display_color_depth == COLOR_DEPTH_888);
598 enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
599}
600
601void enc1_stream_encoder_set_mst_bandwidth(
602 struct stream_encoder *enc,
603 struct fixed31_32 avg_time_slots_per_mtp)
604{
605 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
606 uint32_t x = dc_fixpt_floor(
607 avg_time_slots_per_mtp);
608 uint32_t y = dc_fixpt_ceil(
609 dc_fixpt_shl(
610 dc_fixpt_sub_int(
611 avg_time_slots_per_mtp,
612 x),
613 26));
614
615 REG_SET_2(DP_MSE_RATE_CNTL, 0,
616 DP_MSE_RATE_X, x,
617 DP_MSE_RATE_Y, y);
618
619 /* wait for update to be completed on the link */
620 /* i.e. DP_MSE_RATE_UPDATE_PENDING field (read only) */
621 /* is reset to 0 (not pending) */
622 REG_WAIT(DP_MSE_RATE_UPDATE, DP_MSE_RATE_UPDATE_PENDING,
623 0,
624 10, DP_MST_UPDATE_MAX_RETRY);
625}
626
627static void enc1_stream_encoder_update_hdmi_info_packets(
628 struct stream_encoder *enc,
629 const struct encoder_info_frame *info_frame)
630{
631 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
632
633 /* for bring up, disable dp double TODO */
634 REG_UPDATE(HDMI_DB_CONTROL, HDMI_DB_DISABLE, 1);
635
636 enc1_update_hdmi_info_packet(enc1, 0, &info_frame->avi);
637 enc1_update_hdmi_info_packet(enc1, 1, &info_frame->vendor);
638 enc1_update_hdmi_info_packet(enc1, 2, &info_frame->gamut);
639 enc1_update_hdmi_info_packet(enc1, 3, &info_frame->spd);
640 enc1_update_hdmi_info_packet(enc1, 4, &info_frame->hdrsmd);
641}
642
643static void enc1_stream_encoder_stop_hdmi_info_packets(
644 struct stream_encoder *enc)
645{
646 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
647
648 /* stop generic packets 0 & 1 on HDMI */
649 REG_SET_6(HDMI_GENERIC_PACKET_CONTROL0, 0,
650 HDMI_GENERIC1_CONT, 0,
651 HDMI_GENERIC1_LINE, 0,
652 HDMI_GENERIC1_SEND, 0,
653 HDMI_GENERIC0_CONT, 0,
654 HDMI_GENERIC0_LINE, 0,
655 HDMI_GENERIC0_SEND, 0);
656
657 /* stop generic packets 2 & 3 on HDMI */
658 REG_SET_6(HDMI_GENERIC_PACKET_CONTROL1, 0,
659 HDMI_GENERIC0_CONT, 0,
660 HDMI_GENERIC0_LINE, 0,
661 HDMI_GENERIC0_SEND, 0,
662 HDMI_GENERIC1_CONT, 0,
663 HDMI_GENERIC1_LINE, 0,
664 HDMI_GENERIC1_SEND, 0);
665
666 /* stop generic packets 2 & 3 on HDMI */
667 REG_SET_6(HDMI_GENERIC_PACKET_CONTROL2, 0,
668 HDMI_GENERIC0_CONT, 0,
669 HDMI_GENERIC0_LINE, 0,
670 HDMI_GENERIC0_SEND, 0,
671 HDMI_GENERIC1_CONT, 0,
672 HDMI_GENERIC1_LINE, 0,
673 HDMI_GENERIC1_SEND, 0);
674
675 REG_SET_6(HDMI_GENERIC_PACKET_CONTROL3, 0,
676 HDMI_GENERIC0_CONT, 0,
677 HDMI_GENERIC0_LINE, 0,
678 HDMI_GENERIC0_SEND, 0,
679 HDMI_GENERIC1_CONT, 0,
680 HDMI_GENERIC1_LINE, 0,
681 HDMI_GENERIC1_SEND, 0);
682}
683
684void enc1_stream_encoder_update_dp_info_packets(
685 struct stream_encoder *enc,
686 const struct encoder_info_frame *info_frame)
687{
688 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
689 uint32_t value = 0;
690
691 if (info_frame->vsc.valid)
692 enc1_update_generic_info_packet(
693 enc1,
694 0, /* packetIndex */
695 &info_frame->vsc);
696
697 if (info_frame->spd.valid)
698 enc1_update_generic_info_packet(
699 enc1,
700 2, /* packetIndex */
701 &info_frame->spd);
702
703 if (info_frame->hdrsmd.valid)
704 enc1_update_generic_info_packet(
705 enc1,
706 3, /* packetIndex */
707 &info_frame->hdrsmd);
708
709 /* enable/disable transmission of packet(s).
710 * If enabled, packet transmission begins on the next frame
711 */
712 REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, info_frame->vsc.valid);
713 REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, info_frame->spd.valid);
714 REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, info_frame->hdrsmd.valid);
715
716
717 /* This bit is the master enable bit.
718 * When enabling secondary stream engine,
719 * this master bit must also be set.
720 * This register shared with audio info frame.
721 * Therefore we need to enable master bit
722 * if at least on of the fields is not 0
723 */
724 value = REG_READ(DP_SEC_CNTL);
725 if (value)
726 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
727}
728
729void enc1_stream_encoder_stop_dp_info_packets(
730 struct stream_encoder *enc)
731{
732 /* stop generic packets on DP */
733 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
734 uint32_t value = 0;
735
736 REG_SET_10(DP_SEC_CNTL, 0,
737 DP_SEC_GSP0_ENABLE, 0,
738 DP_SEC_GSP1_ENABLE, 0,
739 DP_SEC_GSP2_ENABLE, 0,
740 DP_SEC_GSP3_ENABLE, 0,
741 DP_SEC_GSP4_ENABLE, 0,
742 DP_SEC_GSP5_ENABLE, 0,
743 DP_SEC_GSP6_ENABLE, 0,
744 DP_SEC_GSP7_ENABLE, 0,
745 DP_SEC_MPG_ENABLE, 0,
746 DP_SEC_STREAM_ENABLE, 0);
747
748 /* this register shared with audio info frame.
749 * therefore we need to keep master enabled
750 * if at least one of the fields is not 0 */
751 value = REG_READ(DP_SEC_CNTL);
752 if (value)
753 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
754
755}
756
757void enc1_stream_encoder_dp_blank(
758 struct stream_encoder *enc)
759{
760 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
761 uint32_t retries = 0;
762 uint32_t reg1 = 0;
763 uint32_t max_retries = DP_BLANK_MAX_RETRY * 10;
764
765 /* Note: For CZ, we are changing driver default to disable
766 * stream deferred to next VBLANK. If results are positive, we
767 * will make the same change to all DCE versions. There are a
768 * handful of panels that cannot handle disable stream at
769 * HBLANK and will result in a white line flash across the
770 * screen on stream disable.
771 */
772 REG_GET(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, &reg1);
773 if ((reg1 & 0x1) == 0)
774 /*stream not enabled*/
775 return;
776 /* Specify the video stream disable point
777 * (2 = start of the next vertical blank)
778 */
779 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, 2);
780 /* Larger delay to wait until VBLANK - use max retry of
781 * 10us*3000=30ms. This covers 16.6ms of typical 60 Hz mode +
782 * a little more because we may not trust delay accuracy.
783 */
784 max_retries = DP_BLANK_MAX_RETRY * 150;
785
786 /* disable DP stream */
787 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
788
789 /* the encoder stops sending the video stream
790 * at the start of the vertical blanking.
791 * Poll for DP_VID_STREAM_STATUS == 0
792 */
793
794 REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS,
795 0,
796 10, max_retries);
797
798 ASSERT(retries <= max_retries);
799
800 /* Tell the DP encoder to ignore timing from CRTC, must be done after
801 * the polling. If we set DP_STEER_FIFO_RESET before DP stream blank is
802 * complete, stream status will be stuck in video stream enabled state,
803 * i.e. DP_VID_STREAM_STATUS stuck at 1.
804 */
805
806 REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, true);
807}
808
809/* output video stream to link encoder */
810void enc1_stream_encoder_dp_unblank(
811 struct stream_encoder *enc,
812 const struct encoder_unblank_param *param)
813{
814 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
815
816 if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) {
817 uint32_t n_vid = 0x8000;
818 uint32_t m_vid;
819
820 /* M / N = Fstream / Flink
821 * m_vid / n_vid = pixel rate / link rate
822 */
823
824 uint64_t m_vid_l = n_vid;
825
826 m_vid_l *= param->pixel_clk_khz;
827 m_vid_l = div_u64(m_vid_l,
828 param->link_settings.link_rate
829 * LINK_RATE_REF_FREQ_IN_KHZ);
830
831 m_vid = (uint32_t) m_vid_l;
832
833 /* enable auto measurement */
834
835 REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0);
836
837 /* auto measurement need 1 full 0x8000 symbol cycle to kick in,
838 * therefore program initial value for Mvid and Nvid
839 */
840
841 REG_UPDATE(DP_VID_N, DP_VID_N, n_vid);
842
843 REG_UPDATE(DP_VID_M, DP_VID_M, m_vid);
844
845 REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 1);
846 }
847
848 /* set DIG_START to 0x1 to resync FIFO */
849
850 REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);
851
852 /* switch DP encoder to CRTC data */
853
854 REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
855
856 /* wait 100us for DIG/DP logic to prime
857 * (i.e. a few video lines)
858 */
859 udelay(100);
860
861 /* the hardware would start sending video at the start of the next DP
862 * frame (i.e. rising edge of the vblank).
863 * NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this
864 * register has no effect on enable transition! HW always guarantees
865 * VID_STREAM enable at start of next frame, and this is not
866 * programmable
867 */
868
869 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
870}
871
872void enc1_stream_encoder_set_avmute(
873 struct stream_encoder *enc,
874 bool enable)
875{
876 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
877 unsigned int value = enable ? 1 : 0;
878
879 REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, value);
880}
881
882
883#define DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT 0x8000
884#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC 1
885
886#include "include/audio_types.h"
887
888/**
889* speakersToChannels
890*
891* @brief
892* translate speakers to channels
893*
894* FL - Front Left
895* FR - Front Right
896* RL - Rear Left
897* RR - Rear Right
898* RC - Rear Center
899* FC - Front Center
900* FLC - Front Left Center
901* FRC - Front Right Center
902* RLC - Rear Left Center
903* RRC - Rear Right Center
904* LFE - Low Freq Effect
905*
906* FC
907* FLC FRC
908* FL FR
909*
910* LFE
911* ()
912*
913*
914* RL RR
915* RLC RRC
916* RC
917*
918* ch 8 7 6 5 4 3 2 1
919* 0b00000011 - - - - - - FR FL
920* 0b00000111 - - - - - LFE FR FL
921* 0b00001011 - - - - FC - FR FL
922* 0b00001111 - - - - FC LFE FR FL
923* 0b00010011 - - - RC - - FR FL
924* 0b00010111 - - - RC - LFE FR FL
925* 0b00011011 - - - RC FC - FR FL
926* 0b00011111 - - - RC FC LFE FR FL
927* 0b00110011 - - RR RL - - FR FL
928* 0b00110111 - - RR RL - LFE FR FL
929* 0b00111011 - - RR RL FC - FR FL
930* 0b00111111 - - RR RL FC LFE FR FL
931* 0b01110011 - RC RR RL - - FR FL
932* 0b01110111 - RC RR RL - LFE FR FL
933* 0b01111011 - RC RR RL FC - FR FL
934* 0b01111111 - RC RR RL FC LFE FR FL
935* 0b11110011 RRC RLC RR RL - - FR FL
936* 0b11110111 RRC RLC RR RL - LFE FR FL
937* 0b11111011 RRC RLC RR RL FC - FR FL
938* 0b11111111 RRC RLC RR RL FC LFE FR FL
939* 0b11000011 FRC FLC - - - - FR FL
940* 0b11000111 FRC FLC - - - LFE FR FL
941* 0b11001011 FRC FLC - - FC - FR FL
942* 0b11001111 FRC FLC - - FC LFE FR FL
943* 0b11010011 FRC FLC - RC - - FR FL
944* 0b11010111 FRC FLC - RC - LFE FR FL
945* 0b11011011 FRC FLC - RC FC - FR FL
946* 0b11011111 FRC FLC - RC FC LFE FR FL
947* 0b11110011 FRC FLC RR RL - - FR FL
948* 0b11110111 FRC FLC RR RL - LFE FR FL
949* 0b11111011 FRC FLC RR RL FC - FR FL
950* 0b11111111 FRC FLC RR RL FC LFE FR FL
951*
952* @param
953* speakers - speaker information as it comes from CEA audio block
954*/
955/* translate speakers to channels */
956
957union audio_cea_channels {
958 uint8_t all;
959 struct audio_cea_channels_bits {
960 uint32_t FL:1;
961 uint32_t FR:1;
962 uint32_t LFE:1;
963 uint32_t FC:1;
964 uint32_t RL_RC:1;
965 uint32_t RR:1;
966 uint32_t RC_RLC_FLC:1;
967 uint32_t RRC_FRC:1;
968 } channels;
969};
970
971struct audio_clock_info {
972 /* pixel clock frequency*/
973 uint32_t pixel_clock_in_10khz;
974 /* N - 32KHz audio */
975 uint32_t n_32khz;
976 /* CTS - 32KHz audio*/
977 uint32_t cts_32khz;
978 uint32_t n_44khz;
979 uint32_t cts_44khz;
980 uint32_t n_48khz;
981 uint32_t cts_48khz;
982};
983
984/* 25.2MHz/1.001*/
985/* 25.2MHz/1.001*/
986/* 25.2MHz*/
987/* 27MHz */
988/* 27MHz*1.001*/
989/* 27MHz*1.001*/
990/* 54MHz*/
991/* 54MHz*1.001*/
992/* 74.25MHz/1.001*/
993/* 74.25MHz*/
994/* 148.5MHz/1.001*/
995/* 148.5MHz*/
996
997static const struct audio_clock_info audio_clock_info_table[16] = {
998 {2517, 4576, 28125, 7007, 31250, 6864, 28125},
999 {2518, 4576, 28125, 7007, 31250, 6864, 28125},
1000 {2520, 4096, 25200, 6272, 28000, 6144, 25200},
1001 {2700, 4096, 27000, 6272, 30000, 6144, 27000},
1002 {2702, 4096, 27027, 6272, 30030, 6144, 27027},
1003 {2703, 4096, 27027, 6272, 30030, 6144, 27027},
1004 {5400, 4096, 54000, 6272, 60000, 6144, 54000},
1005 {5405, 4096, 54054, 6272, 60060, 6144, 54054},
1006 {7417, 11648, 210937, 17836, 234375, 11648, 140625},
1007 {7425, 4096, 74250, 6272, 82500, 6144, 74250},
1008 {14835, 11648, 421875, 8918, 234375, 5824, 140625},
1009 {14850, 4096, 148500, 6272, 165000, 6144, 148500},
1010 {29670, 5824, 421875, 4459, 234375, 5824, 281250},
1011 {29700, 3072, 222750, 4704, 247500, 5120, 247500},
1012 {59340, 5824, 843750, 8918, 937500, 5824, 562500},
1013 {59400, 3072, 445500, 9408, 990000, 6144, 594000}
1014};
1015
1016static const struct audio_clock_info audio_clock_info_table_36bpc[14] = {
1017 {2517, 9152, 84375, 7007, 48875, 9152, 56250},
1018 {2518, 9152, 84375, 7007, 48875, 9152, 56250},
1019 {2520, 4096, 37800, 6272, 42000, 6144, 37800},
1020 {2700, 4096, 40500, 6272, 45000, 6144, 40500},
1021 {2702, 8192, 81081, 6272, 45045, 8192, 54054},
1022 {2703, 8192, 81081, 6272, 45045, 8192, 54054},
1023 {5400, 4096, 81000, 6272, 90000, 6144, 81000},
1024 {5405, 4096, 81081, 6272, 90090, 6144, 81081},
1025 {7417, 11648, 316406, 17836, 351562, 11648, 210937},
1026 {7425, 4096, 111375, 6272, 123750, 6144, 111375},
1027 {14835, 11648, 632812, 17836, 703125, 11648, 421875},
1028 {14850, 4096, 222750, 6272, 247500, 6144, 222750},
1029 {29670, 5824, 632812, 8918, 703125, 5824, 421875},
1030 {29700, 4096, 445500, 4704, 371250, 5120, 371250}
1031};
1032
1033static const struct audio_clock_info audio_clock_info_table_48bpc[14] = {
1034 {2517, 4576, 56250, 7007, 62500, 6864, 56250},
1035 {2518, 4576, 56250, 7007, 62500, 6864, 56250},
1036 {2520, 4096, 50400, 6272, 56000, 6144, 50400},
1037 {2700, 4096, 54000, 6272, 60000, 6144, 54000},
1038 {2702, 4096, 54054, 6267, 60060, 8192, 54054},
1039 {2703, 4096, 54054, 6272, 60060, 8192, 54054},
1040 {5400, 4096, 108000, 6272, 120000, 6144, 108000},
1041 {5405, 4096, 108108, 6272, 120120, 6144, 108108},
1042 {7417, 11648, 421875, 17836, 468750, 11648, 281250},
1043 {7425, 4096, 148500, 6272, 165000, 6144, 148500},
1044 {14835, 11648, 843750, 8918, 468750, 11648, 281250},
1045 {14850, 4096, 297000, 6272, 330000, 6144, 297000},
1046 {29670, 5824, 843750, 4459, 468750, 5824, 562500},
1047 {29700, 3072, 445500, 4704, 495000, 5120, 495000}
1048
1049
1050};
1051
1052static union audio_cea_channels speakers_to_channels(
1053 struct audio_speaker_flags speaker_flags)
1054{
1055 union audio_cea_channels cea_channels = {0};
1056
1057 /* these are one to one */
1058 cea_channels.channels.FL = speaker_flags.FL_FR;
1059 cea_channels.channels.FR = speaker_flags.FL_FR;
1060 cea_channels.channels.LFE = speaker_flags.LFE;
1061 cea_channels.channels.FC = speaker_flags.FC;
1062
1063 /* if Rear Left and Right exist move RC speaker to channel 7
1064 * otherwise to channel 5
1065 */
1066 if (speaker_flags.RL_RR) {
1067 cea_channels.channels.RL_RC = speaker_flags.RL_RR;
1068 cea_channels.channels.RR = speaker_flags.RL_RR;
1069 cea_channels.channels.RC_RLC_FLC = speaker_flags.RC;
1070 } else {
1071 cea_channels.channels.RL_RC = speaker_flags.RC;
1072 }
1073
1074 /* FRONT Left Right Center and REAR Left Right Center are exclusive */
1075 if (speaker_flags.FLC_FRC) {
1076 cea_channels.channels.RC_RLC_FLC = speaker_flags.FLC_FRC;
1077 cea_channels.channels.RRC_FRC = speaker_flags.FLC_FRC;
1078 } else {
1079 cea_channels.channels.RC_RLC_FLC = speaker_flags.RLC_RRC;
1080 cea_channels.channels.RRC_FRC = speaker_flags.RLC_RRC;
1081 }
1082
1083 return cea_channels;
1084}
1085
1086static uint32_t calc_max_audio_packets_per_line(
1087 const struct audio_crtc_info *crtc_info)
1088{
1089 uint32_t max_packets_per_line;
1090
1091 max_packets_per_line =
1092 crtc_info->h_total - crtc_info->h_active;
1093
1094 if (crtc_info->pixel_repetition)
1095 max_packets_per_line *= crtc_info->pixel_repetition;
1096
1097 /* for other hdmi features */
1098 max_packets_per_line -= 58;
1099 /* for Control Period */
1100 max_packets_per_line -= 16;
1101 /* Number of Audio Packets per Line */
1102 max_packets_per_line /= 32;
1103
1104 return max_packets_per_line;
1105}
1106
1107static void get_audio_clock_info(
1108 enum dc_color_depth color_depth,
1109 uint32_t crtc_pixel_clock_in_khz,
1110 uint32_t actual_pixel_clock_in_khz,
1111 struct audio_clock_info *audio_clock_info)
1112{
1113 const struct audio_clock_info *clock_info;
1114 uint32_t index;
1115 uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_in_khz / 10;
1116 uint32_t audio_array_size;
1117
1118 switch (color_depth) {
1119 case COLOR_DEPTH_161616:
1120 clock_info = audio_clock_info_table_48bpc;
1121 audio_array_size = ARRAY_SIZE(
1122 audio_clock_info_table_48bpc);
1123 break;
1124 case COLOR_DEPTH_121212:
1125 clock_info = audio_clock_info_table_36bpc;
1126 audio_array_size = ARRAY_SIZE(
1127 audio_clock_info_table_36bpc);
1128 break;
1129 default:
1130 clock_info = audio_clock_info_table;
1131 audio_array_size = ARRAY_SIZE(
1132 audio_clock_info_table);
1133 break;
1134 }
1135
1136 if (clock_info != NULL) {
1137 /* search for exact pixel clock in table */
1138 for (index = 0; index < audio_array_size; index++) {
1139 if (clock_info[index].pixel_clock_in_10khz >
1140 crtc_pixel_clock_in_10khz)
1141 break; /* not match */
1142 else if (clock_info[index].pixel_clock_in_10khz ==
1143 crtc_pixel_clock_in_10khz) {
1144 /* match found */
1145 *audio_clock_info = clock_info[index];
1146 return;
1147 }
1148 }
1149 }
1150
1151 /* not found */
1152 if (actual_pixel_clock_in_khz == 0)
1153 actual_pixel_clock_in_khz = crtc_pixel_clock_in_khz;
1154
1155 /* See HDMI spec the table entry under
1156 * pixel clock of "Other". */
1157 audio_clock_info->pixel_clock_in_10khz =
1158 actual_pixel_clock_in_khz / 10;
1159 audio_clock_info->cts_32khz = actual_pixel_clock_in_khz;
1160 audio_clock_info->cts_44khz = actual_pixel_clock_in_khz;
1161 audio_clock_info->cts_48khz = actual_pixel_clock_in_khz;
1162
1163 audio_clock_info->n_32khz = 4096;
1164 audio_clock_info->n_44khz = 6272;
1165 audio_clock_info->n_48khz = 6144;
1166}
1167
1168static void enc1_se_audio_setup(
1169 struct stream_encoder *enc,
1170 unsigned int az_inst,
1171 struct audio_info *audio_info)
1172{
1173 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
1174
1175 uint32_t speakers = 0;
1176 uint32_t channels = 0;
1177
1178 ASSERT(audio_info);
1179 if (audio_info == NULL)
1180 /* This should not happen.it does so we don't get BSOD*/
1181 return;
1182
1183 speakers = audio_info->flags.info.ALLSPEAKERS;
1184 channels = speakers_to_channels(audio_info->flags.speaker_flags).all;
1185
1186 /* setup the audio stream source select (audio -> dig mapping) */
1187 REG_SET(AFMT_AUDIO_SRC_CONTROL, 0, AFMT_AUDIO_SRC_SELECT, az_inst);
1188
1189 /* Channel allocation */
1190 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels);
1191}
1192
1193static void enc1_se_setup_hdmi_audio(
1194 struct stream_encoder *enc,
1195 const struct audio_crtc_info *crtc_info)
1196{
1197 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
1198
1199 struct audio_clock_info audio_clock_info = {0};
1200 uint32_t max_packets_per_line;
1201
1202 /* For now still do calculation, although this field is ignored when
1203 * above HDMI_PACKET_GEN_VERSION set to 1
1204 */
1205 max_packets_per_line = calc_max_audio_packets_per_line(crtc_info);
1206
1207 /* HDMI_AUDIO_PACKET_CONTROL */
1208 REG_UPDATE_2(HDMI_AUDIO_PACKET_CONTROL,
1209 HDMI_AUDIO_PACKETS_PER_LINE, max_packets_per_line,
1210 HDMI_AUDIO_DELAY_EN, 1);
1211
1212 /* AFMT_AUDIO_PACKET_CONTROL */
1213 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
1214
1215 /* AFMT_AUDIO_PACKET_CONTROL2 */
1216 REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,
1217 AFMT_AUDIO_LAYOUT_OVRD, 0,
1218 AFMT_60958_OSF_OVRD, 0);
1219
1220 /* HDMI_ACR_PACKET_CONTROL */
1221 REG_UPDATE_3(HDMI_ACR_PACKET_CONTROL,
1222 HDMI_ACR_AUTO_SEND, 1,
1223 HDMI_ACR_SOURCE, 0,
1224 HDMI_ACR_AUDIO_PRIORITY, 0);
1225
1226 /* Program audio clock sample/regeneration parameters */
1227 get_audio_clock_info(crtc_info->color_depth,
1228 crtc_info->requested_pixel_clock,
1229 crtc_info->calculated_pixel_clock,
1230 &audio_clock_info);
1231 DC_LOG_HW_AUDIO(
1232 "\n%s:Input::requested_pixel_clock = %d" \
1233 "calculated_pixel_clock = %d \n", __func__, \
1234 crtc_info->requested_pixel_clock, \
1235 crtc_info->calculated_pixel_clock);
1236
1237 /* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */
1238 REG_UPDATE(HDMI_ACR_32_0, HDMI_ACR_CTS_32, audio_clock_info.cts_32khz);
1239
1240 /* HDMI_ACR_32_1__HDMI_ACR_N_32_MASK */
1241 REG_UPDATE(HDMI_ACR_32_1, HDMI_ACR_N_32, audio_clock_info.n_32khz);
1242
1243 /* HDMI_ACR_44_0__HDMI_ACR_CTS_44_MASK */
1244 REG_UPDATE(HDMI_ACR_44_0, HDMI_ACR_CTS_44, audio_clock_info.cts_44khz);
1245
1246 /* HDMI_ACR_44_1__HDMI_ACR_N_44_MASK */
1247 REG_UPDATE(HDMI_ACR_44_1, HDMI_ACR_N_44, audio_clock_info.n_44khz);
1248
1249 /* HDMI_ACR_48_0__HDMI_ACR_CTS_48_MASK */
1250 REG_UPDATE(HDMI_ACR_48_0, HDMI_ACR_CTS_48, audio_clock_info.cts_48khz);
1251
1252 /* HDMI_ACR_48_1__HDMI_ACR_N_48_MASK */
1253 REG_UPDATE(HDMI_ACR_48_1, HDMI_ACR_N_48, audio_clock_info.n_48khz);
1254
1255 /* Video driver cannot know in advance which sample rate will
1256 * be used by HD Audio driver
1257 * HDMI_ACR_PACKET_CONTROL__HDMI_ACR_N_MULTIPLE field is
1258 * programmed below in interruppt callback
1259 */
1260
1261 /* AFMT_60958_0__AFMT_60958_CS_CHANNEL_NUMBER_L_MASK &
1262 * AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK
1263 */
1264 REG_UPDATE_2(AFMT_60958_0,
1265 AFMT_60958_CS_CHANNEL_NUMBER_L, 1,
1266 AFMT_60958_CS_CLOCK_ACCURACY, 0);
1267
1268 /* AFMT_60958_1 AFMT_60958_CS_CHALNNEL_NUMBER_R */
1269 REG_UPDATE(AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, 2);
1270
1271 /* AFMT_60958_2 now keep this settings until
1272 * Programming guide comes out
1273 */
1274 REG_UPDATE_6(AFMT_60958_2,
1275 AFMT_60958_CS_CHANNEL_NUMBER_2, 3,
1276 AFMT_60958_CS_CHANNEL_NUMBER_3, 4,
1277 AFMT_60958_CS_CHANNEL_NUMBER_4, 5,
1278 AFMT_60958_CS_CHANNEL_NUMBER_5, 6,
1279 AFMT_60958_CS_CHANNEL_NUMBER_6, 7,
1280 AFMT_60958_CS_CHANNEL_NUMBER_7, 8);
1281}
1282
1283static void enc1_se_setup_dp_audio(
1284 struct stream_encoder *enc)
1285{
1286 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
1287
1288 /* --- DP Audio packet configurations --- */
1289
1290 /* ATP Configuration */
1291 REG_SET(DP_SEC_AUD_N, 0,
1292 DP_SEC_AUD_N, DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT);
1293
1294 /* Async/auto-calc timestamp mode */
1295 REG_SET(DP_SEC_TIMESTAMP, 0, DP_SEC_TIMESTAMP_MODE,
1296 DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC);
1297
1298 /* --- The following are the registers
1299 * copied from the SetupHDMI ---
1300 */
1301
1302 /* AFMT_AUDIO_PACKET_CONTROL */
1303 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
1304
1305 /* AFMT_AUDIO_PACKET_CONTROL2 */
1306 /* Program the ATP and AIP next */
1307 REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,
1308 AFMT_AUDIO_LAYOUT_OVRD, 0,
1309 AFMT_60958_OSF_OVRD, 0);
1310
1311 /* AFMT_INFOFRAME_CONTROL0 */
1312 REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
1313
1314 /* AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK */
1315 REG_UPDATE(AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, 0);
1316}
1317
1318static void enc1_se_enable_audio_clock(
1319 struct stream_encoder *enc,
1320 bool enable)
1321{
1322 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
1323
1324 if (REG(AFMT_CNTL) == 0)
1325 return; /* DCE8/10 does not have this register */
1326
1327 REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, !!enable);
1328
1329 /* wait for AFMT clock to turn on,
1330 * expectation: this should complete in 1-2 reads
1331 *
1332 * REG_WAIT(AFMT_CNTL, AFMT_AUDIO_CLOCK_ON, !!enable, 1, 10);
1333 *
1334 * TODO: wait for clock_on does not work well. May need HW
1335 * program sequence. But audio seems work normally even without wait
1336 * for clock_on status change
1337 */
1338}
1339
1340static void enc1_se_enable_dp_audio(
1341 struct stream_encoder *enc)
1342{
1343 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
1344
1345 /* Enable Audio packets */
1346 REG_UPDATE(DP_SEC_CNTL, DP_SEC_ASP_ENABLE, 1);
1347
1348 /* Program the ATP and AIP next */
1349 REG_UPDATE_2(DP_SEC_CNTL,
1350 DP_SEC_ATP_ENABLE, 1,
1351 DP_SEC_AIP_ENABLE, 1);
1352
1353 /* Program STREAM_ENABLE after all the other enables. */
1354 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
1355}
1356
1357static void enc1_se_disable_dp_audio(
1358 struct stream_encoder *enc)
1359{
1360 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
1361 uint32_t value = 0;
1362
1363 /* Disable Audio packets */
1364 REG_UPDATE_5(DP_SEC_CNTL,
1365 DP_SEC_ASP_ENABLE, 0,
1366 DP_SEC_ATP_ENABLE, 0,
1367 DP_SEC_AIP_ENABLE, 0,
1368 DP_SEC_ACM_ENABLE, 0,
1369 DP_SEC_STREAM_ENABLE, 0);
1370
1371 /* This register shared with encoder info frame. Therefore we need to
1372 * keep master enabled if at least on of the fields is not 0
1373 */
1374 value = REG_READ(DP_SEC_CNTL);
1375 if (value != 0)
1376 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
1377
1378}
1379
1380void enc1_se_audio_mute_control(
1381 struct stream_encoder *enc,
1382 bool mute)
1383{
1384 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
1385
1386 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute);
1387}
1388
1389void enc1_se_dp_audio_setup(
1390 struct stream_encoder *enc,
1391 unsigned int az_inst,
1392 struct audio_info *info)
1393{
1394 enc1_se_audio_setup(enc, az_inst, info);
1395}
1396
1397void enc1_se_dp_audio_enable(
1398 struct stream_encoder *enc)
1399{
1400 enc1_se_enable_audio_clock(enc, true);
1401 enc1_se_setup_dp_audio(enc);
1402 enc1_se_enable_dp_audio(enc);
1403}
1404
1405void enc1_se_dp_audio_disable(
1406 struct stream_encoder *enc)
1407{
1408 enc1_se_disable_dp_audio(enc);
1409 enc1_se_enable_audio_clock(enc, false);
1410}
1411
1412void enc1_se_hdmi_audio_setup(
1413 struct stream_encoder *enc,
1414 unsigned int az_inst,
1415 struct audio_info *info,
1416 struct audio_crtc_info *audio_crtc_info)
1417{
1418 enc1_se_enable_audio_clock(enc, true);
1419 enc1_se_setup_hdmi_audio(enc, audio_crtc_info);
1420 enc1_se_audio_setup(enc, az_inst, info);
1421}
1422
1423void enc1_se_hdmi_audio_disable(
1424 struct stream_encoder *enc)
1425{
1426 enc1_se_enable_audio_clock(enc, false);
1427}
1428
1429
1430void enc1_setup_stereo_sync(
1431 struct stream_encoder *enc,
1432 int tg_inst, bool enable)
1433{
1434 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
1435 REG_UPDATE(DIG_FE_CNTL, DIG_STEREOSYNC_SELECT, tg_inst);
1436 REG_UPDATE(DIG_FE_CNTL, DIG_STEREOSYNC_GATE_EN, !enable);
1437}
1438
1439
1440static const struct stream_encoder_funcs dcn10_str_enc_funcs = {
1441 .dp_set_stream_attribute =
1442 enc1_stream_encoder_dp_set_stream_attribute,
1443 .hdmi_set_stream_attribute =
1444 enc1_stream_encoder_hdmi_set_stream_attribute,
1445 .dvi_set_stream_attribute =
1446 enc1_stream_encoder_dvi_set_stream_attribute,
1447 .set_mst_bandwidth =
1448 enc1_stream_encoder_set_mst_bandwidth,
1449 .update_hdmi_info_packets =
1450 enc1_stream_encoder_update_hdmi_info_packets,
1451 .stop_hdmi_info_packets =
1452 enc1_stream_encoder_stop_hdmi_info_packets,
1453 .update_dp_info_packets =
1454 enc1_stream_encoder_update_dp_info_packets,
1455 .stop_dp_info_packets =
1456 enc1_stream_encoder_stop_dp_info_packets,
1457 .dp_blank =
1458 enc1_stream_encoder_dp_blank,
1459 .dp_unblank =
1460 enc1_stream_encoder_dp_unblank,
1461 .audio_mute_control = enc1_se_audio_mute_control,
1462
1463 .dp_audio_setup = enc1_se_dp_audio_setup,
1464 .dp_audio_enable = enc1_se_dp_audio_enable,
1465 .dp_audio_disable = enc1_se_dp_audio_disable,
1466
1467 .hdmi_audio_setup = enc1_se_hdmi_audio_setup,
1468 .hdmi_audio_disable = enc1_se_hdmi_audio_disable,
1469 .setup_stereo_sync = enc1_setup_stereo_sync,
1470 .set_avmute = enc1_stream_encoder_set_avmute,
1471};
1472
1473void dcn10_stream_encoder_construct(
1474 struct dcn10_stream_encoder *enc1,
1475 struct dc_context *ctx,
1476 struct dc_bios *bp,
1477 enum engine_id eng_id,
1478 const struct dcn10_stream_enc_registers *regs,
1479 const struct dcn10_stream_encoder_shift *se_shift,
1480 const struct dcn10_stream_encoder_mask *se_mask)
1481{
1482 enc1->base.funcs = &dcn10_str_enc_funcs;
1483 enc1->base.ctx = ctx;
1484 enc1->base.id = eng_id;
1485 enc1->base.bp = bp;
1486 enc1->regs = regs;
1487 enc1->se_shift = se_shift;
1488 enc1->se_mask = se_mask;
1489}
1490
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
new file mode 100644
index 000000000000..6b3e4ded155b
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
@@ -0,0 +1,524 @@
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#ifndef __DC_STREAM_ENCODER_DCN10_H__
27#define __DC_STREAM_ENCODER_DCN10_H__
28
29#include "stream_encoder.h"
30
31#define DCN10STRENC_FROM_STRENC(stream_encoder)\
32 container_of(stream_encoder, struct dcn10_stream_encoder, base)
33
34#define SE_COMMON_DCN_REG_LIST(id) \
35 SRI(AFMT_CNTL, DIG, id), \
36 SRI(AFMT_GENERIC_0, DIG, id), \
37 SRI(AFMT_GENERIC_1, DIG, id), \
38 SRI(AFMT_GENERIC_2, DIG, id), \
39 SRI(AFMT_GENERIC_3, DIG, id), \
40 SRI(AFMT_GENERIC_4, DIG, id), \
41 SRI(AFMT_GENERIC_5, DIG, id), \
42 SRI(AFMT_GENERIC_6, DIG, id), \
43 SRI(AFMT_GENERIC_7, DIG, id), \
44 SRI(AFMT_GENERIC_HDR, DIG, id), \
45 SRI(AFMT_INFOFRAME_CONTROL0, DIG, id), \
46 SRI(AFMT_VBI_PACKET_CONTROL, DIG, id), \
47 SRI(AFMT_VBI_PACKET_CONTROL1, DIG, id), \
48 SRI(AFMT_AUDIO_PACKET_CONTROL, DIG, id), \
49 SRI(AFMT_AUDIO_PACKET_CONTROL2, DIG, id), \
50 SRI(AFMT_AUDIO_SRC_CONTROL, DIG, id), \
51 SRI(AFMT_60958_0, DIG, id), \
52 SRI(AFMT_60958_1, DIG, id), \
53 SRI(AFMT_60958_2, DIG, id), \
54 SRI(DIG_FE_CNTL, DIG, id), \
55 SRI(HDMI_CONTROL, DIG, id), \
56 SRI(HDMI_DB_CONTROL, DIG, id), \
57 SRI(HDMI_GC, DIG, id), \
58 SRI(HDMI_GENERIC_PACKET_CONTROL0, DIG, id), \
59 SRI(HDMI_GENERIC_PACKET_CONTROL1, DIG, id), \
60 SRI(HDMI_GENERIC_PACKET_CONTROL2, DIG, id), \
61 SRI(HDMI_GENERIC_PACKET_CONTROL3, DIG, id), \
62 SRI(HDMI_INFOFRAME_CONTROL0, DIG, id), \
63 SRI(HDMI_INFOFRAME_CONTROL1, DIG, id), \
64 SRI(HDMI_VBI_PACKET_CONTROL, DIG, id), \
65 SRI(HDMI_AUDIO_PACKET_CONTROL, DIG, id),\
66 SRI(HDMI_ACR_PACKET_CONTROL, DIG, id),\
67 SRI(HDMI_ACR_32_0, DIG, id),\
68 SRI(HDMI_ACR_32_1, DIG, id),\
69 SRI(HDMI_ACR_44_0, DIG, id),\
70 SRI(HDMI_ACR_44_1, DIG, id),\
71 SRI(HDMI_ACR_48_0, DIG, id),\
72 SRI(HDMI_ACR_48_1, DIG, id),\
73 SRI(DP_DB_CNTL, DP, id), \
74 SRI(DP_MSA_MISC, DP, id), \
75 SRI(DP_MSA_COLORIMETRY, DP, id), \
76 SRI(DP_MSA_TIMING_PARAM1, DP, id), \
77 SRI(DP_MSA_TIMING_PARAM2, DP, id), \
78 SRI(DP_MSA_TIMING_PARAM3, DP, id), \
79 SRI(DP_MSA_TIMING_PARAM4, DP, id), \
80 SRI(DP_MSE_RATE_CNTL, DP, id), \
81 SRI(DP_MSE_RATE_UPDATE, DP, id), \
82 SRI(DP_PIXEL_FORMAT, DP, id), \
83 SRI(DP_SEC_CNTL, DP, id), \
84 SRI(DP_STEER_FIFO, DP, id), \
85 SRI(DP_VID_M, DP, id), \
86 SRI(DP_VID_N, DP, id), \
87 SRI(DP_VID_STREAM_CNTL, DP, id), \
88 SRI(DP_VID_TIMING, DP, id), \
89 SRI(DP_SEC_AUD_N, DP, id), \
90 SRI(DP_SEC_TIMESTAMP, DP, id)
91
92#define SE_DCN_REG_LIST(id)\
93 SE_COMMON_DCN_REG_LIST(id)
94
95
96struct dcn10_stream_enc_registers {
97 uint32_t AFMT_CNTL;
98 uint32_t AFMT_AVI_INFO0;
99 uint32_t AFMT_AVI_INFO1;
100 uint32_t AFMT_AVI_INFO2;
101 uint32_t AFMT_AVI_INFO3;
102 uint32_t AFMT_GENERIC_0;
103 uint32_t AFMT_GENERIC_1;
104 uint32_t AFMT_GENERIC_2;
105 uint32_t AFMT_GENERIC_3;
106 uint32_t AFMT_GENERIC_4;
107 uint32_t AFMT_GENERIC_5;
108 uint32_t AFMT_GENERIC_6;
109 uint32_t AFMT_GENERIC_7;
110 uint32_t AFMT_GENERIC_HDR;
111 uint32_t AFMT_INFOFRAME_CONTROL0;
112 uint32_t AFMT_VBI_PACKET_CONTROL;
113 uint32_t AFMT_VBI_PACKET_CONTROL1;
114 uint32_t AFMT_AUDIO_PACKET_CONTROL;
115 uint32_t AFMT_AUDIO_PACKET_CONTROL2;
116 uint32_t AFMT_AUDIO_SRC_CONTROL;
117 uint32_t AFMT_60958_0;
118 uint32_t AFMT_60958_1;
119 uint32_t AFMT_60958_2;
120 uint32_t DIG_FE_CNTL;
121 uint32_t DP_MSE_RATE_CNTL;
122 uint32_t DP_MSE_RATE_UPDATE;
123 uint32_t DP_PIXEL_FORMAT;
124 uint32_t DP_SEC_CNTL;
125 uint32_t DP_STEER_FIFO;
126 uint32_t DP_VID_M;
127 uint32_t DP_VID_N;
128 uint32_t DP_VID_STREAM_CNTL;
129 uint32_t DP_VID_TIMING;
130 uint32_t DP_SEC_AUD_N;
131 uint32_t DP_SEC_TIMESTAMP;
132 uint32_t HDMI_CONTROL;
133 uint32_t HDMI_GC;
134 uint32_t HDMI_GENERIC_PACKET_CONTROL0;
135 uint32_t HDMI_GENERIC_PACKET_CONTROL1;
136 uint32_t HDMI_GENERIC_PACKET_CONTROL2;
137 uint32_t HDMI_GENERIC_PACKET_CONTROL3;
138 uint32_t HDMI_GENERIC_PACKET_CONTROL4;
139 uint32_t HDMI_GENERIC_PACKET_CONTROL5;
140 uint32_t HDMI_INFOFRAME_CONTROL0;
141 uint32_t HDMI_INFOFRAME_CONTROL1;
142 uint32_t HDMI_VBI_PACKET_CONTROL;
143 uint32_t HDMI_AUDIO_PACKET_CONTROL;
144 uint32_t HDMI_ACR_PACKET_CONTROL;
145 uint32_t HDMI_ACR_32_0;
146 uint32_t HDMI_ACR_32_1;
147 uint32_t HDMI_ACR_44_0;
148 uint32_t HDMI_ACR_44_1;
149 uint32_t HDMI_ACR_48_0;
150 uint32_t HDMI_ACR_48_1;
151 uint32_t DP_DB_CNTL;
152 uint32_t DP_MSA_MISC;
153 uint32_t DP_MSA_COLORIMETRY;
154 uint32_t DP_MSA_TIMING_PARAM1;
155 uint32_t DP_MSA_TIMING_PARAM2;
156 uint32_t DP_MSA_TIMING_PARAM3;
157 uint32_t DP_MSA_TIMING_PARAM4;
158 uint32_t HDMI_DB_CONTROL;
159};
160
161
162#define SE_SF(reg_name, field_name, post_fix)\
163 .field_name = reg_name ## __ ## field_name ## post_fix
164
165#define SE_COMMON_MASK_SH_LIST_SOC_BASE(mask_sh)\
166 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_INDEX, mask_sh),\
167 SE_SF(DIG0_AFMT_GENERIC_HDR, AFMT_GENERIC_HB0, mask_sh),\
168 SE_SF(DIG0_AFMT_GENERIC_HDR, AFMT_GENERIC_HB1, mask_sh),\
169 SE_SF(DIG0_AFMT_GENERIC_HDR, AFMT_GENERIC_HB2, mask_sh),\
170 SE_SF(DIG0_AFMT_GENERIC_HDR, AFMT_GENERIC_HB3, mask_sh),\
171 SE_SF(DP0_DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, mask_sh),\
172 SE_SF(DP0_DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, mask_sh),\
173 SE_SF(DIG0_HDMI_CONTROL, HDMI_PACKET_GEN_VERSION, mask_sh),\
174 SE_SF(DIG0_HDMI_CONTROL, HDMI_KEEPOUT_MODE, mask_sh),\
175 SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_ENABLE, mask_sh),\
176 SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, mask_sh),\
177 SE_SF(DIG0_HDMI_CONTROL, HDMI_DATA_SCRAMBLE_EN, mask_sh),\
178 SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_CONT, mask_sh),\
179 SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_SEND, mask_sh),\
180 SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_NULL_SEND, mask_sh),\
181 SE_SF(DIG0_HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, mask_sh),\
182 SE_SF(DIG0_AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, mask_sh),\
183 SE_SF(DIG0_HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE, mask_sh),\
184 SE_SF(DIG0_HDMI_GC, HDMI_GC_AVMUTE, mask_sh),\
185 SE_SF(DP0_DP_MSE_RATE_CNTL, DP_MSE_RATE_X, mask_sh),\
186 SE_SF(DP0_DP_MSE_RATE_CNTL, DP_MSE_RATE_Y, mask_sh),\
187 SE_SF(DP0_DP_MSE_RATE_UPDATE, DP_MSE_RATE_UPDATE_PENDING, mask_sh),\
188 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, mask_sh),\
189 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, mask_sh),\
190 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP1_ENABLE, mask_sh),\
191 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, mask_sh),\
192 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, mask_sh),\
193 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_MPG_ENABLE, mask_sh),\
194 SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, mask_sh),\
195 SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, mask_sh),\
196 SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, mask_sh),\
197 SE_SF(DP0_DP_STEER_FIFO, DP_STEER_FIFO_RESET, mask_sh),\
198 SE_SF(DP0_DP_VID_TIMING, DP_VID_M_N_GEN_EN, mask_sh),\
199 SE_SF(DP0_DP_VID_N, DP_VID_N, mask_sh),\
200 SE_SF(DP0_DP_VID_M, DP_VID_M, mask_sh),\
201 SE_SF(DIG0_DIG_FE_CNTL, DIG_START, mask_sh),\
202 SE_SF(DIG0_AFMT_AUDIO_SRC_CONTROL, AFMT_AUDIO_SRC_SELECT, mask_sh),\
203 SE_SF(DIG0_AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, mask_sh),\
204 SE_SF(DIG0_HDMI_AUDIO_PACKET_CONTROL, HDMI_AUDIO_PACKETS_PER_LINE, mask_sh),\
205 SE_SF(DIG0_HDMI_AUDIO_PACKET_CONTROL, HDMI_AUDIO_DELAY_EN, mask_sh),\
206 SE_SF(DIG0_AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, mask_sh),\
207 SE_SF(DIG0_AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_LAYOUT_OVRD, mask_sh),\
208 SE_SF(DIG0_AFMT_AUDIO_PACKET_CONTROL2, AFMT_60958_OSF_OVRD, mask_sh),\
209 SE_SF(DIG0_HDMI_ACR_PACKET_CONTROL, HDMI_ACR_AUTO_SEND, mask_sh),\
210 SE_SF(DIG0_HDMI_ACR_PACKET_CONTROL, HDMI_ACR_SOURCE, mask_sh),\
211 SE_SF(DIG0_HDMI_ACR_PACKET_CONTROL, HDMI_ACR_AUDIO_PRIORITY, mask_sh),\
212 SE_SF(DIG0_HDMI_ACR_32_0, HDMI_ACR_CTS_32, mask_sh),\
213 SE_SF(DIG0_HDMI_ACR_32_1, HDMI_ACR_N_32, mask_sh),\
214 SE_SF(DIG0_HDMI_ACR_44_0, HDMI_ACR_CTS_44, mask_sh),\
215 SE_SF(DIG0_HDMI_ACR_44_1, HDMI_ACR_N_44, mask_sh),\
216 SE_SF(DIG0_HDMI_ACR_48_0, HDMI_ACR_CTS_48, mask_sh),\
217 SE_SF(DIG0_HDMI_ACR_48_1, HDMI_ACR_N_48, mask_sh),\
218 SE_SF(DIG0_AFMT_60958_0, AFMT_60958_CS_CHANNEL_NUMBER_L, mask_sh),\
219 SE_SF(DIG0_AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, mask_sh),\
220 SE_SF(DIG0_AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, mask_sh),\
221 SE_SF(DIG0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_2, mask_sh),\
222 SE_SF(DIG0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_3, mask_sh),\
223 SE_SF(DIG0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_4, mask_sh),\
224 SE_SF(DIG0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_5, mask_sh),\
225 SE_SF(DIG0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_6, mask_sh),\
226 SE_SF(DIG0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_7, mask_sh),\
227 SE_SF(DP0_DP_SEC_AUD_N, DP_SEC_AUD_N, mask_sh),\
228 SE_SF(DP0_DP_SEC_TIMESTAMP, DP_SEC_TIMESTAMP_MODE, mask_sh),\
229 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ASP_ENABLE, mask_sh),\
230 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ATP_ENABLE, mask_sh),\
231 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_AIP_ENABLE, mask_sh),\
232 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ACM_ENABLE, mask_sh),\
233 SE_SF(DIG0_AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, mask_sh),\
234 SE_SF(DIG0_AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, mask_sh),\
235 SE_SF(DIG0_HDMI_CONTROL, HDMI_CLOCK_CHANNEL_RATE, mask_sh),\
236 SE_SF(DIG0_DIG_FE_CNTL, TMDS_PIXEL_ENCODING, mask_sh),\
237 SE_SF(DIG0_DIG_FE_CNTL, TMDS_COLOR_FORMAT, mask_sh),\
238 SE_SF(DIG0_DIG_FE_CNTL, DIG_STEREOSYNC_SELECT, mask_sh),\
239 SE_SF(DIG0_DIG_FE_CNTL, DIG_STEREOSYNC_GATE_EN, mask_sh),\
240 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS, mask_sh),\
241 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT, mask_sh),\
242 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, mask_sh),\
243 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC0_FRAME_UPDATE_PENDING, mask_sh),\
244 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC1_FRAME_UPDATE_PENDING, mask_sh),\
245 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_FRAME_UPDATE_PENDING, mask_sh),\
246 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_FRAME_UPDATE_PENDING, mask_sh),\
247 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_FRAME_UPDATE_PENDING, mask_sh),\
248 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_FRAME_UPDATE_PENDING, mask_sh),\
249 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_FRAME_UPDATE_PENDING, mask_sh),\
250 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE_PENDING, mask_sh),\
251 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC0_FRAME_UPDATE, mask_sh),\
252 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC1_FRAME_UPDATE, mask_sh),\
253 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_FRAME_UPDATE, mask_sh),\
254 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_FRAME_UPDATE, mask_sh),\
255 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_FRAME_UPDATE, mask_sh),\
256 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_FRAME_UPDATE, mask_sh),\
257 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_FRAME_UPDATE, mask_sh),\
258 SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE, mask_sh),\
259 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP4_ENABLE, mask_sh),\
260 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP5_ENABLE, mask_sh),\
261 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP6_ENABLE, mask_sh),\
262 SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, mask_sh),\
263 SE_SF(DP0_DP_DB_CNTL, DP_DB_DISABLE, mask_sh),\
264 SE_SF(DP0_DP_MSA_COLORIMETRY, DP_MSA_MISC0, mask_sh),\
265 SE_SF(DP0_DP_MSA_TIMING_PARAM1, DP_MSA_HTOTAL, mask_sh),\
266 SE_SF(DP0_DP_MSA_TIMING_PARAM1, DP_MSA_VTOTAL, mask_sh),\
267 SE_SF(DP0_DP_MSA_TIMING_PARAM2, DP_MSA_HSTART, mask_sh),\
268 SE_SF(DP0_DP_MSA_TIMING_PARAM2, DP_MSA_VSTART, mask_sh),\
269 SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_HSYNCWIDTH, mask_sh),\
270 SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_HSYNCPOLARITY, mask_sh),\
271 SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_VSYNCWIDTH, mask_sh),\
272 SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_VSYNCPOLARITY, mask_sh),\
273 SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_HWIDTH, mask_sh),\
274 SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_VHEIGHT, mask_sh),\
275 SE_SF(DIG0_HDMI_DB_CONTROL, HDMI_DB_DISABLE, mask_sh),\
276 SE_SF(DP0_DP_VID_TIMING, DP_VID_N_MUL, mask_sh)
277
278#define SE_COMMON_MASK_SH_LIST_SOC(mask_sh)\
279 SE_COMMON_MASK_SH_LIST_SOC_BASE(mask_sh)
280
281#define SE_COMMON_MASK_SH_LIST_DCN10(mask_sh)\
282 SE_COMMON_MASK_SH_LIST_SOC(mask_sh),\
283 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_CONT, mask_sh),\
284 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_SEND, mask_sh),\
285 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_LINE, mask_sh),\
286 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_CONT, mask_sh),\
287 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_SEND, mask_sh),\
288 SE_SF(DIG0_HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_LINE, mask_sh)
289
290
291#define SE_REG_FIELD_LIST_DCN1_0(type) \
292 type AFMT_GENERIC_INDEX;\
293 type AFMT_GENERIC_HB0;\
294 type AFMT_GENERIC_HB1;\
295 type AFMT_GENERIC_HB2;\
296 type AFMT_GENERIC_HB3;\
297 type AFMT_GENERIC_LOCK_STATUS;\
298 type AFMT_GENERIC_CONFLICT;\
299 type AFMT_GENERIC_CONFLICT_CLR;\
300 type AFMT_GENERIC0_FRAME_UPDATE_PENDING;\
301 type AFMT_GENERIC1_FRAME_UPDATE_PENDING;\
302 type AFMT_GENERIC2_FRAME_UPDATE_PENDING;\
303 type AFMT_GENERIC3_FRAME_UPDATE_PENDING;\
304 type AFMT_GENERIC4_FRAME_UPDATE_PENDING;\
305 type AFMT_GENERIC5_FRAME_UPDATE_PENDING;\
306 type AFMT_GENERIC6_FRAME_UPDATE_PENDING;\
307 type AFMT_GENERIC7_FRAME_UPDATE_PENDING;\
308 type AFMT_GENERIC0_FRAME_UPDATE;\
309 type AFMT_GENERIC1_FRAME_UPDATE;\
310 type AFMT_GENERIC2_FRAME_UPDATE;\
311 type AFMT_GENERIC3_FRAME_UPDATE;\
312 type AFMT_GENERIC4_FRAME_UPDATE;\
313 type AFMT_GENERIC5_FRAME_UPDATE;\
314 type AFMT_GENERIC6_FRAME_UPDATE;\
315 type AFMT_GENERIC7_FRAME_UPDATE;\
316 type HDMI_GENERIC0_CONT;\
317 type HDMI_GENERIC0_SEND;\
318 type HDMI_GENERIC0_LINE;\
319 type HDMI_GENERIC1_CONT;\
320 type HDMI_GENERIC1_SEND;\
321 type HDMI_GENERIC1_LINE;\
322 type HDMI_GENERIC2_CONT;\
323 type HDMI_GENERIC2_SEND;\
324 type HDMI_GENERIC2_LINE;\
325 type HDMI_GENERIC3_CONT;\
326 type HDMI_GENERIC3_SEND;\
327 type HDMI_GENERIC3_LINE;\
328 type HDMI_GENERIC4_CONT;\
329 type HDMI_GENERIC4_SEND;\
330 type HDMI_GENERIC4_LINE;\
331 type HDMI_GENERIC5_CONT;\
332 type HDMI_GENERIC5_SEND;\
333 type HDMI_GENERIC5_LINE;\
334 type HDMI_GENERIC6_CONT;\
335 type HDMI_GENERIC6_SEND;\
336 type HDMI_GENERIC6_LINE;\
337 type HDMI_GENERIC7_CONT;\
338 type HDMI_GENERIC7_SEND;\
339 type HDMI_GENERIC7_LINE;\
340 type DP_PIXEL_ENCODING;\
341 type DP_COMPONENT_DEPTH;\
342 type HDMI_PACKET_GEN_VERSION;\
343 type HDMI_KEEPOUT_MODE;\
344 type HDMI_DEEP_COLOR_ENABLE;\
345 type HDMI_CLOCK_CHANNEL_RATE;\
346 type HDMI_DEEP_COLOR_DEPTH;\
347 type HDMI_GC_CONT;\
348 type HDMI_GC_SEND;\
349 type HDMI_NULL_SEND;\
350 type HDMI_DATA_SCRAMBLE_EN;\
351 type HDMI_AUDIO_INFO_SEND;\
352 type AFMT_AUDIO_INFO_UPDATE;\
353 type HDMI_AUDIO_INFO_LINE;\
354 type HDMI_GC_AVMUTE;\
355 type DP_MSE_RATE_X;\
356 type DP_MSE_RATE_Y;\
357 type DP_MSE_RATE_UPDATE_PENDING;\
358 type DP_SEC_GSP0_ENABLE;\
359 type DP_SEC_STREAM_ENABLE;\
360 type DP_SEC_GSP1_ENABLE;\
361 type DP_SEC_GSP2_ENABLE;\
362 type DP_SEC_GSP3_ENABLE;\
363 type DP_SEC_GSP4_ENABLE;\
364 type DP_SEC_GSP5_ENABLE;\
365 type DP_SEC_GSP6_ENABLE;\
366 type DP_SEC_GSP7_ENABLE;\
367 type DP_SEC_MPG_ENABLE;\
368 type DP_VID_STREAM_DIS_DEFER;\
369 type DP_VID_STREAM_ENABLE;\
370 type DP_VID_STREAM_STATUS;\
371 type DP_STEER_FIFO_RESET;\
372 type DP_VID_M_N_GEN_EN;\
373 type DP_VID_N;\
374 type DP_VID_M;\
375 type DIG_START;\
376 type AFMT_AUDIO_SRC_SELECT;\
377 type AFMT_AUDIO_CHANNEL_ENABLE;\
378 type HDMI_AUDIO_PACKETS_PER_LINE;\
379 type HDMI_AUDIO_DELAY_EN;\
380 type AFMT_60958_CS_UPDATE;\
381 type AFMT_AUDIO_LAYOUT_OVRD;\
382 type AFMT_60958_OSF_OVRD;\
383 type HDMI_ACR_AUTO_SEND;\
384 type HDMI_ACR_SOURCE;\
385 type HDMI_ACR_AUDIO_PRIORITY;\
386 type HDMI_ACR_CTS_32;\
387 type HDMI_ACR_N_32;\
388 type HDMI_ACR_CTS_44;\
389 type HDMI_ACR_N_44;\
390 type HDMI_ACR_CTS_48;\
391 type HDMI_ACR_N_48;\
392 type AFMT_60958_CS_CHANNEL_NUMBER_L;\
393 type AFMT_60958_CS_CLOCK_ACCURACY;\
394 type AFMT_60958_CS_CHANNEL_NUMBER_R;\
395 type AFMT_60958_CS_CHANNEL_NUMBER_2;\
396 type AFMT_60958_CS_CHANNEL_NUMBER_3;\
397 type AFMT_60958_CS_CHANNEL_NUMBER_4;\
398 type AFMT_60958_CS_CHANNEL_NUMBER_5;\
399 type AFMT_60958_CS_CHANNEL_NUMBER_6;\
400 type AFMT_60958_CS_CHANNEL_NUMBER_7;\
401 type DP_SEC_AUD_N;\
402 type DP_SEC_TIMESTAMP_MODE;\
403 type DP_SEC_ASP_ENABLE;\
404 type DP_SEC_ATP_ENABLE;\
405 type DP_SEC_AIP_ENABLE;\
406 type DP_SEC_ACM_ENABLE;\
407 type AFMT_AUDIO_SAMPLE_SEND;\
408 type AFMT_AUDIO_CLOCK_EN;\
409 type TMDS_PIXEL_ENCODING;\
410 type TMDS_COLOR_FORMAT;\
411 type DIG_STEREOSYNC_SELECT;\
412 type DIG_STEREOSYNC_GATE_EN;\
413 type DP_DB_DISABLE;\
414 type DP_MSA_MISC0;\
415 type DP_MSA_HTOTAL;\
416 type DP_MSA_VTOTAL;\
417 type DP_MSA_HSTART;\
418 type DP_MSA_VSTART;\
419 type DP_MSA_HSYNCWIDTH;\
420 type DP_MSA_HSYNCPOLARITY;\
421 type DP_MSA_VSYNCWIDTH;\
422 type DP_MSA_VSYNCPOLARITY;\
423 type DP_MSA_HWIDTH;\
424 type DP_MSA_VHEIGHT;\
425 type HDMI_DB_DISABLE;\
426 type DP_VID_N_MUL;\
427 type DP_VID_M_DOUBLE_VALUE_EN
428
429struct dcn10_stream_encoder_shift {
430 SE_REG_FIELD_LIST_DCN1_0(uint8_t);
431};
432
433struct dcn10_stream_encoder_mask {
434 SE_REG_FIELD_LIST_DCN1_0(uint32_t);
435};
436
437struct dcn10_stream_encoder {
438 struct stream_encoder base;
439 const struct dcn10_stream_enc_registers *regs;
440 const struct dcn10_stream_encoder_shift *se_shift;
441 const struct dcn10_stream_encoder_mask *se_mask;
442};
443
444void dcn10_stream_encoder_construct(
445 struct dcn10_stream_encoder *enc1,
446 struct dc_context *ctx,
447 struct dc_bios *bp,
448 enum engine_id eng_id,
449 const struct dcn10_stream_enc_registers *regs,
450 const struct dcn10_stream_encoder_shift *se_shift,
451 const struct dcn10_stream_encoder_mask *se_mask);
452
453void enc1_update_generic_info_packet(
454 struct dcn10_stream_encoder *enc1,
455 uint32_t packet_index,
456 const struct dc_info_packet *info_packet);
457
458void enc1_stream_encoder_dp_set_stream_attribute(
459 struct stream_encoder *enc,
460 struct dc_crtc_timing *crtc_timing,
461 enum dc_color_space output_color_space);
462
463void enc1_stream_encoder_hdmi_set_stream_attribute(
464 struct stream_encoder *enc,
465 struct dc_crtc_timing *crtc_timing,
466 int actual_pix_clk_khz,
467 bool enable_audio);
468
469void enc1_stream_encoder_dvi_set_stream_attribute(
470 struct stream_encoder *enc,
471 struct dc_crtc_timing *crtc_timing,
472 bool is_dual_link);
473
474void enc1_stream_encoder_set_mst_bandwidth(
475 struct stream_encoder *enc,
476 struct fixed31_32 avg_time_slots_per_mtp);
477
478void enc1_stream_encoder_update_dp_info_packets(
479 struct stream_encoder *enc,
480 const struct encoder_info_frame *info_frame);
481
482void enc1_stream_encoder_stop_dp_info_packets(
483 struct stream_encoder *enc);
484
485void enc1_stream_encoder_dp_blank(
486 struct stream_encoder *enc);
487
488void enc1_stream_encoder_dp_unblank(
489 struct stream_encoder *enc,
490 const struct encoder_unblank_param *param);
491
492void enc1_setup_stereo_sync(
493 struct stream_encoder *enc,
494 int tg_inst, bool enable);
495
496void enc1_stream_encoder_set_avmute(
497 struct stream_encoder *enc,
498 bool enable);
499
500void enc1_se_audio_mute_control(
501 struct stream_encoder *enc,
502 bool mute);
503
504void enc1_se_dp_audio_setup(
505 struct stream_encoder *enc,
506 unsigned int az_inst,
507 struct audio_info *info);
508
509void enc1_se_dp_audio_enable(
510 struct stream_encoder *enc);
511
512void enc1_se_dp_audio_disable(
513 struct stream_encoder *enc);
514
515void enc1_se_hdmi_audio_setup(
516 struct stream_encoder *enc,
517 unsigned int az_inst,
518 struct audio_info *info,
519 struct audio_crtc_info *audio_crtc_info);
520
521void enc1_se_hdmi_audio_disable(
522 struct stream_encoder *enc);
523
524#endif /* __DC_STREAM_ENCODER_DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h b/drivers/gpu/drm/amd/display/dc/dm_services.h
index 22e7ee7dcd26..4ff9b2bba178 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_services.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_services.h
@@ -341,6 +341,10 @@ bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
341 341
342unsigned long long dm_get_timestamp(struct dc_context *ctx); 342unsigned long long dm_get_timestamp(struct dc_context *ctx);
343 343
344unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx,
345 unsigned long long current_time_stamp,
346 unsigned long long last_time_stamp);
347
344/* 348/*
345 * performance tracing 349 * performance tracing
346 */ 350 */
@@ -351,10 +355,6 @@ void dm_perf_trace_timestamp(const char *func_name, unsigned int line);
351/* 355/*
352 * Debug and verification hooks 356 * Debug and verification hooks
353 */ 357 */
354bool dm_helpers_dc_conn_log(
355 struct dc_context *ctx,
356 struct log_entry *entry,
357 enum dc_log_type event);
358 358
359void dm_dtn_log_begin(struct dc_context *ctx); 359void dm_dtn_log_begin(struct dc_context *ctx);
360void dm_dtn_log_append_v(struct dc_context *ctx, const char *msg, ...); 360void dm_dtn_log_append_v(struct dc_context *ctx, const char *msg, ...);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
index b1ad3553f900..47c19f8fe7d1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
@@ -108,4 +108,17 @@ enum output_standard {
108 dm_std_uninitialized = 0, dm_std_cvtr2, dm_std_cvt 108 dm_std_uninitialized = 0, dm_std_cvtr2, dm_std_cvt
109}; 109};
110 110
111enum mpc_combine_affinity {
112 dm_mpc_always_when_possible,
113 dm_mpc_reduce_voltage,
114 dm_mpc_reduce_voltage_and_clocks
115};
116
117enum self_refresh_affinity {
118 dm_try_to_allow_self_refresh_and_mclk_switch,
119 dm_allow_self_refresh_and_mclk_switch,
120 dm_allow_self_refresh,
121 dm_neither_self_refresh_nor_mclk_switch
122};
123
111#endif 124#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
index c109b2c34c8f..fd9d97aab071 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
@@ -26,75 +26,89 @@
26#include "display_mode_lib.h" 26#include "display_mode_lib.h"
27#include "dc_features.h" 27#include "dc_features.h"
28 28
29static const struct _vcs_dpi_ip_params_st dcn1_0_ip = {
30 .rob_buffer_size_kbytes = 64,
31 .det_buffer_size_kbytes = 164,
32 .dpte_buffer_size_in_pte_reqs = 42,
33 .dpp_output_buffer_pixels = 2560,
34 .opp_output_buffer_lines = 1,
35 .pixel_chunk_size_kbytes = 8,
36 .pte_enable = 1,
37 .pte_chunk_size_kbytes = 2,
38 .meta_chunk_size_kbytes = 2,
39 .writeback_chunk_size_kbytes = 2,
40 .line_buffer_size_bits = 589824,
41 .max_line_buffer_lines = 12,
42 .IsLineBufferBppFixed = 0,
43 .LineBufferFixedBpp = -1,
44 .writeback_luma_buffer_size_kbytes = 12,
45 .writeback_chroma_buffer_size_kbytes = 8,
46 .max_num_dpp = 4,
47 .max_num_wb = 2,
48 .max_dchub_pscl_bw_pix_per_clk = 4,
49 .max_pscl_lb_bw_pix_per_clk = 2,
50 .max_lb_vscl_bw_pix_per_clk = 4,
51 .max_vscl_hscl_bw_pix_per_clk = 4,
52 .max_hscl_ratio = 4,
53 .max_vscl_ratio = 4,
54 .hscl_mults = 4,
55 .vscl_mults = 4,
56 .max_hscl_taps = 8,
57 .max_vscl_taps = 8,
58 .dispclk_ramp_margin_percent = 1,
59 .underscan_factor = 1.10,
60 .min_vblank_lines = 14,
61 .dppclk_delay_subtotal = 90,
62 .dispclk_delay_subtotal = 42,
63 .dcfclk_cstate_latency = 10,
64 .max_inter_dcn_tile_repeaters = 8,
65 .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = 0,
66 .bug_forcing_LC_req_same_size_fixed = 0,
67};
68
69static const struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc = {
70 .sr_exit_time_us = 9.0,
71 .sr_enter_plus_exit_time_us = 11.0,
72 .urgent_latency_us = 4.0,
73 .writeback_latency_us = 12.0,
74 .ideal_dram_bw_after_urgent_percent = 80.0,
75 .max_request_size_bytes = 256,
76 .downspread_percent = 0.5,
77 .dram_page_open_time_ns = 50.0,
78 .dram_rw_turnaround_time_ns = 17.5,
79 .dram_return_buffer_per_channel_bytes = 8192,
80 .round_trip_ping_latency_dcfclk_cycles = 128,
81 .urgent_out_of_order_return_per_channel_bytes = 256,
82 .channel_interleave_bytes = 256,
83 .num_banks = 8,
84 .num_chans = 2,
85 .vmm_page_size_bytes = 4096,
86 .dram_clock_change_latency_us = 17.0,
87 .writeback_dram_clock_change_latency_us = 23.0,
88 .return_bus_width_bytes = 64,
89};
90
29static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project) 91static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project)
30{ 92{
31 if (project == DML_PROJECT_RAVEN1) { 93 switch (project) {
32 soc->sr_exit_time_us = 9.0; 94 case DML_PROJECT_RAVEN1:
33 soc->sr_enter_plus_exit_time_us = 11.0; 95 *soc = dcn1_0_soc;
34 soc->urgent_latency_us = 4.0; 96 break;
35 soc->writeback_latency_us = 12.0; 97 default:
36 soc->ideal_dram_bw_after_urgent_percent = 80.0; 98 ASSERT(0);
37 soc->max_request_size_bytes = 256; 99 break;
38 soc->downspread_percent = 0.5;
39 soc->dram_page_open_time_ns = 50.0;
40 soc->dram_rw_turnaround_time_ns = 17.5;
41 soc->dram_return_buffer_per_channel_bytes = 8192;
42 soc->round_trip_ping_latency_dcfclk_cycles = 128;
43 soc->urgent_out_of_order_return_per_channel_bytes = 256;
44 soc->channel_interleave_bytes = 256;
45 soc->num_banks = 8;
46 soc->num_chans = 2;
47 soc->vmm_page_size_bytes = 4096;
48 soc->dram_clock_change_latency_us = 17.0;
49 soc->writeback_dram_clock_change_latency_us = 23.0;
50 soc->return_bus_width_bytes = 64;
51 } else {
52 BREAK_TO_DEBUGGER(); /* Invalid Project Specified */
53 } 100 }
54} 101}
55 102
56static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project project) 103static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project project)
57{ 104{
58 if (project == DML_PROJECT_RAVEN1) { 105 switch (project) {
59 ip->rob_buffer_size_kbytes = 64; 106 case DML_PROJECT_RAVEN1:
60 ip->det_buffer_size_kbytes = 164; 107 *ip = dcn1_0_ip;
61 ip->dpte_buffer_size_in_pte_reqs = 42; 108 break;
62 ip->dpp_output_buffer_pixels = 2560; 109 default:
63 ip->opp_output_buffer_lines = 1; 110 ASSERT(0);
64 ip->pixel_chunk_size_kbytes = 8; 111 break;
65 ip->pte_enable = 1;
66 ip->pte_chunk_size_kbytes = 2;
67 ip->meta_chunk_size_kbytes = 2;
68 ip->writeback_chunk_size_kbytes = 2;
69 ip->line_buffer_size_bits = 589824;
70 ip->max_line_buffer_lines = 12;
71 ip->IsLineBufferBppFixed = 0;
72 ip->LineBufferFixedBpp = -1;
73 ip->writeback_luma_buffer_size_kbytes = 12;
74 ip->writeback_chroma_buffer_size_kbytes = 8;
75 ip->max_num_dpp = 4;
76 ip->max_num_wb = 2;
77 ip->max_dchub_pscl_bw_pix_per_clk = 4;
78 ip->max_pscl_lb_bw_pix_per_clk = 2;
79 ip->max_lb_vscl_bw_pix_per_clk = 4;
80 ip->max_vscl_hscl_bw_pix_per_clk = 4;
81 ip->max_hscl_ratio = 4;
82 ip->max_vscl_ratio = 4;
83 ip->hscl_mults = 4;
84 ip->vscl_mults = 4;
85 ip->max_hscl_taps = 8;
86 ip->max_vscl_taps = 8;
87 ip->dispclk_ramp_margin_percent = 1;
88 ip->underscan_factor = 1.10;
89 ip->min_vblank_lines = 14;
90 ip->dppclk_delay_subtotal = 90;
91 ip->dispclk_delay_subtotal = 42;
92 ip->dcfclk_cstate_latency = 10;
93 ip->max_inter_dcn_tile_repeaters = 8;
94 ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = 0;
95 ip->bug_forcing_LC_req_same_size_fixed = 0;
96 } else {
97 BREAK_TO_DEBUGGER(); /* Invalid Project Specified */
98 } 112 }
99} 113}
100 114
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
index 09affa16cc43..7fa0375939ae 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
@@ -25,39 +25,39 @@
25#ifndef __DISPLAY_MODE_STRUCTS_H__ 25#ifndef __DISPLAY_MODE_STRUCTS_H__
26#define __DISPLAY_MODE_STRUCTS_H__ 26#define __DISPLAY_MODE_STRUCTS_H__
27 27
28typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st; 28typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st;
29typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st; 29typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st;
30typedef struct _vcs_dpi_ip_params_st ip_params_st; 30typedef struct _vcs_dpi_ip_params_st ip_params_st;
31typedef struct _vcs_dpi_display_pipe_source_params_st display_pipe_source_params_st; 31typedef struct _vcs_dpi_display_pipe_source_params_st display_pipe_source_params_st;
32typedef struct _vcs_dpi_display_output_params_st display_output_params_st; 32typedef struct _vcs_dpi_display_output_params_st display_output_params_st;
33typedef struct _vcs_dpi_display_bandwidth_st display_bandwidth_st; 33typedef struct _vcs_dpi_display_bandwidth_st display_bandwidth_st;
34typedef struct _vcs_dpi_scaler_ratio_depth_st scaler_ratio_depth_st; 34typedef struct _vcs_dpi_scaler_ratio_depth_st scaler_ratio_depth_st;
35typedef struct _vcs_dpi_scaler_taps_st scaler_taps_st; 35typedef struct _vcs_dpi_scaler_taps_st scaler_taps_st;
36typedef struct _vcs_dpi_display_pipe_dest_params_st display_pipe_dest_params_st; 36typedef struct _vcs_dpi_display_pipe_dest_params_st display_pipe_dest_params_st;
37typedef struct _vcs_dpi_display_pipe_params_st display_pipe_params_st; 37typedef struct _vcs_dpi_display_pipe_params_st display_pipe_params_st;
38typedef struct _vcs_dpi_display_clocks_and_cfg_st display_clocks_and_cfg_st; 38typedef struct _vcs_dpi_display_clocks_and_cfg_st display_clocks_and_cfg_st;
39typedef struct _vcs_dpi_display_e2e_pipe_params_st display_e2e_pipe_params_st; 39typedef struct _vcs_dpi_display_e2e_pipe_params_st display_e2e_pipe_params_st;
40typedef struct _vcs_dpi_dchub_buffer_sizing_st dchub_buffer_sizing_st; 40typedef struct _vcs_dpi_dchub_buffer_sizing_st dchub_buffer_sizing_st;
41typedef struct _vcs_dpi_watermarks_perf_st watermarks_perf_st; 41typedef struct _vcs_dpi_watermarks_perf_st watermarks_perf_st;
42typedef struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_watermarks_st; 42typedef struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_watermarks_st;
43typedef struct _vcs_dpi_wm_calc_pipe_params_st wm_calc_pipe_params_st; 43typedef struct _vcs_dpi_wm_calc_pipe_params_st wm_calc_pipe_params_st;
44typedef struct _vcs_dpi_vratio_pre_st vratio_pre_st; 44typedef struct _vcs_dpi_vratio_pre_st vratio_pre_st;
45typedef struct _vcs_dpi_display_data_rq_misc_params_st display_data_rq_misc_params_st; 45typedef struct _vcs_dpi_display_data_rq_misc_params_st display_data_rq_misc_params_st;
46typedef struct _vcs_dpi_display_data_rq_sizing_params_st display_data_rq_sizing_params_st; 46typedef struct _vcs_dpi_display_data_rq_sizing_params_st display_data_rq_sizing_params_st;
47typedef struct _vcs_dpi_display_data_rq_dlg_params_st display_data_rq_dlg_params_st; 47typedef struct _vcs_dpi_display_data_rq_dlg_params_st display_data_rq_dlg_params_st;
48typedef struct _vcs_dpi_display_cur_rq_dlg_params_st display_cur_rq_dlg_params_st; 48typedef struct _vcs_dpi_display_cur_rq_dlg_params_st display_cur_rq_dlg_params_st;
49typedef struct _vcs_dpi_display_rq_dlg_params_st display_rq_dlg_params_st; 49typedef struct _vcs_dpi_display_rq_dlg_params_st display_rq_dlg_params_st;
50typedef struct _vcs_dpi_display_rq_sizing_params_st display_rq_sizing_params_st; 50typedef struct _vcs_dpi_display_rq_sizing_params_st display_rq_sizing_params_st;
51typedef struct _vcs_dpi_display_rq_misc_params_st display_rq_misc_params_st; 51typedef struct _vcs_dpi_display_rq_misc_params_st display_rq_misc_params_st;
52typedef struct _vcs_dpi_display_rq_params_st display_rq_params_st; 52typedef struct _vcs_dpi_display_rq_params_st display_rq_params_st;
53typedef struct _vcs_dpi_display_dlg_regs_st display_dlg_regs_st; 53typedef struct _vcs_dpi_display_dlg_regs_st display_dlg_regs_st;
54typedef struct _vcs_dpi_display_ttu_regs_st display_ttu_regs_st; 54typedef struct _vcs_dpi_display_ttu_regs_st display_ttu_regs_st;
55typedef struct _vcs_dpi_display_data_rq_regs_st display_data_rq_regs_st; 55typedef struct _vcs_dpi_display_data_rq_regs_st display_data_rq_regs_st;
56typedef struct _vcs_dpi_display_rq_regs_st display_rq_regs_st; 56typedef struct _vcs_dpi_display_rq_regs_st display_rq_regs_st;
57typedef struct _vcs_dpi_display_dlg_sys_params_st display_dlg_sys_params_st; 57typedef struct _vcs_dpi_display_dlg_sys_params_st display_dlg_sys_params_st;
58typedef struct _vcs_dpi_display_dlg_prefetch_param_st display_dlg_prefetch_param_st; 58typedef struct _vcs_dpi_display_dlg_prefetch_param_st display_dlg_prefetch_param_st;
59typedef struct _vcs_dpi_display_pipe_clock_st display_pipe_clock_st; 59typedef struct _vcs_dpi_display_pipe_clock_st display_pipe_clock_st;
60typedef struct _vcs_dpi_display_arb_params_st display_arb_params_st; 60typedef struct _vcs_dpi_display_arb_params_st display_arb_params_st;
61 61
62struct _vcs_dpi_voltage_scaling_st { 62struct _vcs_dpi_voltage_scaling_st {
63 int state; 63 int state;
@@ -72,89 +72,107 @@ struct _vcs_dpi_voltage_scaling_st {
72 double dppclk_mhz; 72 double dppclk_mhz;
73}; 73};
74 74
75struct _vcs_dpi_soc_bounding_box_st { 75struct _vcs_dpi_soc_bounding_box_st {
76 double sr_exit_time_us; 76 double sr_exit_time_us;
77 double sr_enter_plus_exit_time_us; 77 double sr_enter_plus_exit_time_us;
78 double urgent_latency_us; 78 double urgent_latency_us;
79 double writeback_latency_us; 79 double urgent_latency_pixel_data_only_us;
80 double ideal_dram_bw_after_urgent_percent; 80 double urgent_latency_pixel_mixed_with_vm_data_us;
81 unsigned int max_request_size_bytes; 81 double urgent_latency_vm_data_only_us;
82 double downspread_percent; 82 double writeback_latency_us;
83 double dram_page_open_time_ns; 83 double ideal_dram_bw_after_urgent_percent;
84 double dram_rw_turnaround_time_ns; 84 double pct_ideal_dram_sdp_bw_after_urgent_pixel_only; // PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly
85 double dram_return_buffer_per_channel_bytes; 85 double pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
86 double dram_channel_width_bytes; 86 double pct_ideal_dram_sdp_bw_after_urgent_vm_only;
87 double max_avg_sdp_bw_use_normal_percent;
88 double max_avg_dram_bw_use_normal_percent;
89 unsigned int max_request_size_bytes;
90 double downspread_percent;
91 double dram_page_open_time_ns;
92 double dram_rw_turnaround_time_ns;
93 double dram_return_buffer_per_channel_bytes;
94 double dram_channel_width_bytes;
87 double fabric_datapath_to_dcn_data_return_bytes; 95 double fabric_datapath_to_dcn_data_return_bytes;
88 double dcn_downspread_percent; 96 double dcn_downspread_percent;
89 double dispclk_dppclk_vco_speed_mhz; 97 double dispclk_dppclk_vco_speed_mhz;
90 double dfs_vco_period_ps; 98 double dfs_vco_period_ps;
91 unsigned int round_trip_ping_latency_dcfclk_cycles; 99 unsigned int urgent_out_of_order_return_per_channel_pixel_only_bytes;
92 unsigned int urgent_out_of_order_return_per_channel_bytes; 100 unsigned int urgent_out_of_order_return_per_channel_pixel_and_vm_bytes;
93 unsigned int channel_interleave_bytes; 101 unsigned int urgent_out_of_order_return_per_channel_vm_only_bytes;
94 unsigned int num_banks; 102 unsigned int round_trip_ping_latency_dcfclk_cycles;
95 unsigned int num_chans; 103 unsigned int urgent_out_of_order_return_per_channel_bytes;
96 unsigned int vmm_page_size_bytes; 104 unsigned int channel_interleave_bytes;
97 double dram_clock_change_latency_us; 105 unsigned int num_banks;
98 double writeback_dram_clock_change_latency_us; 106 unsigned int num_chans;
99 unsigned int return_bus_width_bytes; 107 unsigned int vmm_page_size_bytes;
100 unsigned int voltage_override; 108 double dram_clock_change_latency_us;
101 double xfc_bus_transport_time_us; 109 double writeback_dram_clock_change_latency_us;
102 double xfc_xbuf_latency_tolerance_us; 110 unsigned int return_bus_width_bytes;
111 unsigned int voltage_override;
112 double xfc_bus_transport_time_us;
113 double xfc_xbuf_latency_tolerance_us;
114 int use_urgent_burst_bw;
103 struct _vcs_dpi_voltage_scaling_st clock_limits[7]; 115 struct _vcs_dpi_voltage_scaling_st clock_limits[7];
104}; 116};
105 117
106struct _vcs_dpi_ip_params_st { 118struct _vcs_dpi_ip_params_st {
107 unsigned int max_inter_dcn_tile_repeaters; 119 bool gpuvm_enable;
108 unsigned int num_dsc; 120 bool hostvm_enable;
109 unsigned int odm_capable; 121 unsigned int gpuvm_max_page_table_levels;
110 unsigned int rob_buffer_size_kbytes; 122 unsigned int hostvm_max_page_table_levels;
111 unsigned int det_buffer_size_kbytes; 123 unsigned int hostvm_cached_page_table_levels;
112 unsigned int dpte_buffer_size_in_pte_reqs; 124 unsigned int pte_group_size_bytes;
113 unsigned int pde_proc_buffer_size_64k_reqs; 125 unsigned int max_inter_dcn_tile_repeaters;
114 unsigned int dpp_output_buffer_pixels; 126 unsigned int num_dsc;
115 unsigned int opp_output_buffer_lines; 127 unsigned int odm_capable;
116 unsigned int pixel_chunk_size_kbytes; 128 unsigned int rob_buffer_size_kbytes;
117 unsigned char pte_enable; 129 unsigned int det_buffer_size_kbytes;
118 unsigned int pte_chunk_size_kbytes; 130 unsigned int dpte_buffer_size_in_pte_reqs;
119 unsigned int meta_chunk_size_kbytes; 131 unsigned int pde_proc_buffer_size_64k_reqs;
120 unsigned int writeback_chunk_size_kbytes; 132 unsigned int dpp_output_buffer_pixels;
121 unsigned int line_buffer_size_bits; 133 unsigned int opp_output_buffer_lines;
122 unsigned int max_line_buffer_lines; 134 unsigned int pixel_chunk_size_kbytes;
123 unsigned int writeback_luma_buffer_size_kbytes; 135 unsigned char pte_enable;
124 unsigned int writeback_chroma_buffer_size_kbytes; 136 unsigned int pte_chunk_size_kbytes;
125 unsigned int writeback_chroma_line_buffer_width_pixels; 137 unsigned int meta_chunk_size_kbytes;
126 unsigned int max_page_table_levels; 138 unsigned int writeback_chunk_size_kbytes;
127 unsigned int max_num_dpp; 139 unsigned int line_buffer_size_bits;
128 unsigned int max_num_otg; 140 unsigned int max_line_buffer_lines;
129 unsigned int cursor_chunk_size; 141 unsigned int writeback_luma_buffer_size_kbytes;
130 unsigned int cursor_buffer_size; 142 unsigned int writeback_chroma_buffer_size_kbytes;
131 unsigned int max_num_wb; 143 unsigned int writeback_chroma_line_buffer_width_pixels;
132 unsigned int max_dchub_pscl_bw_pix_per_clk; 144 unsigned int max_page_table_levels;
133 unsigned int max_pscl_lb_bw_pix_per_clk; 145 unsigned int max_num_dpp;
134 unsigned int max_lb_vscl_bw_pix_per_clk; 146 unsigned int max_num_otg;
135 unsigned int max_vscl_hscl_bw_pix_per_clk; 147 unsigned int cursor_chunk_size;
136 double max_hscl_ratio; 148 unsigned int cursor_buffer_size;
137 double max_vscl_ratio; 149 unsigned int max_num_wb;
138 unsigned int hscl_mults; 150 unsigned int max_dchub_pscl_bw_pix_per_clk;
139 unsigned int vscl_mults; 151 unsigned int max_pscl_lb_bw_pix_per_clk;
140 unsigned int max_hscl_taps; 152 unsigned int max_lb_vscl_bw_pix_per_clk;
141 unsigned int max_vscl_taps; 153 unsigned int max_vscl_hscl_bw_pix_per_clk;
142 unsigned int xfc_supported; 154 double max_hscl_ratio;
143 unsigned int xfc_fill_constant_bytes; 155 double max_vscl_ratio;
144 double dispclk_ramp_margin_percent; 156 unsigned int hscl_mults;
145 double xfc_fill_bw_overhead_percent; 157 unsigned int vscl_mults;
146 double underscan_factor; 158 unsigned int max_hscl_taps;
147 unsigned int min_vblank_lines; 159 unsigned int max_vscl_taps;
148 unsigned int dppclk_delay_subtotal; 160 unsigned int xfc_supported;
149 unsigned int dispclk_delay_subtotal; 161 unsigned int xfc_fill_constant_bytes;
150 unsigned int dcfclk_cstate_latency; 162 double dispclk_ramp_margin_percent;
151 unsigned int dppclk_delay_scl; 163 double xfc_fill_bw_overhead_percent;
152 unsigned int dppclk_delay_scl_lb_only; 164 double underscan_factor;
153 unsigned int dppclk_delay_cnvc_formatter; 165 unsigned int min_vblank_lines;
154 unsigned int dppclk_delay_cnvc_cursor; 166 unsigned int dppclk_delay_subtotal;
155 unsigned int is_line_buffer_bpp_fixed; 167 unsigned int dispclk_delay_subtotal;
156 unsigned int line_buffer_fixed_bpp; 168 unsigned int dcfclk_cstate_latency;
157 unsigned int dcc_supported; 169 unsigned int dppclk_delay_scl;
170 unsigned int dppclk_delay_scl_lb_only;
171 unsigned int dppclk_delay_cnvc_formatter;
172 unsigned int dppclk_delay_cnvc_cursor;
173 unsigned int is_line_buffer_bpp_fixed;
174 unsigned int line_buffer_fixed_bpp;
175 unsigned int dcc_supported;
158 176
159 unsigned int IsLineBufferBppFixed; 177 unsigned int IsLineBufferBppFixed;
160 unsigned int LineBufferFixedBpp; 178 unsigned int LineBufferFixedBpp;
@@ -169,41 +187,45 @@ struct _vcs_dpi_display_xfc_params_st {
169 int xfc_slv_chunk_size_bytes; 187 int xfc_slv_chunk_size_bytes;
170}; 188};
171 189
172struct _vcs_dpi_display_pipe_source_params_st { 190struct _vcs_dpi_display_pipe_source_params_st {
173 int source_format; 191 int source_format;
174 unsigned char dcc; 192 unsigned char dcc;
175 unsigned int dcc_override; 193 unsigned int dcc_override;
176 unsigned int dcc_rate; 194 unsigned int dcc_rate;
177 unsigned char dcc_use_global; 195 unsigned char dcc_use_global;
178 unsigned char vm; 196 unsigned char vm;
179 unsigned char vm_levels_force_en; 197 bool gpuvm; // gpuvm enabled
180 unsigned int vm_levels_force; 198 bool hostvm; // hostvm enabled
181 int source_scan; 199 bool gpuvm_levels_force_en;
182 int sw_mode; 200 unsigned int gpuvm_levels_force;
183 int macro_tile_size; 201 bool hostvm_levels_force_en;
184 unsigned char is_display_sw; 202 unsigned int hostvm_levels_force;
185 unsigned int viewport_width; 203 int source_scan;
186 unsigned int viewport_height; 204 int sw_mode;
187 unsigned int viewport_y_y; 205 int macro_tile_size;
188 unsigned int viewport_y_c; 206 unsigned char is_display_sw;
189 unsigned int viewport_width_c; 207 unsigned int viewport_width;
190 unsigned int viewport_height_c; 208 unsigned int viewport_height;
191 unsigned int data_pitch; 209 unsigned int viewport_y_y;
192 unsigned int data_pitch_c; 210 unsigned int viewport_y_c;
193 unsigned int meta_pitch; 211 unsigned int viewport_width_c;
194 unsigned int meta_pitch_c; 212 unsigned int viewport_height_c;
195 unsigned int cur0_src_width; 213 unsigned int data_pitch;
196 int cur0_bpp; 214 unsigned int data_pitch_c;
197 unsigned int cur1_src_width; 215 unsigned int meta_pitch;
198 int cur1_bpp; 216 unsigned int meta_pitch_c;
199 int num_cursors; 217 unsigned int cur0_src_width;
200 unsigned char is_hsplit; 218 int cur0_bpp;
201 unsigned char dynamic_metadata_enable; 219 unsigned int cur1_src_width;
202 unsigned int dynamic_metadata_lines_before_active; 220 int cur1_bpp;
203 unsigned int dynamic_metadata_xmit_bytes; 221 int num_cursors;
204 unsigned int hsplit_grp; 222 unsigned char is_hsplit;
205 unsigned char xfc_enable; 223 unsigned char dynamic_metadata_enable;
206 unsigned char xfc_slave; 224 unsigned int dynamic_metadata_lines_before_active;
225 unsigned int dynamic_metadata_xmit_bytes;
226 unsigned int hsplit_grp;
227 unsigned char xfc_enable;
228 unsigned char xfc_slave;
207 struct _vcs_dpi_display_xfc_params_st xfc_params; 229 struct _vcs_dpi_display_xfc_params_st xfc_params;
208}; 230};
209struct writeback_st { 231struct writeback_st {
@@ -215,338 +237,339 @@ struct writeback_st {
215 int wb_vtaps_luma; 237 int wb_vtaps_luma;
216 int wb_htaps_chroma; 238 int wb_htaps_chroma;
217 int wb_vtaps_chroma; 239 int wb_vtaps_chroma;
218 int wb_hratio; 240 double wb_hratio;
219 int wb_vratio; 241 double wb_vratio;
220}; 242};
221 243
222struct _vcs_dpi_display_output_params_st { 244struct _vcs_dpi_display_output_params_st {
223 int dp_lanes; 245 int dp_lanes;
224 int output_bpp; 246 int output_bpp;
225 int dsc_enable; 247 int dsc_enable;
226 int wb_enable; 248 int wb_enable;
227 int opp_input_bpc; 249 int num_active_wb;
228 int output_type; 250 int output_bpc;
229 int output_format; 251 int output_type;
230 int output_standard; 252 int output_format;
231 int dsc_slices; 253 int output_standard;
254 int dsc_slices;
232 struct writeback_st wb; 255 struct writeback_st wb;
233}; 256};
234 257
235struct _vcs_dpi_display_bandwidth_st { 258struct _vcs_dpi_display_bandwidth_st {
236 double total_bw_consumed_gbps; 259 double total_bw_consumed_gbps;
237 double guaranteed_urgent_return_bw_gbps; 260 double guaranteed_urgent_return_bw_gbps;
238}; 261};
239 262
240struct _vcs_dpi_scaler_ratio_depth_st { 263struct _vcs_dpi_scaler_ratio_depth_st {
241 double hscl_ratio; 264 double hscl_ratio;
242 double vscl_ratio; 265 double vscl_ratio;
243 double hscl_ratio_c; 266 double hscl_ratio_c;
244 double vscl_ratio_c; 267 double vscl_ratio_c;
245 double vinit; 268 double vinit;
246 double vinit_c; 269 double vinit_c;
247 double vinit_bot; 270 double vinit_bot;
248 double vinit_bot_c; 271 double vinit_bot_c;
249 int lb_depth; 272 int lb_depth;
250 int scl_enable; 273 int scl_enable;
251}; 274};
252 275
253struct _vcs_dpi_scaler_taps_st { 276struct _vcs_dpi_scaler_taps_st {
254 unsigned int htaps; 277 unsigned int htaps;
255 unsigned int vtaps; 278 unsigned int vtaps;
256 unsigned int htaps_c; 279 unsigned int htaps_c;
257 unsigned int vtaps_c; 280 unsigned int vtaps_c;
258}; 281};
259 282
260struct _vcs_dpi_display_pipe_dest_params_st { 283struct _vcs_dpi_display_pipe_dest_params_st {
261 unsigned int recout_width; 284 unsigned int recout_width;
262 unsigned int recout_height; 285 unsigned int recout_height;
263 unsigned int full_recout_width; 286 unsigned int full_recout_width;
264 unsigned int full_recout_height; 287 unsigned int full_recout_height;
265 unsigned int hblank_start; 288 unsigned int hblank_start;
266 unsigned int hblank_end; 289 unsigned int hblank_end;
267 unsigned int vblank_start; 290 unsigned int vblank_start;
268 unsigned int vblank_end; 291 unsigned int vblank_end;
269 unsigned int htotal; 292 unsigned int htotal;
270 unsigned int vtotal; 293 unsigned int vtotal;
271 unsigned int vactive; 294 unsigned int vactive;
272 unsigned int hactive; 295 unsigned int hactive;
273 unsigned int vstartup_start; 296 unsigned int vstartup_start;
274 unsigned int vupdate_offset; 297 unsigned int vupdate_offset;
275 unsigned int vupdate_width; 298 unsigned int vupdate_width;
276 unsigned int vready_offset; 299 unsigned int vready_offset;
277 unsigned char interlaced; 300 unsigned char interlaced;
278 unsigned char underscan; 301 unsigned char underscan;
279 double pixel_rate_mhz; 302 double pixel_rate_mhz;
280 unsigned char synchronized_vblank_all_planes; 303 unsigned char synchronized_vblank_all_planes;
281 unsigned char otg_inst; 304 unsigned char otg_inst;
282 unsigned char odm_split_cnt; 305 unsigned char odm_split_cnt;
283 unsigned char odm_combine; 306 unsigned char odm_combine;
284}; 307};
285 308
286struct _vcs_dpi_display_pipe_params_st { 309struct _vcs_dpi_display_pipe_params_st {
287 display_pipe_source_params_st src; 310 display_pipe_source_params_st src;
288 display_pipe_dest_params_st dest; 311 display_pipe_dest_params_st dest;
289 scaler_ratio_depth_st scale_ratio_depth; 312 scaler_ratio_depth_st scale_ratio_depth;
290 scaler_taps_st scale_taps; 313 scaler_taps_st scale_taps;
291}; 314};
292 315
293struct _vcs_dpi_display_clocks_and_cfg_st { 316struct _vcs_dpi_display_clocks_and_cfg_st {
294 int voltage; 317 int voltage;
295 double dppclk_mhz; 318 double dppclk_mhz;
296 double refclk_mhz; 319 double refclk_mhz;
297 double dispclk_mhz; 320 double dispclk_mhz;
298 double dcfclk_mhz; 321 double dcfclk_mhz;
299 double socclk_mhz; 322 double socclk_mhz;
300}; 323};
301 324
302struct _vcs_dpi_display_e2e_pipe_params_st { 325struct _vcs_dpi_display_e2e_pipe_params_st {
303 display_pipe_params_st pipe; 326 display_pipe_params_st pipe;
304 display_output_params_st dout; 327 display_output_params_st dout;
305 display_clocks_and_cfg_st clks_cfg; 328 display_clocks_and_cfg_st clks_cfg;
306}; 329};
307 330
308struct _vcs_dpi_dchub_buffer_sizing_st { 331struct _vcs_dpi_dchub_buffer_sizing_st {
309 unsigned int swath_width_y; 332 unsigned int swath_width_y;
310 unsigned int swath_height_y; 333 unsigned int swath_height_y;
311 unsigned int swath_height_c; 334 unsigned int swath_height_c;
312 unsigned int detail_buffer_size_y; 335 unsigned int detail_buffer_size_y;
313}; 336};
314 337
315struct _vcs_dpi_watermarks_perf_st { 338struct _vcs_dpi_watermarks_perf_st {
316 double stutter_eff_in_active_region_percent; 339 double stutter_eff_in_active_region_percent;
317 double urgent_latency_supported_us; 340 double urgent_latency_supported_us;
318 double non_urgent_latency_supported_us; 341 double non_urgent_latency_supported_us;
319 double dram_clock_change_margin_us; 342 double dram_clock_change_margin_us;
320 double dram_access_eff_percent; 343 double dram_access_eff_percent;
321}; 344};
322 345
323struct _vcs_dpi_cstate_pstate_watermarks_st { 346struct _vcs_dpi_cstate_pstate_watermarks_st {
324 double cstate_exit_us; 347 double cstate_exit_us;
325 double cstate_enter_plus_exit_us; 348 double cstate_enter_plus_exit_us;
326 double pstate_change_us; 349 double pstate_change_us;
327}; 350};
328 351
329struct _vcs_dpi_wm_calc_pipe_params_st { 352struct _vcs_dpi_wm_calc_pipe_params_st {
330 unsigned int num_dpp; 353 unsigned int num_dpp;
331 int voltage; 354 int voltage;
332 int output_type; 355 int output_type;
333 double dcfclk_mhz; 356 double dcfclk_mhz;
334 double socclk_mhz; 357 double socclk_mhz;
335 double dppclk_mhz; 358 double dppclk_mhz;
336 double pixclk_mhz; 359 double pixclk_mhz;
337 unsigned char interlace_en; 360 unsigned char interlace_en;
338 unsigned char pte_enable; 361 unsigned char pte_enable;
339 unsigned char dcc_enable; 362 unsigned char dcc_enable;
340 double dcc_rate; 363 double dcc_rate;
341 double bytes_per_pixel_c; 364 double bytes_per_pixel_c;
342 double bytes_per_pixel_y; 365 double bytes_per_pixel_y;
343 unsigned int swath_width_y; 366 unsigned int swath_width_y;
344 unsigned int swath_height_y; 367 unsigned int swath_height_y;
345 unsigned int swath_height_c; 368 unsigned int swath_height_c;
346 unsigned int det_buffer_size_y; 369 unsigned int det_buffer_size_y;
347 double h_ratio; 370 double h_ratio;
348 double v_ratio; 371 double v_ratio;
349 unsigned int h_taps; 372 unsigned int h_taps;
350 unsigned int h_total; 373 unsigned int h_total;
351 unsigned int v_total; 374 unsigned int v_total;
352 unsigned int v_active; 375 unsigned int v_active;
353 unsigned int e2e_index; 376 unsigned int e2e_index;
354 double display_pipe_line_delivery_time; 377 double display_pipe_line_delivery_time;
355 double read_bw; 378 double read_bw;
356 unsigned int lines_in_det_y; 379 unsigned int lines_in_det_y;
357 unsigned int lines_in_det_y_rounded_down_to_swath; 380 unsigned int lines_in_det_y_rounded_down_to_swath;
358 double full_det_buffering_time; 381 double full_det_buffering_time;
359 double dcfclk_deepsleep_mhz_per_plane; 382 double dcfclk_deepsleep_mhz_per_plane;
360}; 383};
361 384
362struct _vcs_dpi_vratio_pre_st { 385struct _vcs_dpi_vratio_pre_st {
363 double vratio_pre_l; 386 double vratio_pre_l;
364 double vratio_pre_c; 387 double vratio_pre_c;
365}; 388};
366 389
367struct _vcs_dpi_display_data_rq_misc_params_st { 390struct _vcs_dpi_display_data_rq_misc_params_st {
368 unsigned int full_swath_bytes; 391 unsigned int full_swath_bytes;
369 unsigned int stored_swath_bytes; 392 unsigned int stored_swath_bytes;
370 unsigned int blk256_height; 393 unsigned int blk256_height;
371 unsigned int blk256_width; 394 unsigned int blk256_width;
372 unsigned int req_height; 395 unsigned int req_height;
373 unsigned int req_width; 396 unsigned int req_width;
374}; 397};
375 398
376struct _vcs_dpi_display_data_rq_sizing_params_st { 399struct _vcs_dpi_display_data_rq_sizing_params_st {
377 unsigned int chunk_bytes; 400 unsigned int chunk_bytes;
378 unsigned int min_chunk_bytes; 401 unsigned int min_chunk_bytes;
379 unsigned int meta_chunk_bytes; 402 unsigned int meta_chunk_bytes;
380 unsigned int min_meta_chunk_bytes; 403 unsigned int min_meta_chunk_bytes;
381 unsigned int mpte_group_bytes; 404 unsigned int mpte_group_bytes;
382 unsigned int dpte_group_bytes; 405 unsigned int dpte_group_bytes;
383}; 406};
384 407
385struct _vcs_dpi_display_data_rq_dlg_params_st { 408struct _vcs_dpi_display_data_rq_dlg_params_st {
386 unsigned int swath_width_ub; 409 unsigned int swath_width_ub;
387 unsigned int swath_height; 410 unsigned int swath_height;
388 unsigned int req_per_swath_ub; 411 unsigned int req_per_swath_ub;
389 unsigned int meta_pte_bytes_per_frame_ub; 412 unsigned int meta_pte_bytes_per_frame_ub;
390 unsigned int dpte_req_per_row_ub; 413 unsigned int dpte_req_per_row_ub;
391 unsigned int dpte_groups_per_row_ub; 414 unsigned int dpte_groups_per_row_ub;
392 unsigned int dpte_row_height; 415 unsigned int dpte_row_height;
393 unsigned int dpte_bytes_per_row_ub; 416 unsigned int dpte_bytes_per_row_ub;
394 unsigned int meta_chunks_per_row_ub; 417 unsigned int meta_chunks_per_row_ub;
395 unsigned int meta_req_per_row_ub; 418 unsigned int meta_req_per_row_ub;
396 unsigned int meta_row_height; 419 unsigned int meta_row_height;
397 unsigned int meta_bytes_per_row_ub; 420 unsigned int meta_bytes_per_row_ub;
398}; 421};
399 422
400struct _vcs_dpi_display_cur_rq_dlg_params_st { 423struct _vcs_dpi_display_cur_rq_dlg_params_st {
401 unsigned char enable; 424 unsigned char enable;
402 unsigned int swath_height; 425 unsigned int swath_height;
403 unsigned int req_per_line; 426 unsigned int req_per_line;
404}; 427};
405 428
406struct _vcs_dpi_display_rq_dlg_params_st { 429struct _vcs_dpi_display_rq_dlg_params_st {
407 display_data_rq_dlg_params_st rq_l; 430 display_data_rq_dlg_params_st rq_l;
408 display_data_rq_dlg_params_st rq_c; 431 display_data_rq_dlg_params_st rq_c;
409 display_cur_rq_dlg_params_st rq_cur0; 432 display_cur_rq_dlg_params_st rq_cur0;
410}; 433};
411 434
412struct _vcs_dpi_display_rq_sizing_params_st { 435struct _vcs_dpi_display_rq_sizing_params_st {
413 display_data_rq_sizing_params_st rq_l; 436 display_data_rq_sizing_params_st rq_l;
414 display_data_rq_sizing_params_st rq_c; 437 display_data_rq_sizing_params_st rq_c;
415}; 438};
416 439
417struct _vcs_dpi_display_rq_misc_params_st { 440struct _vcs_dpi_display_rq_misc_params_st {
418 display_data_rq_misc_params_st rq_l; 441 display_data_rq_misc_params_st rq_l;
419 display_data_rq_misc_params_st rq_c; 442 display_data_rq_misc_params_st rq_c;
420}; 443};
421 444
422struct _vcs_dpi_display_rq_params_st { 445struct _vcs_dpi_display_rq_params_st {
423 unsigned char yuv420; 446 unsigned char yuv420;
424 unsigned char yuv420_10bpc; 447 unsigned char yuv420_10bpc;
425 display_rq_misc_params_st misc; 448 display_rq_misc_params_st misc;
426 display_rq_sizing_params_st sizing; 449 display_rq_sizing_params_st sizing;
427 display_rq_dlg_params_st dlg; 450 display_rq_dlg_params_st dlg;
428}; 451};
429 452
430struct _vcs_dpi_display_dlg_regs_st { 453struct _vcs_dpi_display_dlg_regs_st {
431 unsigned int refcyc_h_blank_end; 454 unsigned int refcyc_h_blank_end;
432 unsigned int dlg_vblank_end; 455 unsigned int dlg_vblank_end;
433 unsigned int min_dst_y_next_start; 456 unsigned int min_dst_y_next_start;
434 unsigned int refcyc_per_htotal; 457 unsigned int refcyc_per_htotal;
435 unsigned int refcyc_x_after_scaler; 458 unsigned int refcyc_x_after_scaler;
436 unsigned int dst_y_after_scaler; 459 unsigned int dst_y_after_scaler;
437 unsigned int dst_y_prefetch; 460 unsigned int dst_y_prefetch;
438 unsigned int dst_y_per_vm_vblank; 461 unsigned int dst_y_per_vm_vblank;
439 unsigned int dst_y_per_row_vblank; 462 unsigned int dst_y_per_row_vblank;
440 unsigned int dst_y_per_vm_flip; 463 unsigned int dst_y_per_vm_flip;
441 unsigned int dst_y_per_row_flip; 464 unsigned int dst_y_per_row_flip;
442 unsigned int ref_freq_to_pix_freq; 465 unsigned int ref_freq_to_pix_freq;
443 unsigned int vratio_prefetch; 466 unsigned int vratio_prefetch;
444 unsigned int vratio_prefetch_c; 467 unsigned int vratio_prefetch_c;
445 unsigned int refcyc_per_pte_group_vblank_l; 468 unsigned int refcyc_per_pte_group_vblank_l;
446 unsigned int refcyc_per_pte_group_vblank_c; 469 unsigned int refcyc_per_pte_group_vblank_c;
447 unsigned int refcyc_per_meta_chunk_vblank_l; 470 unsigned int refcyc_per_meta_chunk_vblank_l;
448 unsigned int refcyc_per_meta_chunk_vblank_c; 471 unsigned int refcyc_per_meta_chunk_vblank_c;
449 unsigned int refcyc_per_pte_group_flip_l; 472 unsigned int refcyc_per_pte_group_flip_l;
450 unsigned int refcyc_per_pte_group_flip_c; 473 unsigned int refcyc_per_pte_group_flip_c;
451 unsigned int refcyc_per_meta_chunk_flip_l; 474 unsigned int refcyc_per_meta_chunk_flip_l;
452 unsigned int refcyc_per_meta_chunk_flip_c; 475 unsigned int refcyc_per_meta_chunk_flip_c;
453 unsigned int dst_y_per_pte_row_nom_l; 476 unsigned int dst_y_per_pte_row_nom_l;
454 unsigned int dst_y_per_pte_row_nom_c; 477 unsigned int dst_y_per_pte_row_nom_c;
455 unsigned int refcyc_per_pte_group_nom_l; 478 unsigned int refcyc_per_pte_group_nom_l;
456 unsigned int refcyc_per_pte_group_nom_c; 479 unsigned int refcyc_per_pte_group_nom_c;
457 unsigned int dst_y_per_meta_row_nom_l; 480 unsigned int dst_y_per_meta_row_nom_l;
458 unsigned int dst_y_per_meta_row_nom_c; 481 unsigned int dst_y_per_meta_row_nom_c;
459 unsigned int refcyc_per_meta_chunk_nom_l; 482 unsigned int refcyc_per_meta_chunk_nom_l;
460 unsigned int refcyc_per_meta_chunk_nom_c; 483 unsigned int refcyc_per_meta_chunk_nom_c;
461 unsigned int refcyc_per_line_delivery_pre_l; 484 unsigned int refcyc_per_line_delivery_pre_l;
462 unsigned int refcyc_per_line_delivery_pre_c; 485 unsigned int refcyc_per_line_delivery_pre_c;
463 unsigned int refcyc_per_line_delivery_l; 486 unsigned int refcyc_per_line_delivery_l;
464 unsigned int refcyc_per_line_delivery_c; 487 unsigned int refcyc_per_line_delivery_c;
465 unsigned int chunk_hdl_adjust_cur0; 488 unsigned int chunk_hdl_adjust_cur0;
466 unsigned int chunk_hdl_adjust_cur1; 489 unsigned int chunk_hdl_adjust_cur1;
467 unsigned int vready_after_vcount0; 490 unsigned int vready_after_vcount0;
468 unsigned int dst_y_offset_cur0; 491 unsigned int dst_y_offset_cur0;
469 unsigned int dst_y_offset_cur1; 492 unsigned int dst_y_offset_cur1;
470 unsigned int xfc_reg_transfer_delay; 493 unsigned int xfc_reg_transfer_delay;
471 unsigned int xfc_reg_precharge_delay; 494 unsigned int xfc_reg_precharge_delay;
472 unsigned int xfc_reg_remote_surface_flip_latency; 495 unsigned int xfc_reg_remote_surface_flip_latency;
473 unsigned int xfc_reg_prefetch_margin; 496 unsigned int xfc_reg_prefetch_margin;
474 unsigned int dst_y_delta_drq_limit; 497 unsigned int dst_y_delta_drq_limit;
475}; 498};
476 499
477struct _vcs_dpi_display_ttu_regs_st { 500struct _vcs_dpi_display_ttu_regs_st {
478 unsigned int qos_level_low_wm; 501 unsigned int qos_level_low_wm;
479 unsigned int qos_level_high_wm; 502 unsigned int qos_level_high_wm;
480 unsigned int min_ttu_vblank; 503 unsigned int min_ttu_vblank;
481 unsigned int qos_level_flip; 504 unsigned int qos_level_flip;
482 unsigned int refcyc_per_req_delivery_l; 505 unsigned int refcyc_per_req_delivery_l;
483 unsigned int refcyc_per_req_delivery_c; 506 unsigned int refcyc_per_req_delivery_c;
484 unsigned int refcyc_per_req_delivery_cur0; 507 unsigned int refcyc_per_req_delivery_cur0;
485 unsigned int refcyc_per_req_delivery_cur1; 508 unsigned int refcyc_per_req_delivery_cur1;
486 unsigned int refcyc_per_req_delivery_pre_l; 509 unsigned int refcyc_per_req_delivery_pre_l;
487 unsigned int refcyc_per_req_delivery_pre_c; 510 unsigned int refcyc_per_req_delivery_pre_c;
488 unsigned int refcyc_per_req_delivery_pre_cur0; 511 unsigned int refcyc_per_req_delivery_pre_cur0;
489 unsigned int refcyc_per_req_delivery_pre_cur1; 512 unsigned int refcyc_per_req_delivery_pre_cur1;
490 unsigned int qos_level_fixed_l; 513 unsigned int qos_level_fixed_l;
491 unsigned int qos_level_fixed_c; 514 unsigned int qos_level_fixed_c;
492 unsigned int qos_level_fixed_cur0; 515 unsigned int qos_level_fixed_cur0;
493 unsigned int qos_level_fixed_cur1; 516 unsigned int qos_level_fixed_cur1;
494 unsigned int qos_ramp_disable_l; 517 unsigned int qos_ramp_disable_l;
495 unsigned int qos_ramp_disable_c; 518 unsigned int qos_ramp_disable_c;
496 unsigned int qos_ramp_disable_cur0; 519 unsigned int qos_ramp_disable_cur0;
497 unsigned int qos_ramp_disable_cur1; 520 unsigned int qos_ramp_disable_cur1;
498}; 521};
499 522
500struct _vcs_dpi_display_data_rq_regs_st { 523struct _vcs_dpi_display_data_rq_regs_st {
501 unsigned int chunk_size; 524 unsigned int chunk_size;
502 unsigned int min_chunk_size; 525 unsigned int min_chunk_size;
503 unsigned int meta_chunk_size; 526 unsigned int meta_chunk_size;
504 unsigned int min_meta_chunk_size; 527 unsigned int min_meta_chunk_size;
505 unsigned int dpte_group_size; 528 unsigned int dpte_group_size;
506 unsigned int mpte_group_size; 529 unsigned int mpte_group_size;
507 unsigned int swath_height; 530 unsigned int swath_height;
508 unsigned int pte_row_height_linear; 531 unsigned int pte_row_height_linear;
509}; 532};
510 533
511struct _vcs_dpi_display_rq_regs_st { 534struct _vcs_dpi_display_rq_regs_st {
512 display_data_rq_regs_st rq_regs_l; 535 display_data_rq_regs_st rq_regs_l;
513 display_data_rq_regs_st rq_regs_c; 536 display_data_rq_regs_st rq_regs_c;
514 unsigned int drq_expansion_mode; 537 unsigned int drq_expansion_mode;
515 unsigned int prq_expansion_mode; 538 unsigned int prq_expansion_mode;
516 unsigned int mrq_expansion_mode; 539 unsigned int mrq_expansion_mode;
517 unsigned int crq_expansion_mode; 540 unsigned int crq_expansion_mode;
518 unsigned int plane1_base_address; 541 unsigned int plane1_base_address;
519}; 542};
520 543
521struct _vcs_dpi_display_dlg_sys_params_st { 544struct _vcs_dpi_display_dlg_sys_params_st {
522 double t_mclk_wm_us; 545 double t_mclk_wm_us;
523 double t_urg_wm_us; 546 double t_urg_wm_us;
524 double t_sr_wm_us; 547 double t_sr_wm_us;
525 double t_extra_us; 548 double t_extra_us;
526 double mem_trip_us; 549 double mem_trip_us;
527 double t_srx_delay_us; 550 double t_srx_delay_us;
528 double deepsleep_dcfclk_mhz; 551 double deepsleep_dcfclk_mhz;
529 double total_flip_bw; 552 double total_flip_bw;
530 unsigned int total_flip_bytes; 553 unsigned int total_flip_bytes;
531}; 554};
532 555
533struct _vcs_dpi_display_dlg_prefetch_param_st { 556struct _vcs_dpi_display_dlg_prefetch_param_st {
534 double prefetch_bw; 557 double prefetch_bw;
535 unsigned int flip_bytes; 558 unsigned int flip_bytes;
536}; 559};
537 560
538struct _vcs_dpi_display_pipe_clock_st { 561struct _vcs_dpi_display_pipe_clock_st {
539 double dcfclk_mhz; 562 double dcfclk_mhz;
540 double dispclk_mhz; 563 double dispclk_mhz;
541 double socclk_mhz; 564 double socclk_mhz;
542 double dscclk_mhz[6]; 565 double dscclk_mhz[6];
543 double dppclk_mhz[6]; 566 double dppclk_mhz[6];
544}; 567};
545 568
546struct _vcs_dpi_display_arb_params_st { 569struct _vcs_dpi_display_arb_params_st {
547 int max_req_outstanding; 570 int max_req_outstanding;
548 int min_req_outstanding; 571 int min_req_outstanding;
549 int sat_level_us; 572 int sat_level_us;
550}; 573};
551 574
552#endif /*__DISPLAY_MODE_STRUCTS_H__*/ 575#endif /*__DISPLAY_MODE_STRUCTS_H__*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
index f9cf08357989..e8ce08567cd8 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
@@ -35,6 +35,16 @@ static inline double dml_min(double a, double b)
35 return (double) dcn_bw_min2(a, b); 35 return (double) dcn_bw_min2(a, b);
36} 36}
37 37
38static inline double dml_min3(double a, double b, double c)
39{
40 return dml_min(dml_min(a, b), c);
41}
42
43static inline double dml_min4(double a, double b, double c, double d)
44{
45 return dml_min(dml_min(a, b), dml_min(c, d));
46}
47
38static inline double dml_max(double a, double b) 48static inline double dml_max(double a, double b)
39{ 49{
40 return (double) dcn_bw_max2(a, b); 50 return (double) dcn_bw_max2(a, b);
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c
index 87b580fa4bc9..0caee3523017 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c
@@ -75,6 +75,7 @@ bool dal_hw_factory_init(
75 return true; 75 return true;
76 case DCE_VERSION_11_0: 76 case DCE_VERSION_11_0:
77 case DCE_VERSION_11_2: 77 case DCE_VERSION_11_2:
78 case DCE_VERSION_11_22:
78 dal_hw_factory_dce110_init(factory); 79 dal_hw_factory_dce110_init(factory);
79 return true; 80 return true;
80 case DCE_VERSION_12_0: 81 case DCE_VERSION_12_0:
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
index 0ae8ace25739..55c707488541 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
@@ -72,6 +72,7 @@ bool dal_hw_translate_init(
72 case DCE_VERSION_10_0: 72 case DCE_VERSION_10_0:
73 case DCE_VERSION_11_0: 73 case DCE_VERSION_11_0:
74 case DCE_VERSION_11_2: 74 case DCE_VERSION_11_2:
75 case DCE_VERSION_11_22:
75 dal_hw_translate_dce110_init(translate); 76 dal_hw_translate_dce110_init(translate);
76 return true; 77 return true;
77 case DCE_VERSION_12_0: 78 case DCE_VERSION_12_0:
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c
index abd0095ced30..b7256f595052 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c
@@ -527,7 +527,7 @@ static void construct(
527 REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div); 527 REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div);
528 528
529 if (xtal_ref_div == 0) { 529 if (xtal_ref_div == 0) {
530 DC_LOG_WARNING("Invalid base timer divider\n", 530 DC_LOG_WARNING("Invalid base timer divider [%s]\n",
531 __func__); 531 __func__);
532 xtal_ref_div = 2; 532 xtal_ref_div = 2;
533 } 533 }
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c
index 5cbf6626b8d4..14dc8c94d862 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c
@@ -83,6 +83,7 @@ struct i2caux *dal_i2caux_create(
83 case DCE_VERSION_8_3: 83 case DCE_VERSION_8_3:
84 return dal_i2caux_dce80_create(ctx); 84 return dal_i2caux_dce80_create(ctx);
85 case DCE_VERSION_11_2: 85 case DCE_VERSION_11_2:
86 case DCE_VERSION_11_22:
86 return dal_i2caux_dce112_create(ctx); 87 return dal_i2caux_dce112_create(ctx);
87 case DCE_VERSION_11_0: 88 case DCE_VERSION_11_0:
88 return dal_i2caux_dce110_create(ctx); 89 return dal_i2caux_dce110_create(ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index 8c51ad70cace..a94942d4e66b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -95,11 +95,6 @@ struct resource_funcs {
95 struct link_encoder *(*link_enc_create)( 95 struct link_encoder *(*link_enc_create)(
96 const struct encoder_init_data *init); 96 const struct encoder_init_data *init);
97 97
98 enum dc_status (*validate_guaranteed)(
99 struct dc *dc,
100 struct dc_stream_state *stream,
101 struct dc_state *context);
102
103 bool (*validate_bandwidth)( 98 bool (*validate_bandwidth)(
104 struct dc *dc, 99 struct dc *dc,
105 struct dc_state *context); 100 struct dc_state *context);
@@ -250,6 +245,7 @@ struct dce_bw_output {
250 bool all_displays_in_sync; 245 bool all_displays_in_sync;
251 struct dce_watermarks urgent_wm_ns[MAX_PIPES]; 246 struct dce_watermarks urgent_wm_ns[MAX_PIPES];
252 struct dce_watermarks stutter_exit_wm_ns[MAX_PIPES]; 247 struct dce_watermarks stutter_exit_wm_ns[MAX_PIPES];
248 struct dce_watermarks stutter_entry_wm_ns[MAX_PIPES];
253 struct dce_watermarks nbp_state_change_wm_ns[MAX_PIPES]; 249 struct dce_watermarks nbp_state_change_wm_ns[MAX_PIPES];
254 int sclk_khz; 250 int sclk_khz;
255 int sclk_deep_sleep_khz; 251 int sclk_deep_sleep_khz;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dce_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/dce_calcs.h
index a9bfe9ff8ce6..eece165206f9 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dce_calcs.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dce_calcs.h
@@ -42,6 +42,8 @@ enum bw_calcs_version {
42 BW_CALCS_VERSION_CARRIZO, 42 BW_CALCS_VERSION_CARRIZO,
43 BW_CALCS_VERSION_POLARIS10, 43 BW_CALCS_VERSION_POLARIS10,
44 BW_CALCS_VERSION_POLARIS11, 44 BW_CALCS_VERSION_POLARIS11,
45 BW_CALCS_VERSION_POLARIS12,
46 BW_CALCS_VERSION_VEGAM,
45 BW_CALCS_VERSION_STONEY, 47 BW_CALCS_VERSION_STONEY,
46 BW_CALCS_VERSION_VEGA10 48 BW_CALCS_VERSION_VEGA10
47}; 49};
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
new file mode 100644
index 000000000000..02f757dd70d4
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#ifndef __DAL_DCHUBBUB_H__
27#define __DAL_DCHUBBUB_H__
28
29
30enum dcc_control {
31 dcc_control__256_256_xxx,
32 dcc_control__128_128_xxx,
33 dcc_control__256_64_64,
34};
35
36enum segment_order {
37 segment_order__na,
38 segment_order__contiguous,
39 segment_order__non_contiguous,
40};
41
42
43struct hubbub_funcs {
44 void (*update_dchub)(
45 struct hubbub *hubbub,
46 struct dchub_init_data *dh_data);
47
48 bool (*get_dcc_compression_cap)(struct hubbub *hubbub,
49 const struct dc_dcc_surface_param *input,
50 struct dc_surface_dcc_cap *output);
51
52 bool (*dcc_support_swizzle)(
53 enum swizzle_mode_values swizzle,
54 unsigned int bytes_per_element,
55 enum segment_order *segment_order_horz,
56 enum segment_order *segment_order_vert);
57
58 bool (*dcc_support_pixel_format)(
59 enum surface_pixel_format format,
60 unsigned int *bytes_per_element);
61};
62
63
64#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
index 99995608b620..582458f028f8 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -44,7 +44,23 @@ struct dpp_grph_csc_adjustment {
44 enum graphics_gamut_adjust_type gamut_adjust_type; 44 enum graphics_gamut_adjust_type gamut_adjust_type;
45}; 45};
46 46
47struct dcn_dpp_state {
48 uint32_t igam_lut_mode;
49 uint32_t igam_input_format;
50 uint32_t dgam_lut_mode;
51 uint32_t rgam_lut_mode;
52 uint32_t gamut_remap_mode;
53 uint32_t gamut_remap_c11_c12;
54 uint32_t gamut_remap_c13_c14;
55 uint32_t gamut_remap_c21_c22;
56 uint32_t gamut_remap_c23_c24;
57 uint32_t gamut_remap_c31_c32;
58 uint32_t gamut_remap_c33_c34;
59};
60
47struct dpp_funcs { 61struct dpp_funcs {
62 void (*dpp_read_state)(struct dpp *dpp, struct dcn_dpp_state *s);
63
48 void (*dpp_reset)(struct dpp *dpp); 64 void (*dpp_reset)(struct dpp *dpp);
49 65
50 void (*dpp_set_scaler)(struct dpp *dpp, 66 void (*dpp_set_scaler)(struct dpp *dpp,
@@ -117,7 +133,7 @@ struct dpp_funcs {
117 struct dpp *dpp_base, 133 struct dpp *dpp_base,
118 enum surface_pixel_format format, 134 enum surface_pixel_format format,
119 enum expansion_mode mode, 135 enum expansion_mode mode,
120 struct csc_transform input_csc_color_matrix, 136 struct dc_csc_transform input_csc_color_matrix,
121 enum dc_color_space input_color_space); 137 enum dc_color_space input_color_space);
122 138
123 void (*dpp_full_bypass)(struct dpp *dpp_base); 139 void (*dpp_full_bypass)(struct dpp *dpp_base);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
index 9ced254e652c..97df82cddf82 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -56,7 +56,6 @@ struct hubp {
56 bool power_gated; 56 bool power_gated;
57}; 57};
58 58
59
60struct hubp_funcs { 59struct hubp_funcs {
61 void (*hubp_setup)( 60 void (*hubp_setup)(
62 struct hubp *hubp, 61 struct hubp *hubp,
@@ -121,6 +120,9 @@ struct hubp_funcs {
121 120
122 void (*hubp_clk_cntl)(struct hubp *hubp, bool enable); 121 void (*hubp_clk_cntl)(struct hubp *hubp, bool enable);
123 void (*hubp_vtg_sel)(struct hubp *hubp, uint32_t otg_inst); 122 void (*hubp_vtg_sel)(struct hubp *hubp, uint32_t otg_inst);
123 void (*hubp_read_state)(struct hubp *hubp);
124 void (*hubp_disable_control)(struct hubp *hubp, bool disable_hubp);
125 unsigned int (*hubp_get_underflow_status)(struct hubp *hubp);
124 126
125}; 127};
126 128
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
index b22158190262..cf7433ebf91a 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -140,11 +140,6 @@ enum opp_regamma {
140 OPP_REGAMMA_USER 140 OPP_REGAMMA_USER
141}; 141};
142 142
143struct csc_transform {
144 uint16_t matrix[12];
145 bool enable_adjustment;
146};
147
148struct dc_bias_and_scale { 143struct dc_bias_and_scale {
149 uint16_t scale_red; 144 uint16_t scale_red;
150 uint16_t bias_red; 145 uint16_t bias_red;
@@ -191,4 +186,9 @@ enum controller_dp_test_pattern {
191 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA 186 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA
192}; 187};
193 188
189enum dc_lut_mode {
190 LUT_BYPASS,
191 LUT_RAM_A,
192 LUT_RAM_B
193};
194#endif /* __DAL_HW_SHARED_H__ */ 194#endif /* __DAL_HW_SHARED_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h
index 2109eac20a3d..b2fa4c4cd920 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h
@@ -87,7 +87,7 @@ struct ipp_funcs {
87 struct input_pixel_processor *ipp, 87 struct input_pixel_processor *ipp,
88 enum surface_pixel_format format, 88 enum surface_pixel_format format,
89 enum expansion_mode mode, 89 enum expansion_mode mode,
90 struct csc_transform input_csc_color_matrix, 90 struct dc_csc_transform input_csc_color_matrix,
91 enum dc_color_space input_color_space); 91 enum dc_color_space input_color_space);
92 92
93 /* DCE function to setup IPP. TODO: see if we can consolidate to setup */ 93 /* DCE function to setup IPP. TODO: see if we can consolidate to setup */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 54d8a1386142..cf6df2e7beb2 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -149,6 +149,7 @@ struct link_encoder_funcs {
149 bool connect); 149 bool connect);
150 void (*enable_hpd)(struct link_encoder *enc); 150 void (*enable_hpd)(struct link_encoder *enc);
151 void (*disable_hpd)(struct link_encoder *enc); 151 void (*disable_hpd)(struct link_encoder *enc);
152 bool (*is_dig_enabled)(struct link_encoder *enc);
152 void (*destroy)(struct link_encoder **enc); 153 void (*destroy)(struct link_encoder **enc);
153}; 154};
154 155
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
index 3e1e7e6a8792..47f1dc5a43b7 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
@@ -104,6 +104,7 @@ struct mem_input_funcs {
104 struct mem_input *mem_input, 104 struct mem_input *mem_input,
105 struct dce_watermarks nbp, 105 struct dce_watermarks nbp,
106 struct dce_watermarks stutter, 106 struct dce_watermarks stutter,
107 struct dce_watermarks stutter_enter,
107 struct dce_watermarks urgent, 108 struct dce_watermarks urgent,
108 uint32_t total_dest_line_time_ns); 109 uint32_t total_dest_line_time_ns);
109 110
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index 23a8d5e53a89..caf74e3c836f 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -105,7 +105,24 @@ struct mpc {
105 struct mpcc mpcc_array[MAX_MPCC]; 105 struct mpcc mpcc_array[MAX_MPCC];
106}; 106};
107 107
108struct mpcc_state {
109 uint32_t opp_id;
110 uint32_t dpp_id;
111 uint32_t bot_mpcc_id;
112 uint32_t mode;
113 uint32_t alpha_mode;
114 uint32_t pre_multiplied_alpha;
115 uint32_t overlap_only;
116 uint32_t idle;
117 uint32_t busy;
118};
119
108struct mpc_funcs { 120struct mpc_funcs {
121 void (*read_mpcc_state)(
122 struct mpc *mpc,
123 int mpcc_inst,
124 struct mpcc_state *s);
125
109 /* 126 /*
110 * Insert DPP into MPC tree based on specified blending position. 127 * Insert DPP into MPC tree based on specified blending position.
111 * Only used for planes that are part of blending chain for OPP output 128 * Only used for planes that are part of blending chain for OPP output
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
index b5db1692393c..cfa7ec9517ae 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
@@ -29,31 +29,40 @@
29#define STREAM_ENCODER_H_ 29#define STREAM_ENCODER_H_
30 30
31#include "audio_types.h" 31#include "audio_types.h"
32#include "hw_shared.h"
32 33
33struct dc_bios; 34struct dc_bios;
34struct dc_context; 35struct dc_context;
35struct dc_crtc_timing; 36struct dc_crtc_timing;
36 37
37struct encoder_info_packet { 38enum dp_pixel_encoding_type {
38 bool valid; 39 DP_PIXEL_ENCODING_TYPE_RGB444 = 0x00000000,
39 uint8_t hb0; 40 DP_PIXEL_ENCODING_TYPE_YCBCR422 = 0x00000001,
40 uint8_t hb1; 41 DP_PIXEL_ENCODING_TYPE_YCBCR444 = 0x00000002,
41 uint8_t hb2; 42 DP_PIXEL_ENCODING_TYPE_RGB_WIDE_GAMUT = 0x00000003,
42 uint8_t hb3; 43 DP_PIXEL_ENCODING_TYPE_Y_ONLY = 0x00000004,
43 uint8_t sb[32]; 44 DP_PIXEL_ENCODING_TYPE_YCBCR420 = 0x00000005
45};
46
47enum dp_component_depth {
48 DP_COMPONENT_PIXEL_DEPTH_6BPC = 0x00000000,
49 DP_COMPONENT_PIXEL_DEPTH_8BPC = 0x00000001,
50 DP_COMPONENT_PIXEL_DEPTH_10BPC = 0x00000002,
51 DP_COMPONENT_PIXEL_DEPTH_12BPC = 0x00000003,
52 DP_COMPONENT_PIXEL_DEPTH_16BPC = 0x00000004
44}; 53};
45 54
46struct encoder_info_frame { 55struct encoder_info_frame {
47 /* auxiliary video information */ 56 /* auxiliary video information */
48 struct encoder_info_packet avi; 57 struct dc_info_packet avi;
49 struct encoder_info_packet gamut; 58 struct dc_info_packet gamut;
50 struct encoder_info_packet vendor; 59 struct dc_info_packet vendor;
51 /* source product description */ 60 /* source product description */
52 struct encoder_info_packet spd; 61 struct dc_info_packet spd;
53 /* video stream configuration */ 62 /* video stream configuration */
54 struct encoder_info_packet vsc; 63 struct dc_info_packet vsc;
55 /* HDR Static MetaData */ 64 /* HDR Static MetaData */
56 struct encoder_info_packet hdrsmd; 65 struct dc_info_packet hdrsmd;
57}; 66};
58 67
59struct encoder_unblank_param { 68struct encoder_unblank_param {
@@ -147,6 +156,7 @@ struct stream_encoder_funcs {
147 156
148 void (*set_avmute)( 157 void (*set_avmute)(
149 struct stream_encoder *enc, bool enable); 158 struct stream_encoder *enc, bool enable);
159
150}; 160};
151 161
152#endif /* STREAM_ENCODER_H_ */ 162#endif /* STREAM_ENCODER_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index 3217b5bf6c7a..69cb0a105300 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -140,6 +140,9 @@ struct timing_generator_funcs {
140 void (*program_timing)(struct timing_generator *tg, 140 void (*program_timing)(struct timing_generator *tg,
141 const struct dc_crtc_timing *timing, 141 const struct dc_crtc_timing *timing,
142 bool use_vbios); 142 bool use_vbios);
143 void (*program_vline_interrupt)(struct timing_generator *optc,
144 const struct dc_crtc_timing *dc_crtc_timing,
145 unsigned long long vsync_delta);
143 bool (*enable_crtc)(struct timing_generator *tg); 146 bool (*enable_crtc)(struct timing_generator *tg);
144 bool (*disable_crtc)(struct timing_generator *tg); 147 bool (*disable_crtc)(struct timing_generator *tg);
145 bool (*is_counter_moving)(struct timing_generator *tg); 148 bool (*is_counter_moving)(struct timing_generator *tg);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
index c5b3623bcbd9..fecc80c47c26 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
@@ -252,7 +252,7 @@ struct transform_funcs {
252 struct transform *xfm_base, 252 struct transform *xfm_base,
253 enum surface_pixel_format format, 253 enum surface_pixel_format format,
254 enum expansion_mode mode, 254 enum expansion_mode mode,
255 struct csc_transform input_csc_color_matrix, 255 struct dc_csc_transform input_csc_color_matrix,
256 enum dc_color_space input_color_space); 256 enum dc_color_space input_color_space);
257 257
258 void (*ipp_full_bypass)(struct transform *xfm_base); 258 void (*ipp_full_bypass)(struct transform *xfm_base);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index e764cbad881b..63fc6c499789 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -32,6 +32,8 @@
32#include "inc/hw/link_encoder.h" 32#include "inc/hw/link_encoder.h"
33#include "core_status.h" 33#include "core_status.h"
34 34
35#define EDP_BACKLIGHT_RAMP_DISABLE_LEVEL 0xFFFFFFFF
36
35enum pipe_gating_control { 37enum pipe_gating_control {
36 PIPE_GATING_CONTROL_DISABLE = 0, 38 PIPE_GATING_CONTROL_DISABLE = 0,
37 PIPE_GATING_CONTROL_ENABLE, 39 PIPE_GATING_CONTROL_ENABLE,
@@ -63,6 +65,7 @@ struct dchub_init_data;
63struct dc_static_screen_events; 65struct dc_static_screen_events;
64struct resource_pool; 66struct resource_pool;
65struct resource_context; 67struct resource_context;
68struct stream_resource;
66 69
67struct hw_sequencer_funcs { 70struct hw_sequencer_funcs {
68 71
@@ -80,11 +83,6 @@ struct hw_sequencer_funcs {
80 int num_planes, 83 int num_planes,
81 struct dc_state *context); 84 struct dc_state *context);
82 85
83 void (*set_plane_config)(
84 const struct dc *dc,
85 struct pipe_ctx *pipe_ctx,
86 struct resource_context *res_ctx);
87
88 void (*program_gamut_remap)( 86 void (*program_gamut_remap)(
89 struct pipe_ctx *pipe_ctx); 87 struct pipe_ctx *pipe_ctx);
90 88
@@ -93,6 +91,12 @@ struct hw_sequencer_funcs {
93 enum dc_color_space colorspace, 91 enum dc_color_space colorspace,
94 uint16_t *matrix); 92 uint16_t *matrix);
95 93
94 void (*program_output_csc)(struct dc *dc,
95 struct pipe_ctx *pipe_ctx,
96 enum dc_color_space colorspace,
97 uint16_t *matrix,
98 int opp_id);
99
96 void (*update_plane_addr)( 100 void (*update_plane_addr)(
97 const struct dc *dc, 101 const struct dc *dc,
98 struct pipe_ctx *pipe_ctx); 102 struct pipe_ctx *pipe_ctx);
@@ -154,6 +158,11 @@ struct hw_sequencer_funcs {
154 struct dc *dc, 158 struct dc *dc,
155 struct pipe_ctx *pipe, 159 struct pipe_ctx *pipe,
156 bool lock); 160 bool lock);
161 void (*blank_pixel_data)(
162 struct dc *dc,
163 struct stream_resource *stream_res,
164 struct dc_stream_state *stream,
165 bool blank);
157 166
158 void (*set_bandwidth)( 167 void (*set_bandwidth)(
159 struct dc *dc, 168 struct dc *dc,
@@ -169,7 +178,7 @@ struct hw_sequencer_funcs {
169 void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx, 178 void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
170 int num_pipes, const struct dc_static_screen_events *events); 179 int num_pipes, const struct dc_static_screen_events *events);
171 180
172 enum dc_status (*prog_pixclk_crtc_otg)( 181 enum dc_status (*enable_stream_timing)(
173 struct pipe_ctx *pipe_ctx, 182 struct pipe_ctx *pipe_ctx,
174 struct dc_state *context, 183 struct dc_state *context,
175 struct dc *dc); 184 struct dc *dc);
@@ -201,6 +210,7 @@ struct hw_sequencer_funcs {
201 210
202 void (*set_cursor_position)(struct pipe_ctx *pipe); 211 void (*set_cursor_position)(struct pipe_ctx *pipe);
203 void (*set_cursor_attribute)(struct pipe_ctx *pipe); 212 void (*set_cursor_attribute)(struct pipe_ctx *pipe);
213
204}; 214};
205 215
206void color_space_to_black_color( 216void color_space_to_black_color(
diff --git a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h
index 77eb72874e90..3306e7b0b3e3 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h
@@ -183,6 +183,36 @@
183 FN(reg_name, f4), v4, \ 183 FN(reg_name, f4), v4, \
184 FN(reg_name, f5), v5) 184 FN(reg_name, f5), v5)
185 185
186#define REG_GET_6(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
187 generic_reg_get6(CTX, REG(reg_name), \
188 FN(reg_name, f1), v1, \
189 FN(reg_name, f2), v2, \
190 FN(reg_name, f3), v3, \
191 FN(reg_name, f4), v4, \
192 FN(reg_name, f5), v5, \
193 FN(reg_name, f6), v6)
194
195#define REG_GET_7(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
196 generic_reg_get7(CTX, REG(reg_name), \
197 FN(reg_name, f1), v1, \
198 FN(reg_name, f2), v2, \
199 FN(reg_name, f3), v3, \
200 FN(reg_name, f4), v4, \
201 FN(reg_name, f5), v5, \
202 FN(reg_name, f6), v6, \
203 FN(reg_name, f7), v7)
204
205#define REG_GET_8(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
206 generic_reg_get8(CTX, REG(reg_name), \
207 FN(reg_name, f1), v1, \
208 FN(reg_name, f2), v2, \
209 FN(reg_name, f3), v3, \
210 FN(reg_name, f4), v4, \
211 FN(reg_name, f5), v5, \
212 FN(reg_name, f6), v6, \
213 FN(reg_name, f7), v7, \
214 FN(reg_name, f8), v8)
215
186/* macro to poll and wait for a register field to read back given value */ 216/* macro to poll and wait for a register field to read back given value */
187 217
188#define REG_WAIT(reg_name, field, val, delay_between_poll_us, max_try) \ 218#define REG_WAIT(reg_name, field, val, delay_between_poll_us, max_try) \
@@ -389,4 +419,30 @@ uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
389 uint8_t shift4, uint32_t mask4, uint32_t *field_value4, 419 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
390 uint8_t shift5, uint32_t mask5, uint32_t *field_value5); 420 uint8_t shift5, uint32_t mask5, uint32_t *field_value5);
391 421
422uint32_t generic_reg_get6(const struct dc_context *ctx, uint32_t addr,
423 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
424 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
425 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
426 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
427 uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
428 uint8_t shift6, uint32_t mask6, uint32_t *field_value6);
429
430uint32_t generic_reg_get7(const struct dc_context *ctx, uint32_t addr,
431 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
432 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
433 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
434 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
435 uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
436 uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
437 uint8_t shift7, uint32_t mask7, uint32_t *field_value7);
438
439uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr,
440 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
441 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
442 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
443 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
444 uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
445 uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
446 uint8_t shift7, uint32_t mask7, uint32_t *field_value7,
447 uint8_t shift8, uint32_t mask8, uint32_t *field_value8);
392#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */ 448#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index 5467332faf7b..640a647f4611 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -139,10 +139,6 @@ bool resource_validate_attach_surfaces(
139 struct dc_state *context, 139 struct dc_state *context,
140 const struct resource_pool *pool); 140 const struct resource_pool *pool);
141 141
142void validate_guaranteed_copy_streams(
143 struct dc_state *context,
144 int max_streams);
145
146void resource_validate_ctx_update_pointer_after_copy( 142void resource_validate_ctx_update_pointer_after_copy(
147 const struct dc_state *src_ctx, 143 const struct dc_state *src_ctx,
148 struct dc_state *dst_ctx); 144 struct dc_state *dst_ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h
index a506c2e939f5..0b5f3a278c22 100644
--- a/drivers/gpu/drm/amd/display/dc/irq_types.h
+++ b/drivers/gpu/drm/amd/display/dc/irq_types.h
@@ -26,6 +26,8 @@
26#ifndef __DAL_IRQ_TYPES_H__ 26#ifndef __DAL_IRQ_TYPES_H__
27#define __DAL_IRQ_TYPES_H__ 27#define __DAL_IRQ_TYPES_H__
28 28
29#include "os_types.h"
30
29struct dc_context; 31struct dc_context;
30 32
31typedef void (*interrupt_handler)(void *); 33typedef void (*interrupt_handler)(void *);
@@ -135,6 +137,13 @@ enum dc_irq_source {
135 DC_IRQ_SOURCE_VBLANK5, 137 DC_IRQ_SOURCE_VBLANK5,
136 DC_IRQ_SOURCE_VBLANK6, 138 DC_IRQ_SOURCE_VBLANK6,
137 139
140 DC_IRQ_SOURCE_DC1_VLINE0,
141 DC_IRQ_SOURCE_DC2_VLINE0,
142 DC_IRQ_SOURCE_DC3_VLINE0,
143 DC_IRQ_SOURCE_DC4_VLINE0,
144 DC_IRQ_SOURCE_DC5_VLINE0,
145 DC_IRQ_SOURCE_DC6_VLINE0,
146
138 DAL_IRQ_SOURCES_NUMBER 147 DAL_IRQ_SOURCES_NUMBER
139}; 148};
140 149
diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
index 9b0a04f99ac8..25029ed42d89 100644
--- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h
+++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
@@ -86,6 +86,7 @@
86#define VI_POLARIS10_P_A0 80 86#define VI_POLARIS10_P_A0 80
87#define VI_POLARIS11_M_A0 90 87#define VI_POLARIS11_M_A0 90
88#define VI_POLARIS12_V_A0 100 88#define VI_POLARIS12_V_A0 100
89#define VI_VEGAM_A0 110
89 90
90#define VI_UNKNOWN 0xFF 91#define VI_UNKNOWN 0xFF
91 92
@@ -98,7 +99,9 @@
98 (eChipRev < VI_POLARIS11_M_A0)) 99 (eChipRev < VI_POLARIS11_M_A0))
99#define ASIC_REV_IS_POLARIS11_M(eChipRev) ((eChipRev >= VI_POLARIS11_M_A0) && \ 100#define ASIC_REV_IS_POLARIS11_M(eChipRev) ((eChipRev >= VI_POLARIS11_M_A0) && \
100 (eChipRev < VI_POLARIS12_V_A0)) 101 (eChipRev < VI_POLARIS12_V_A0))
101#define ASIC_REV_IS_POLARIS12_V(eChipRev) (eChipRev >= VI_POLARIS12_V_A0) 102#define ASIC_REV_IS_POLARIS12_V(eChipRev) ((eChipRev >= VI_POLARIS12_V_A0) && \
103 (eChipRev < VI_VEGAM_A0))
104#define ASIC_REV_IS_VEGAM(eChipRev) (eChipRev >= VI_VEGAM_A0)
102 105
103/* DCE11 */ 106/* DCE11 */
104#define CZ_CARRIZO_A0 0x01 107#define CZ_CARRIZO_A0 0x01
@@ -110,17 +113,19 @@
110 ((rev >= STONEY_A0) && (rev < CZ_UNKNOWN)) 113 ((rev >= STONEY_A0) && (rev < CZ_UNKNOWN))
111 114
112/* DCE12 */ 115/* DCE12 */
116#define AI_UNKNOWN 0xFF
113 117
114#define AI_GREENLAND_P_A0 1 118#define AI_GREENLAND_P_A0 1
115#define AI_GREENLAND_P_A1 2 119#define AI_GREENLAND_P_A1 2
116#define AI_UNKNOWN 0xFF 120#define AI_UNKNOWN 0xFF
117 121
118#define AI_VEGA12_P_A0 20 122#define AI_VEGA12_P_A0 20
123#define AI_VEGA20_P_A0 40
119#define ASICREV_IS_GREENLAND_M(eChipRev) (eChipRev < AI_VEGA12_P_A0) 124#define ASICREV_IS_GREENLAND_M(eChipRev) (eChipRev < AI_VEGA12_P_A0)
120#define ASICREV_IS_GREENLAND_P(eChipRev) (eChipRev < AI_VEGA12_P_A0) 125#define ASICREV_IS_GREENLAND_P(eChipRev) (eChipRev < AI_VEGA12_P_A0)
121 126
122#define ASICREV_IS_VEGA12_P(eChipRev) ((eChipRev >= AI_VEGA12_P_A0) && (eChipRev < AI_UNKNOWN)) 127#define ASICREV_IS_VEGA12_P(eChipRev) ((eChipRev >= AI_VEGA12_P_A0) && (eChipRev < AI_VEGA20_P_A0))
123#define ASICREV_IS_VEGA12_p(eChipRev) ((eChipRev >= AI_VEGA12_P_A0) && (eChipRev < AI_UNKNOWN)) 128#define ASICREV_IS_VEGA20_P(eChipRev) ((eChipRev >= AI_VEGA20_P_A0) && (eChipRev < AI_UNKNOWN))
124 129
125/* DCN1_0 */ 130/* DCN1_0 */
126#define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */ 131#define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */
diff --git a/drivers/gpu/drm/amd/display/include/dal_types.h b/drivers/gpu/drm/amd/display/include/dal_types.h
index fa543965feb5..840142b65f8b 100644
--- a/drivers/gpu/drm/amd/display/include/dal_types.h
+++ b/drivers/gpu/drm/amd/display/include/dal_types.h
@@ -40,6 +40,7 @@ enum dce_version {
40 DCE_VERSION_10_0, 40 DCE_VERSION_10_0,
41 DCE_VERSION_11_0, 41 DCE_VERSION_11_0,
42 DCE_VERSION_11_2, 42 DCE_VERSION_11_2,
43 DCE_VERSION_11_22,
43 DCE_VERSION_12_0, 44 DCE_VERSION_12_0,
44 DCE_VERSION_MAX, 45 DCE_VERSION_MAX,
45 DCN_VERSION_1_0, 46 DCN_VERSION_1_0,
diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h
index 0de258622c12..bb0d4ebba9f0 100644
--- a/drivers/gpu/drm/amd/display/include/fixed31_32.h
+++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h
@@ -26,9 +26,13 @@
26#ifndef __DAL_FIXED31_32_H__ 26#ifndef __DAL_FIXED31_32_H__
27#define __DAL_FIXED31_32_H__ 27#define __DAL_FIXED31_32_H__
28 28
29#include "os_types.h"
30
31#define FIXED31_32_BITS_PER_FRACTIONAL_PART 32 29#define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
30#ifndef LLONG_MIN
31#define LLONG_MIN (1LL<<63)
32#endif
33#ifndef LLONG_MAX
34#define LLONG_MAX (-1LL>>1)
35#endif
32 36
33/* 37/*
34 * @brief 38 * @brief
@@ -44,24 +48,25 @@
44 */ 48 */
45 49
46struct fixed31_32 { 50struct fixed31_32 {
47 int64_t value; 51 long long value;
48}; 52};
49 53
54
50/* 55/*
51 * @brief 56 * @brief
52 * Useful constants 57 * Useful constants
53 */ 58 */
54 59
55static const struct fixed31_32 dal_fixed31_32_zero = { 0 }; 60static const struct fixed31_32 dc_fixpt_zero = { 0 };
56static const struct fixed31_32 dal_fixed31_32_epsilon = { 1LL }; 61static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
57static const struct fixed31_32 dal_fixed31_32_half = { 0x80000000LL }; 62static const struct fixed31_32 dc_fixpt_half = { 0x80000000LL };
58static const struct fixed31_32 dal_fixed31_32_one = { 0x100000000LL }; 63static const struct fixed31_32 dc_fixpt_one = { 0x100000000LL };
59 64
60static const struct fixed31_32 dal_fixed31_32_pi = { 13493037705LL }; 65static const struct fixed31_32 dc_fixpt_pi = { 13493037705LL };
61static const struct fixed31_32 dal_fixed31_32_two_pi = { 26986075409LL }; 66static const struct fixed31_32 dc_fixpt_two_pi = { 26986075409LL };
62static const struct fixed31_32 dal_fixed31_32_e = { 11674931555LL }; 67static const struct fixed31_32 dc_fixpt_e = { 11674931555LL };
63static const struct fixed31_32 dal_fixed31_32_ln2 = { 2977044471LL }; 68static const struct fixed31_32 dc_fixpt_ln2 = { 2977044471LL };
64static const struct fixed31_32 dal_fixed31_32_ln2_div_2 = { 1488522236LL }; 69static const struct fixed31_32 dc_fixpt_ln2_div_2 = { 1488522236LL };
65 70
66/* 71/*
67 * @brief 72 * @brief
@@ -72,24 +77,19 @@ static const struct fixed31_32 dal_fixed31_32_ln2_div_2 = { 1488522236LL };
72 * @brief 77 * @brief
73 * result = numerator / denominator 78 * result = numerator / denominator
74 */ 79 */
75struct fixed31_32 dal_fixed31_32_from_fraction( 80struct fixed31_32 dc_fixpt_from_fraction(long long numerator, long long denominator);
76 int64_t numerator,
77 int64_t denominator);
78 81
79/* 82/*
80 * @brief 83 * @brief
81 * result = arg 84 * result = arg
82 */ 85 */
83struct fixed31_32 dal_fixed31_32_from_int_nonconst(int64_t arg); 86static inline struct fixed31_32 dc_fixpt_from_int(int arg)
84static inline struct fixed31_32 dal_fixed31_32_from_int(int64_t arg)
85{ 87{
86 if (__builtin_constant_p(arg)) { 88 struct fixed31_32 res;
87 struct fixed31_32 res; 89
88 BUILD_BUG_ON((LONG_MIN > arg) || (arg > LONG_MAX)); 90 res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
89 res.value = arg << FIXED31_32_BITS_PER_FRACTIONAL_PART; 91
90 return res; 92 return res;
91 } else
92 return dal_fixed31_32_from_int_nonconst(arg);
93} 93}
94 94
95/* 95/*
@@ -101,7 +101,7 @@ static inline struct fixed31_32 dal_fixed31_32_from_int(int64_t arg)
101 * @brief 101 * @brief
102 * result = -arg 102 * result = -arg
103 */ 103 */
104static inline struct fixed31_32 dal_fixed31_32_neg(struct fixed31_32 arg) 104static inline struct fixed31_32 dc_fixpt_neg(struct fixed31_32 arg)
105{ 105{
106 struct fixed31_32 res; 106 struct fixed31_32 res;
107 107
@@ -114,10 +114,10 @@ static inline struct fixed31_32 dal_fixed31_32_neg(struct fixed31_32 arg)
114 * @brief 114 * @brief
115 * result = abs(arg) := (arg >= 0) ? arg : -arg 115 * result = abs(arg) := (arg >= 0) ? arg : -arg
116 */ 116 */
117static inline struct fixed31_32 dal_fixed31_32_abs(struct fixed31_32 arg) 117static inline struct fixed31_32 dc_fixpt_abs(struct fixed31_32 arg)
118{ 118{
119 if (arg.value < 0) 119 if (arg.value < 0)
120 return dal_fixed31_32_neg(arg); 120 return dc_fixpt_neg(arg);
121 else 121 else
122 return arg; 122 return arg;
123} 123}
@@ -131,8 +131,7 @@ static inline struct fixed31_32 dal_fixed31_32_abs(struct fixed31_32 arg)
131 * @brief 131 * @brief
132 * result = arg1 < arg2 132 * result = arg1 < arg2
133 */ 133 */
134static inline bool dal_fixed31_32_lt(struct fixed31_32 arg1, 134static inline bool dc_fixpt_lt(struct fixed31_32 arg1, struct fixed31_32 arg2)
135 struct fixed31_32 arg2)
136{ 135{
137 return arg1.value < arg2.value; 136 return arg1.value < arg2.value;
138} 137}
@@ -141,8 +140,7 @@ static inline bool dal_fixed31_32_lt(struct fixed31_32 arg1,
141 * @brief 140 * @brief
142 * result = arg1 <= arg2 141 * result = arg1 <= arg2
143 */ 142 */
144static inline bool dal_fixed31_32_le(struct fixed31_32 arg1, 143static inline bool dc_fixpt_le(struct fixed31_32 arg1, struct fixed31_32 arg2)
145 struct fixed31_32 arg2)
146{ 144{
147 return arg1.value <= arg2.value; 145 return arg1.value <= arg2.value;
148} 146}
@@ -151,8 +149,7 @@ static inline bool dal_fixed31_32_le(struct fixed31_32 arg1,
151 * @brief 149 * @brief
152 * result = arg1 == arg2 150 * result = arg1 == arg2
153 */ 151 */
154static inline bool dal_fixed31_32_eq(struct fixed31_32 arg1, 152static inline bool dc_fixpt_eq(struct fixed31_32 arg1, struct fixed31_32 arg2)
155 struct fixed31_32 arg2)
156{ 153{
157 return arg1.value == arg2.value; 154 return arg1.value == arg2.value;
158} 155}
@@ -161,8 +158,7 @@ static inline bool dal_fixed31_32_eq(struct fixed31_32 arg1,
161 * @brief 158 * @brief
162 * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2 159 * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
163 */ 160 */
164static inline struct fixed31_32 dal_fixed31_32_min(struct fixed31_32 arg1, 161static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1, struct fixed31_32 arg2)
165 struct fixed31_32 arg2)
166{ 162{
167 if (arg1.value <= arg2.value) 163 if (arg1.value <= arg2.value)
168 return arg1; 164 return arg1;
@@ -174,8 +170,7 @@ static inline struct fixed31_32 dal_fixed31_32_min(struct fixed31_32 arg1,
174 * @brief 170 * @brief
175 * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1 171 * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
176 */ 172 */
177static inline struct fixed31_32 dal_fixed31_32_max(struct fixed31_32 arg1, 173static inline struct fixed31_32 dc_fixpt_max(struct fixed31_32 arg1, struct fixed31_32 arg2)
178 struct fixed31_32 arg2)
179{ 174{
180 if (arg1.value <= arg2.value) 175 if (arg1.value <= arg2.value)
181 return arg2; 176 return arg2;
@@ -189,14 +184,14 @@ static inline struct fixed31_32 dal_fixed31_32_max(struct fixed31_32 arg1,
189 * result = | arg, when min_value < arg < max_value 184 * result = | arg, when min_value < arg < max_value
190 * | max_value, when arg >= max_value 185 * | max_value, when arg >= max_value
191 */ 186 */
192static inline struct fixed31_32 dal_fixed31_32_clamp( 187static inline struct fixed31_32 dc_fixpt_clamp(
193 struct fixed31_32 arg, 188 struct fixed31_32 arg,
194 struct fixed31_32 min_value, 189 struct fixed31_32 min_value,
195 struct fixed31_32 max_value) 190 struct fixed31_32 max_value)
196{ 191{
197 if (dal_fixed31_32_le(arg, min_value)) 192 if (dc_fixpt_le(arg, min_value))
198 return min_value; 193 return min_value;
199 else if (dal_fixed31_32_le(max_value, arg)) 194 else if (dc_fixpt_le(max_value, arg))
200 return max_value; 195 return max_value;
201 else 196 else
202 return arg; 197 return arg;
@@ -211,21 +206,30 @@ static inline struct fixed31_32 dal_fixed31_32_clamp(
211 * @brief 206 * @brief
212 * result = arg << shift 207 * result = arg << shift
213 */ 208 */
214struct fixed31_32 dal_fixed31_32_shl( 209static inline struct fixed31_32 dc_fixpt_shl(struct fixed31_32 arg, unsigned char shift)
215 struct fixed31_32 arg, 210{
216 uint8_t shift); 211 ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
212 ((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
213
214 arg.value = arg.value << shift;
215
216 return arg;
217}
217 218
218/* 219/*
219 * @brief 220 * @brief
220 * result = arg >> shift 221 * result = arg >> shift
221 */ 222 */
222static inline struct fixed31_32 dal_fixed31_32_shr( 223static inline struct fixed31_32 dc_fixpt_shr(struct fixed31_32 arg, unsigned char shift)
223 struct fixed31_32 arg,
224 uint8_t shift)
225{ 224{
226 struct fixed31_32 res; 225 bool negative = arg.value < 0;
227 res.value = arg.value >> shift; 226
228 return res; 227 if (negative)
228 arg.value = -arg.value;
229 arg.value = arg.value >> shift;
230 if (negative)
231 arg.value = -arg.value;
232 return arg;
229} 233}
230 234
231/* 235/*
@@ -237,38 +241,50 @@ static inline struct fixed31_32 dal_fixed31_32_shr(
237 * @brief 241 * @brief
238 * result = arg1 + arg2 242 * result = arg1 + arg2
239 */ 243 */
240struct fixed31_32 dal_fixed31_32_add( 244static inline struct fixed31_32 dc_fixpt_add(struct fixed31_32 arg1, struct fixed31_32 arg2)
241 struct fixed31_32 arg1, 245{
242 struct fixed31_32 arg2); 246 struct fixed31_32 res;
247
248 ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
249 ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
250
251 res.value = arg1.value + arg2.value;
252
253 return res;
254}
243 255
244/* 256/*
245 * @brief 257 * @brief
246 * result = arg1 + arg2 258 * result = arg1 + arg2
247 */ 259 */
248static inline struct fixed31_32 dal_fixed31_32_add_int(struct fixed31_32 arg1, 260static inline struct fixed31_32 dc_fixpt_add_int(struct fixed31_32 arg1, int arg2)
249 int32_t arg2)
250{ 261{
251 return dal_fixed31_32_add(arg1, 262 return dc_fixpt_add(arg1, dc_fixpt_from_int(arg2));
252 dal_fixed31_32_from_int(arg2));
253} 263}
254 264
255/* 265/*
256 * @brief 266 * @brief
257 * result = arg1 - arg2 267 * result = arg1 - arg2
258 */ 268 */
259struct fixed31_32 dal_fixed31_32_sub( 269static inline struct fixed31_32 dc_fixpt_sub(struct fixed31_32 arg1, struct fixed31_32 arg2)
260 struct fixed31_32 arg1, 270{
261 struct fixed31_32 arg2); 271 struct fixed31_32 res;
272
273 ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
274 ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
275
276 res.value = arg1.value - arg2.value;
277
278 return res;
279}
262 280
263/* 281/*
264 * @brief 282 * @brief
265 * result = arg1 - arg2 283 * result = arg1 - arg2
266 */ 284 */
267static inline struct fixed31_32 dal_fixed31_32_sub_int(struct fixed31_32 arg1, 285static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1, int arg2)
268 int32_t arg2)
269{ 286{
270 return dal_fixed31_32_sub(arg1, 287 return dc_fixpt_sub(arg1, dc_fixpt_from_int(arg2));
271 dal_fixed31_32_from_int(arg2));
272} 288}
273 289
274 290
@@ -281,49 +297,40 @@ static inline struct fixed31_32 dal_fixed31_32_sub_int(struct fixed31_32 arg1,
281 * @brief 297 * @brief
282 * result = arg1 * arg2 298 * result = arg1 * arg2
283 */ 299 */
284struct fixed31_32 dal_fixed31_32_mul( 300struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2);
285 struct fixed31_32 arg1,
286 struct fixed31_32 arg2);
287 301
288 302
289/* 303/*
290 * @brief 304 * @brief
291 * result = arg1 * arg2 305 * result = arg1 * arg2
292 */ 306 */
293static inline struct fixed31_32 dal_fixed31_32_mul_int(struct fixed31_32 arg1, 307static inline struct fixed31_32 dc_fixpt_mul_int(struct fixed31_32 arg1, int arg2)
294 int32_t arg2)
295{ 308{
296 return dal_fixed31_32_mul(arg1, 309 return dc_fixpt_mul(arg1, dc_fixpt_from_int(arg2));
297 dal_fixed31_32_from_int(arg2));
298} 310}
299 311
300/* 312/*
301 * @brief 313 * @brief
302 * result = square(arg) := arg * arg 314 * result = square(arg) := arg * arg
303 */ 315 */
304struct fixed31_32 dal_fixed31_32_sqr( 316struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg);
305 struct fixed31_32 arg);
306 317
307/* 318/*
308 * @brief 319 * @brief
309 * result = arg1 / arg2 320 * result = arg1 / arg2
310 */ 321 */
311static inline struct fixed31_32 dal_fixed31_32_div_int(struct fixed31_32 arg1, 322static inline struct fixed31_32 dc_fixpt_div_int(struct fixed31_32 arg1, long long arg2)
312 int64_t arg2)
313{ 323{
314 return dal_fixed31_32_from_fraction(arg1.value, 324 return dc_fixpt_from_fraction(arg1.value, dc_fixpt_from_int(arg2).value);
315 dal_fixed31_32_from_int(arg2).value);
316} 325}
317 326
318/* 327/*
319 * @brief 328 * @brief
320 * result = arg1 / arg2 329 * result = arg1 / arg2
321 */ 330 */
322static inline struct fixed31_32 dal_fixed31_32_div(struct fixed31_32 arg1, 331static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1, struct fixed31_32 arg2)
323 struct fixed31_32 arg2)
324{ 332{
325 return dal_fixed31_32_from_fraction(arg1.value, 333 return dc_fixpt_from_fraction(arg1.value, arg2.value);
326 arg2.value);
327} 334}
328 335
329/* 336/*
@@ -338,8 +345,7 @@ static inline struct fixed31_32 dal_fixed31_32_div(struct fixed31_32 arg1,
338 * @note 345 * @note
339 * No special actions taken in case argument is zero. 346 * No special actions taken in case argument is zero.
340 */ 347 */
341struct fixed31_32 dal_fixed31_32_recip( 348struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg);
342 struct fixed31_32 arg);
343 349
344/* 350/*
345 * @brief 351 * @brief
@@ -354,8 +360,7 @@ struct fixed31_32 dal_fixed31_32_recip(
354 * Argument specified in radians, 360 * Argument specified in radians,
355 * internally it's normalized to [-2pi...2pi] range. 361 * internally it's normalized to [-2pi...2pi] range.
356 */ 362 */
357struct fixed31_32 dal_fixed31_32_sinc( 363struct fixed31_32 dc_fixpt_sinc(struct fixed31_32 arg);
358 struct fixed31_32 arg);
359 364
360/* 365/*
361 * @brief 366 * @brief
@@ -365,8 +370,7 @@ struct fixed31_32 dal_fixed31_32_sinc(
365 * Argument specified in radians, 370 * Argument specified in radians,
366 * internally it's normalized to [-2pi...2pi] range. 371 * internally it's normalized to [-2pi...2pi] range.
367 */ 372 */
368struct fixed31_32 dal_fixed31_32_sin( 373struct fixed31_32 dc_fixpt_sin(struct fixed31_32 arg);
369 struct fixed31_32 arg);
370 374
371/* 375/*
372 * @brief 376 * @brief
@@ -378,8 +382,7 @@ struct fixed31_32 dal_fixed31_32_sin(
378 * passing arguments outside that range 382 * passing arguments outside that range
379 * will cause incorrect result! 383 * will cause incorrect result!
380 */ 384 */
381struct fixed31_32 dal_fixed31_32_cos( 385struct fixed31_32 dc_fixpt_cos(struct fixed31_32 arg);
382 struct fixed31_32 arg);
383 386
384/* 387/*
385 * @brief 388 * @brief
@@ -393,8 +396,7 @@ struct fixed31_32 dal_fixed31_32_cos(
393 * @note 396 * @note
394 * Currently, function is verified for abs(arg) <= 1. 397 * Currently, function is verified for abs(arg) <= 1.
395 */ 398 */
396struct fixed31_32 dal_fixed31_32_exp( 399struct fixed31_32 dc_fixpt_exp(struct fixed31_32 arg);
397 struct fixed31_32 arg);
398 400
399/* 401/*
400 * @brief 402 * @brief
@@ -406,8 +408,7 @@ struct fixed31_32 dal_fixed31_32_exp(
406 * Currently, no special actions taken 408 * Currently, no special actions taken
407 * in case of invalid argument(s). Take care! 409 * in case of invalid argument(s). Take care!
408 */ 410 */
409struct fixed31_32 dal_fixed31_32_log( 411struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg);
410 struct fixed31_32 arg);
411 412
412/* 413/*
413 * @brief 414 * @brief
@@ -421,9 +422,13 @@ struct fixed31_32 dal_fixed31_32_log(
421 * @note 422 * @note
422 * Currently, abs(arg1) should be less than 1. Take care! 423 * Currently, abs(arg1) should be less than 1. Take care!
423 */ 424 */
424struct fixed31_32 dal_fixed31_32_pow( 425static inline struct fixed31_32 dc_fixpt_pow(struct fixed31_32 arg1, struct fixed31_32 arg2)
425 struct fixed31_32 arg1, 426{
426 struct fixed31_32 arg2); 427 return dc_fixpt_exp(
428 dc_fixpt_mul(
429 dc_fixpt_log(arg1),
430 arg2));
431}
427 432
428/* 433/*
429 * @brief 434 * @brief
@@ -434,22 +439,56 @@ struct fixed31_32 dal_fixed31_32_pow(
434 * @brief 439 * @brief
435 * result = floor(arg) := greatest integer lower than or equal to arg 440 * result = floor(arg) := greatest integer lower than or equal to arg
436 */ 441 */
437int32_t dal_fixed31_32_floor( 442static inline int dc_fixpt_floor(struct fixed31_32 arg)
438 struct fixed31_32 arg); 443{
444 unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
445
446 if (arg.value >= 0)
447 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
448 else
449 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
450}
439 451
440/* 452/*
441 * @brief 453 * @brief
442 * result = round(arg) := integer nearest to arg 454 * result = round(arg) := integer nearest to arg
443 */ 455 */
444int32_t dal_fixed31_32_round( 456static inline int dc_fixpt_round(struct fixed31_32 arg)
445 struct fixed31_32 arg); 457{
458 unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
459
460 const long long summand = dc_fixpt_half.value;
461
462 ASSERT(LLONG_MAX - (long long)arg_value >= summand);
463
464 arg_value += summand;
465
466 if (arg.value >= 0)
467 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
468 else
469 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
470}
446 471
447/* 472/*
448 * @brief 473 * @brief
449 * result = ceil(arg) := lowest integer greater than or equal to arg 474 * result = ceil(arg) := lowest integer greater than or equal to arg
450 */ 475 */
451int32_t dal_fixed31_32_ceil( 476static inline int dc_fixpt_ceil(struct fixed31_32 arg)
452 struct fixed31_32 arg); 477{
478 unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
479
480 const long long summand = dc_fixpt_one.value -
481 dc_fixpt_epsilon.value;
482
483 ASSERT(LLONG_MAX - (long long)arg_value >= summand);
484
485 arg_value += summand;
486
487 if (arg.value >= 0)
488 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
489 else
490 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
491}
453 492
454/* the following two function are used in scaler hw programming to convert fixed 493/* the following two function are used in scaler hw programming to convert fixed
455 * point value to format 2 bits from integer part and 19 bits from fractional 494 * point value to format 2 bits from integer part and 19 bits from fractional
@@ -457,20 +496,31 @@ int32_t dal_fixed31_32_ceil(
457 * fractional 496 * fractional
458 */ 497 */
459 498
460uint32_t dal_fixed31_32_u2d19( 499unsigned int dc_fixpt_u2d19(struct fixed31_32 arg);
461 struct fixed31_32 arg); 500
501unsigned int dc_fixpt_u0d19(struct fixed31_32 arg);
462 502
463uint32_t dal_fixed31_32_u0d19( 503unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg);
464 struct fixed31_32 arg);
465 504
505unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg);
466 506
467uint32_t dal_fixed31_32_clamp_u0d14( 507int dc_fixpt_s4d19(struct fixed31_32 arg);
468 struct fixed31_32 arg);
469 508
470uint32_t dal_fixed31_32_clamp_u0d10( 509static inline struct fixed31_32 dc_fixpt_truncate(struct fixed31_32 arg, unsigned int frac_bits)
471 struct fixed31_32 arg); 510{
511 bool negative = arg.value < 0;
472 512
473int32_t dal_fixed31_32_s4d19( 513 if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
474 struct fixed31_32 arg); 514 ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART);
515 return arg;
516 }
517
518 if (negative)
519 arg.value = -arg.value;
520 arg.value &= (~0LL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
521 if (negative)
522 arg.value = -arg.value;
523 return arg;
524}
475 525
476#endif 526#endif
diff --git a/drivers/gpu/drm/amd/display/include/fixed32_32.h b/drivers/gpu/drm/amd/display/include/fixed32_32.h
deleted file mode 100644
index 9c70341fe026..000000000000
--- a/drivers/gpu/drm/amd/display/include/fixed32_32.h
+++ /dev/null
@@ -1,129 +0,0 @@
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26
27#ifndef __DAL_FIXED32_32_H__
28#define __DAL_FIXED32_32_H__
29
30#include "os_types.h"
31
32struct fixed32_32 {
33 uint64_t value;
34};
35
36static const struct fixed32_32 dal_fixed32_32_zero = { 0 };
37static const struct fixed32_32 dal_fixed32_32_one = { 0x100000000LL };
38static const struct fixed32_32 dal_fixed32_32_half = { 0x80000000LL };
39
40struct fixed32_32 dal_fixed32_32_from_fraction(uint32_t n, uint32_t d);
41static inline struct fixed32_32 dal_fixed32_32_from_int(uint32_t value)
42{
43 struct fixed32_32 fx;
44
45 fx.value = (uint64_t)value<<32;
46 return fx;
47}
48
49struct fixed32_32 dal_fixed32_32_add(
50 struct fixed32_32 lhs,
51 struct fixed32_32 rhs);
52struct fixed32_32 dal_fixed32_32_add_int(
53 struct fixed32_32 lhs,
54 uint32_t rhs);
55struct fixed32_32 dal_fixed32_32_sub(
56 struct fixed32_32 lhs,
57 struct fixed32_32 rhs);
58struct fixed32_32 dal_fixed32_32_sub_int(
59 struct fixed32_32 lhs,
60 uint32_t rhs);
61struct fixed32_32 dal_fixed32_32_mul(
62 struct fixed32_32 lhs,
63 struct fixed32_32 rhs);
64struct fixed32_32 dal_fixed32_32_mul_int(
65 struct fixed32_32 lhs,
66 uint32_t rhs);
67struct fixed32_32 dal_fixed32_32_div(
68 struct fixed32_32 lhs,
69 struct fixed32_32 rhs);
70struct fixed32_32 dal_fixed32_32_div_int(
71 struct fixed32_32 lhs,
72 uint32_t rhs);
73
74static inline struct fixed32_32 dal_fixed32_32_min(struct fixed32_32 lhs,
75 struct fixed32_32 rhs)
76{
77 return (lhs.value < rhs.value) ? lhs : rhs;
78}
79
80static inline struct fixed32_32 dal_fixed32_32_max(struct fixed32_32 lhs,
81 struct fixed32_32 rhs)
82{
83 return (lhs.value > rhs.value) ? lhs : rhs;
84}
85
86static inline bool dal_fixed32_32_gt(struct fixed32_32 lhs, struct fixed32_32 rhs)
87{
88 return lhs.value > rhs.value;
89}
90
91static inline bool dal_fixed32_32_gt_int(struct fixed32_32 lhs, uint32_t rhs)
92{
93 return lhs.value > ((uint64_t)rhs<<32);
94}
95
96static inline bool dal_fixed32_32_lt(struct fixed32_32 lhs, struct fixed32_32 rhs)
97{
98 return lhs.value < rhs.value;
99}
100
101static inline bool dal_fixed32_32_lt_int(struct fixed32_32 lhs, uint32_t rhs)
102{
103 return lhs.value < ((uint64_t)rhs<<32);
104}
105
106static inline bool dal_fixed32_32_le(struct fixed32_32 lhs, struct fixed32_32 rhs)
107{
108 return lhs.value <= rhs.value;
109}
110
111static inline bool dal_fixed32_32_le_int(struct fixed32_32 lhs, uint32_t rhs)
112{
113 return lhs.value <= ((uint64_t)rhs<<32);
114}
115
116static inline bool dal_fixed32_32_eq(struct fixed32_32 lhs, struct fixed32_32 rhs)
117{
118 return lhs.value == rhs.value;
119}
120
121uint32_t dal_fixed32_32_ceil(struct fixed32_32 value);
122static inline uint32_t dal_fixed32_32_floor(struct fixed32_32 value)
123{
124 return value.value>>32;
125}
126
127uint32_t dal_fixed32_32_round(struct fixed32_32 value);
128
129#endif
diff --git a/drivers/gpu/drm/amd/display/include/logger_interface.h b/drivers/gpu/drm/amd/display/include/logger_interface.h
index 28dee960d509..dc98d6d4b2bd 100644
--- a/drivers/gpu/drm/amd/display/include/logger_interface.h
+++ b/drivers/gpu/drm/amd/display/include/logger_interface.h
@@ -190,4 +190,13 @@ void context_clock_trace(
190 } \ 190 } \
191} while (0) 191} while (0)
192 192
193#define DISPLAY_STATS_BEGIN(entry) \
194 dm_logger_open(dc->ctx->logger, &entry, LOG_DISPLAYSTATS)
195
196#define DISPLAY_STATS(msg, ...) \
197 dm_logger_append(&log_entry, msg, ##__VA_ARGS__)
198
199#define DISPLAY_STATS_END(entry) \
200 dm_logger_close(&entry)
201
193#endif /* __DAL_LOGGER_INTERFACE_H__ */ 202#endif /* __DAL_LOGGER_INTERFACE_H__ */
diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h
index 427796bdc14a..0a540b9897a6 100644
--- a/drivers/gpu/drm/amd/display/include/logger_types.h
+++ b/drivers/gpu/drm/amd/display/include/logger_types.h
@@ -29,39 +29,39 @@
29#include "os_types.h" 29#include "os_types.h"
30 30
31#define MAX_NAME_LEN 32 31#define MAX_NAME_LEN 32
32#define DC_LOG_ERROR(a, ...) dm_logger_write(DC_LOGGER, LOG_ERROR, a, ## __VA_ARGS__)
33#define DC_LOG_WARNING(a, ...) dm_logger_write(DC_LOGGER, LOG_WARNING, a, ## __VA_ARGS__)
34#define DC_LOG_DEBUG(a, ...) dm_logger_write(DC_LOGGER, LOG_DEBUG, a, ## __VA_ARGS__)
35#define DC_LOG_DC(a, ...) dm_logger_write(DC_LOGGER, LOG_DC, a, ## __VA_ARGS__)
36#define DC_LOG_DTN(a, ...) dm_logger_write(DC_LOGGER, LOG_DTN, a, ## __VA_ARGS__)
37#define DC_LOG_SURFACE(a, ...) dm_logger_write(DC_LOGGER, LOG_SURFACE, a, ## __VA_ARGS__)
38#define DC_LOG_HW_HOTPLUG(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_HOTPLUG, a, ## __VA_ARGS__)
39#define DC_LOG_HW_LINK_TRAINING(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_LINK_TRAINING, a, ## __VA_ARGS__)
40#define DC_LOG_HW_SET_MODE(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_SET_MODE, a, ## __VA_ARGS__)
41#define DC_LOG_HW_RESUME_S3(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_RESUME_S3, a, ## __VA_ARGS__)
42#define DC_LOG_HW_AUDIO(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_AUDIO, a, ## __VA_ARGS__)
43#define DC_LOG_HW_HPD_IRQ(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_HPD_IRQ, a, ## __VA_ARGS__)
44#define DC_LOG_MST(a, ...) dm_logger_write(DC_LOGGER, LOG_MST, a, ## __VA_ARGS__)
45#define DC_LOG_SCALER(a, ...) dm_logger_write(DC_LOGGER, LOG_SCALER, a, ## __VA_ARGS__)
46#define DC_LOG_BIOS(a, ...) dm_logger_write(DC_LOGGER, LOG_BIOS, a, ## __VA_ARGS__)
47#define DC_LOG_BANDWIDTH_CALCS(a, ...) dm_logger_write(DC_LOGGER, LOG_BANDWIDTH_CALCS, a, ## __VA_ARGS__)
48#define DC_LOG_BANDWIDTH_VALIDATION(a, ...) dm_logger_write(DC_LOGGER, LOG_BANDWIDTH_VALIDATION, a, ## __VA_ARGS__)
49#define DC_LOG_I2C_AUX(a, ...) dm_logger_write(DC_LOGGER, LOG_I2C_AUX, a, ## __VA_ARGS__)
50#define DC_LOG_SYNC(a, ...) dm_logger_write(DC_LOGGER, LOG_SYNC, a, ## __VA_ARGS__)
51#define DC_LOG_BACKLIGHT(a, ...) dm_logger_write(DC_LOGGER, LOG_BACKLIGHT, a, ## __VA_ARGS__)
52#define DC_LOG_FEATURE_OVERRIDE(a, ...) dm_logger_write(DC_LOGGER, LOG_FEATURE_OVERRIDE, a, ## __VA_ARGS__)
53#define DC_LOG_DETECTION_EDID_PARSER(a, ...) dm_logger_write(DC_LOGGER, LOG_DETECTION_EDID_PARSER, a, ## __VA_ARGS__)
54#define DC_LOG_DETECTION_DP_CAPS(a, ...) dm_logger_write(DC_LOGGER, LOG_DETECTION_DP_CAPS, a, ## __VA_ARGS__)
55#define DC_LOG_RESOURCE(a, ...) dm_logger_write(DC_LOGGER, LOG_RESOURCE, a, ## __VA_ARGS__)
56#define DC_LOG_DML(a, ...) dm_logger_write(DC_LOGGER, LOG_DML, a, ## __VA_ARGS__)
57#define DC_LOG_EVENT_MODE_SET(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_MODE_SET, a, ## __VA_ARGS__)
58#define DC_LOG_EVENT_DETECTION(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_DETECTION, a, ## __VA_ARGS__)
59#define DC_LOG_EVENT_LINK_TRAINING(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_LINK_TRAINING, a, ## __VA_ARGS__)
60#define DC_LOG_EVENT_LINK_LOSS(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_LINK_LOSS, a, ## __VA_ARGS__)
61#define DC_LOG_EVENT_UNDERFLOW(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_UNDERFLOW, a, ## __VA_ARGS__)
62#define DC_LOG_IF_TRACE(a, ...) dm_logger_write(DC_LOGGER, LOG_IF_TRACE, a, ## __VA_ARGS__)
63#define DC_LOG_PERF_TRACE(a, ...) dm_logger_write(DC_LOGGER, LOG_PERF_TRACE, a, ## __VA_ARGS__)
64 32
33#define DC_LOG_ERROR(...) DRM_ERROR(__VA_ARGS__)
34#define DC_LOG_WARNING(...) DRM_WARN(__VA_ARGS__)
35#define DC_LOG_DEBUG(...) DRM_DEBUG_KMS(__VA_ARGS__)
36#define DC_LOG_DC(...) DRM_DEBUG_KMS(__VA_ARGS__)
37#define DC_LOG_DTN(...) DRM_DEBUG_KMS(__VA_ARGS__)
38#define DC_LOG_SURFACE(...) pr_debug("[SURFACE]:"__VA_ARGS__)
39#define DC_LOG_HW_HOTPLUG(...) DRM_DEBUG_KMS(__VA_ARGS__)
40#define DC_LOG_HW_LINK_TRAINING(...) pr_debug("[HW_LINK_TRAINING]:"__VA_ARGS__)
41#define DC_LOG_HW_SET_MODE(...) DRM_DEBUG_KMS(__VA_ARGS__)
42#define DC_LOG_HW_RESUME_S3(...) DRM_DEBUG_KMS(__VA_ARGS__)
43#define DC_LOG_HW_AUDIO(...) pr_debug("[HW_AUDIO]:"__VA_ARGS__)
44#define DC_LOG_HW_HPD_IRQ(...) DRM_DEBUG_KMS(__VA_ARGS__)
45#define DC_LOG_MST(...) DRM_DEBUG_KMS(__VA_ARGS__)
46#define DC_LOG_SCALER(...) pr_debug("[SCALER]:"__VA_ARGS__)
47#define DC_LOG_BIOS(...) pr_debug("[BIOS]:"__VA_ARGS__)
48#define DC_LOG_BANDWIDTH_CALCS(...) pr_debug("[BANDWIDTH_CALCS]:"__VA_ARGS__)
49#define DC_LOG_BANDWIDTH_VALIDATION(...) DRM_DEBUG_KMS(__VA_ARGS__)
50#define DC_LOG_I2C_AUX(...) DRM_DEBUG_KMS(__VA_ARGS__)
51#define DC_LOG_SYNC(...) DRM_DEBUG_KMS(__VA_ARGS__)
52#define DC_LOG_BACKLIGHT(...) DRM_DEBUG_KMS(__VA_ARGS__)
53#define DC_LOG_FEATURE_OVERRIDE(...) DRM_DEBUG_KMS(__VA_ARGS__)
54#define DC_LOG_DETECTION_EDID_PARSER(...) DRM_DEBUG_KMS(__VA_ARGS__)
55#define DC_LOG_DETECTION_DP_CAPS(...) DRM_DEBUG_KMS(__VA_ARGS__)
56#define DC_LOG_RESOURCE(...) DRM_DEBUG_KMS(__VA_ARGS__)
57#define DC_LOG_DML(...) pr_debug("[DML]:"__VA_ARGS__)
58#define DC_LOG_EVENT_MODE_SET(...) DRM_DEBUG_KMS(__VA_ARGS__)
59#define DC_LOG_EVENT_DETECTION(...) DRM_DEBUG_KMS(__VA_ARGS__)
60#define DC_LOG_EVENT_LINK_TRAINING(...) DRM_DEBUG_KMS(__VA_ARGS__)
61#define DC_LOG_EVENT_LINK_LOSS(...) DRM_DEBUG_KMS(__VA_ARGS__)
62#define DC_LOG_EVENT_UNDERFLOW(...) DRM_DEBUG_KMS(__VA_ARGS__)
63#define DC_LOG_IF_TRACE(...) pr_debug("[IF_TRACE]:"__VA_ARGS__)
64#define DC_LOG_PERF_TRACE(...) DRM_DEBUG_KMS(__VA_ARGS__)
65 65
66struct dal_logger; 66struct dal_logger;
67 67
@@ -98,7 +98,7 @@ enum dc_log_type {
98 LOG_EVENT_UNDERFLOW, 98 LOG_EVENT_UNDERFLOW,
99 LOG_IF_TRACE, 99 LOG_IF_TRACE,
100 LOG_PERF_TRACE, 100 LOG_PERF_TRACE,
101 LOG_PROFILING, 101 LOG_DISPLAYSTATS,
102 102
103 LOG_SECTION_TOTAL_COUNT 103 LOG_SECTION_TOTAL_COUNT
104}; 104};
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index b3747a019deb..0cd111d59018 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -43,7 +43,7 @@ static bool de_pq_initialized; /* = false; */
43/* one-time setup of X points */ 43/* one-time setup of X points */
44void setup_x_points_distribution(void) 44void setup_x_points_distribution(void)
45{ 45{
46 struct fixed31_32 region_size = dal_fixed31_32_from_int(128); 46 struct fixed31_32 region_size = dc_fixpt_from_int(128);
47 int32_t segment; 47 int32_t segment;
48 uint32_t seg_offset; 48 uint32_t seg_offset;
49 uint32_t index; 49 uint32_t index;
@@ -53,8 +53,8 @@ void setup_x_points_distribution(void)
53 coordinates_x[MAX_HW_POINTS + 1].x = region_size; 53 coordinates_x[MAX_HW_POINTS + 1].x = region_size;
54 54
55 for (segment = 6; segment > (6 - NUM_REGIONS); segment--) { 55 for (segment = 6; segment > (6 - NUM_REGIONS); segment--) {
56 region_size = dal_fixed31_32_div_int(region_size, 2); 56 region_size = dc_fixpt_div_int(region_size, 2);
57 increment = dal_fixed31_32_div_int(region_size, 57 increment = dc_fixpt_div_int(region_size,
58 NUM_PTS_IN_REGION); 58 NUM_PTS_IN_REGION);
59 seg_offset = (segment + (NUM_REGIONS - 7)) * NUM_PTS_IN_REGION; 59 seg_offset = (segment + (NUM_REGIONS - 7)) * NUM_PTS_IN_REGION;
60 coordinates_x[seg_offset].x = region_size; 60 coordinates_x[seg_offset].x = region_size;
@@ -62,7 +62,7 @@ void setup_x_points_distribution(void)
62 for (index = seg_offset + 1; 62 for (index = seg_offset + 1;
63 index < seg_offset + NUM_PTS_IN_REGION; 63 index < seg_offset + NUM_PTS_IN_REGION;
64 index++) { 64 index++) {
65 coordinates_x[index].x = dal_fixed31_32_add 65 coordinates_x[index].x = dc_fixpt_add
66 (coordinates_x[index-1].x, increment); 66 (coordinates_x[index-1].x, increment);
67 } 67 }
68 } 68 }
@@ -72,63 +72,63 @@ static void compute_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y)
72{ 72{
73 /* consts for PQ gamma formula. */ 73 /* consts for PQ gamma formula. */
74 const struct fixed31_32 m1 = 74 const struct fixed31_32 m1 =
75 dal_fixed31_32_from_fraction(159301758, 1000000000); 75 dc_fixpt_from_fraction(159301758, 1000000000);
76 const struct fixed31_32 m2 = 76 const struct fixed31_32 m2 =
77 dal_fixed31_32_from_fraction(7884375, 100000); 77 dc_fixpt_from_fraction(7884375, 100000);
78 const struct fixed31_32 c1 = 78 const struct fixed31_32 c1 =
79 dal_fixed31_32_from_fraction(8359375, 10000000); 79 dc_fixpt_from_fraction(8359375, 10000000);
80 const struct fixed31_32 c2 = 80 const struct fixed31_32 c2 =
81 dal_fixed31_32_from_fraction(188515625, 10000000); 81 dc_fixpt_from_fraction(188515625, 10000000);
82 const struct fixed31_32 c3 = 82 const struct fixed31_32 c3 =
83 dal_fixed31_32_from_fraction(186875, 10000); 83 dc_fixpt_from_fraction(186875, 10000);
84 84
85 struct fixed31_32 l_pow_m1; 85 struct fixed31_32 l_pow_m1;
86 struct fixed31_32 base; 86 struct fixed31_32 base;
87 87
88 if (dal_fixed31_32_lt(in_x, dal_fixed31_32_zero)) 88 if (dc_fixpt_lt(in_x, dc_fixpt_zero))
89 in_x = dal_fixed31_32_zero; 89 in_x = dc_fixpt_zero;
90 90
91 l_pow_m1 = dal_fixed31_32_pow(in_x, m1); 91 l_pow_m1 = dc_fixpt_pow(in_x, m1);
92 base = dal_fixed31_32_div( 92 base = dc_fixpt_div(
93 dal_fixed31_32_add(c1, 93 dc_fixpt_add(c1,
94 (dal_fixed31_32_mul(c2, l_pow_m1))), 94 (dc_fixpt_mul(c2, l_pow_m1))),
95 dal_fixed31_32_add(dal_fixed31_32_one, 95 dc_fixpt_add(dc_fixpt_one,
96 (dal_fixed31_32_mul(c3, l_pow_m1)))); 96 (dc_fixpt_mul(c3, l_pow_m1))));
97 *out_y = dal_fixed31_32_pow(base, m2); 97 *out_y = dc_fixpt_pow(base, m2);
98} 98}
99 99
100static void compute_de_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y) 100static void compute_de_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y)
101{ 101{
102 /* consts for dePQ gamma formula. */ 102 /* consts for dePQ gamma formula. */
103 const struct fixed31_32 m1 = 103 const struct fixed31_32 m1 =
104 dal_fixed31_32_from_fraction(159301758, 1000000000); 104 dc_fixpt_from_fraction(159301758, 1000000000);
105 const struct fixed31_32 m2 = 105 const struct fixed31_32 m2 =
106 dal_fixed31_32_from_fraction(7884375, 100000); 106 dc_fixpt_from_fraction(7884375, 100000);
107 const struct fixed31_32 c1 = 107 const struct fixed31_32 c1 =
108 dal_fixed31_32_from_fraction(8359375, 10000000); 108 dc_fixpt_from_fraction(8359375, 10000000);
109 const struct fixed31_32 c2 = 109 const struct fixed31_32 c2 =
110 dal_fixed31_32_from_fraction(188515625, 10000000); 110 dc_fixpt_from_fraction(188515625, 10000000);
111 const struct fixed31_32 c3 = 111 const struct fixed31_32 c3 =
112 dal_fixed31_32_from_fraction(186875, 10000); 112 dc_fixpt_from_fraction(186875, 10000);
113 113
114 struct fixed31_32 l_pow_m1; 114 struct fixed31_32 l_pow_m1;
115 struct fixed31_32 base, div; 115 struct fixed31_32 base, div;
116 116
117 117
118 if (dal_fixed31_32_lt(in_x, dal_fixed31_32_zero)) 118 if (dc_fixpt_lt(in_x, dc_fixpt_zero))
119 in_x = dal_fixed31_32_zero; 119 in_x = dc_fixpt_zero;
120 120
121 l_pow_m1 = dal_fixed31_32_pow(in_x, 121 l_pow_m1 = dc_fixpt_pow(in_x,
122 dal_fixed31_32_div(dal_fixed31_32_one, m2)); 122 dc_fixpt_div(dc_fixpt_one, m2));
123 base = dal_fixed31_32_sub(l_pow_m1, c1); 123 base = dc_fixpt_sub(l_pow_m1, c1);
124 124
125 if (dal_fixed31_32_lt(base, dal_fixed31_32_zero)) 125 if (dc_fixpt_lt(base, dc_fixpt_zero))
126 base = dal_fixed31_32_zero; 126 base = dc_fixpt_zero;
127 127
128 div = dal_fixed31_32_sub(c2, dal_fixed31_32_mul(c3, l_pow_m1)); 128 div = dc_fixpt_sub(c2, dc_fixpt_mul(c3, l_pow_m1));
129 129
130 *out_y = dal_fixed31_32_pow(dal_fixed31_32_div(base, div), 130 *out_y = dc_fixpt_pow(dc_fixpt_div(base, div),
131 dal_fixed31_32_div(dal_fixed31_32_one, m1)); 131 dc_fixpt_div(dc_fixpt_one, m1));
132 132
133} 133}
134/* one-time pre-compute PQ values - only for sdr_white_level 80 */ 134/* one-time pre-compute PQ values - only for sdr_white_level 80 */
@@ -138,14 +138,14 @@ void precompute_pq(void)
138 struct fixed31_32 x; 138 struct fixed31_32 x;
139 const struct hw_x_point *coord_x = coordinates_x + 32; 139 const struct hw_x_point *coord_x = coordinates_x + 32;
140 struct fixed31_32 scaling_factor = 140 struct fixed31_32 scaling_factor =
141 dal_fixed31_32_from_fraction(80, 10000); 141 dc_fixpt_from_fraction(80, 10000);
142 142
143 /* pow function has problems with arguments too small */ 143 /* pow function has problems with arguments too small */
144 for (i = 0; i < 32; i++) 144 for (i = 0; i < 32; i++)
145 pq_table[i] = dal_fixed31_32_zero; 145 pq_table[i] = dc_fixpt_zero;
146 146
147 for (i = 32; i <= MAX_HW_POINTS; i++) { 147 for (i = 32; i <= MAX_HW_POINTS; i++) {
148 x = dal_fixed31_32_mul(coord_x->x, scaling_factor); 148 x = dc_fixpt_mul(coord_x->x, scaling_factor);
149 compute_pq(x, &pq_table[i]); 149 compute_pq(x, &pq_table[i]);
150 ++coord_x; 150 ++coord_x;
151 } 151 }
@@ -158,7 +158,7 @@ void precompute_de_pq(void)
158 struct fixed31_32 y; 158 struct fixed31_32 y;
159 uint32_t begin_index, end_index; 159 uint32_t begin_index, end_index;
160 160
161 struct fixed31_32 scaling_factor = dal_fixed31_32_from_int(125); 161 struct fixed31_32 scaling_factor = dc_fixpt_from_int(125);
162 162
163 /* X points is 2^-25 to 2^7 163 /* X points is 2^-25 to 2^7
164 * De-gamma X is 2^-12 to 2^0 – we are skipping first -12-(-25) = 13 regions 164 * De-gamma X is 2^-12 to 2^0 – we are skipping first -12-(-25) = 13 regions
@@ -167,11 +167,11 @@ void precompute_de_pq(void)
167 end_index = begin_index + 12 * NUM_PTS_IN_REGION; 167 end_index = begin_index + 12 * NUM_PTS_IN_REGION;
168 168
169 for (i = 0; i <= begin_index; i++) 169 for (i = 0; i <= begin_index; i++)
170 de_pq_table[i] = dal_fixed31_32_zero; 170 de_pq_table[i] = dc_fixpt_zero;
171 171
172 for (; i <= end_index; i++) { 172 for (; i <= end_index; i++) {
173 compute_de_pq(coordinates_x[i].x, &y); 173 compute_de_pq(coordinates_x[i].x, &y);
174 de_pq_table[i] = dal_fixed31_32_mul(y, scaling_factor); 174 de_pq_table[i] = dc_fixpt_mul(y, scaling_factor);
175 } 175 }
176 176
177 for (; i <= MAX_HW_POINTS; i++) 177 for (; i <= MAX_HW_POINTS; i++)
@@ -185,25 +185,25 @@ struct dividers {
185 185
186static void build_coefficients(struct gamma_coefficients *coefficients, bool is_2_4) 186static void build_coefficients(struct gamma_coefficients *coefficients, bool is_2_4)
187{ 187{
188 static const int32_t numerator01[] = { 31308, 180000}; 188 static const int32_t numerator01[] = { 31308, 180000};
189 static const int32_t numerator02[] = { 12920, 4500}; 189 static const int32_t numerator02[] = { 12920, 4500};
190 static const int32_t numerator03[] = { 55, 99}; 190 static const int32_t numerator03[] = { 55, 99};
191 static const int32_t numerator04[] = { 55, 99}; 191 static const int32_t numerator04[] = { 55, 99};
192 static const int32_t numerator05[] = { 2400, 2200}; 192 static const int32_t numerator05[] = { 2400, 2200};
193 193
194 uint32_t i = 0; 194 uint32_t i = 0;
195 uint32_t index = is_2_4 == true ? 0:1; 195 uint32_t index = is_2_4 == true ? 0:1;
196 196
197 do { 197 do {
198 coefficients->a0[i] = dal_fixed31_32_from_fraction( 198 coefficients->a0[i] = dc_fixpt_from_fraction(
199 numerator01[index], 10000000); 199 numerator01[index], 10000000);
200 coefficients->a1[i] = dal_fixed31_32_from_fraction( 200 coefficients->a1[i] = dc_fixpt_from_fraction(
201 numerator02[index], 1000); 201 numerator02[index], 1000);
202 coefficients->a2[i] = dal_fixed31_32_from_fraction( 202 coefficients->a2[i] = dc_fixpt_from_fraction(
203 numerator03[index], 1000); 203 numerator03[index], 1000);
204 coefficients->a3[i] = dal_fixed31_32_from_fraction( 204 coefficients->a3[i] = dc_fixpt_from_fraction(
205 numerator04[index], 1000); 205 numerator04[index], 1000);
206 coefficients->user_gamma[i] = dal_fixed31_32_from_fraction( 206 coefficients->user_gamma[i] = dc_fixpt_from_fraction(
207 numerator05[index], 1000); 207 numerator05[index], 1000);
208 208
209 ++i; 209 ++i;
@@ -218,33 +218,33 @@ static struct fixed31_32 translate_from_linear_space(
218 struct fixed31_32 a3, 218 struct fixed31_32 a3,
219 struct fixed31_32 gamma) 219 struct fixed31_32 gamma)
220{ 220{
221 const struct fixed31_32 one = dal_fixed31_32_from_int(1); 221 const struct fixed31_32 one = dc_fixpt_from_int(1);
222 222
223 if (dal_fixed31_32_lt(one, arg)) 223 if (dc_fixpt_lt(one, arg))
224 return one; 224 return one;
225 225
226 if (dal_fixed31_32_le(arg, dal_fixed31_32_neg(a0))) 226 if (dc_fixpt_le(arg, dc_fixpt_neg(a0)))
227 return dal_fixed31_32_sub( 227 return dc_fixpt_sub(
228 a2, 228 a2,
229 dal_fixed31_32_mul( 229 dc_fixpt_mul(
230 dal_fixed31_32_add( 230 dc_fixpt_add(
231 one, 231 one,
232 a3), 232 a3),
233 dal_fixed31_32_pow( 233 dc_fixpt_pow(
234 dal_fixed31_32_neg(arg), 234 dc_fixpt_neg(arg),
235 dal_fixed31_32_recip(gamma)))); 235 dc_fixpt_recip(gamma))));
236 else if (dal_fixed31_32_le(a0, arg)) 236 else if (dc_fixpt_le(a0, arg))
237 return dal_fixed31_32_sub( 237 return dc_fixpt_sub(
238 dal_fixed31_32_mul( 238 dc_fixpt_mul(
239 dal_fixed31_32_add( 239 dc_fixpt_add(
240 one, 240 one,
241 a3), 241 a3),
242 dal_fixed31_32_pow( 242 dc_fixpt_pow(
243 arg, 243 arg,
244 dal_fixed31_32_recip(gamma))), 244 dc_fixpt_recip(gamma))),
245 a2); 245 a2);
246 else 246 else
247 return dal_fixed31_32_mul( 247 return dc_fixpt_mul(
248 arg, 248 arg,
249 a1); 249 a1);
250} 250}
@@ -259,25 +259,25 @@ static struct fixed31_32 translate_to_linear_space(
259{ 259{
260 struct fixed31_32 linear; 260 struct fixed31_32 linear;
261 261
262 a0 = dal_fixed31_32_mul(a0, a1); 262 a0 = dc_fixpt_mul(a0, a1);
263 if (dal_fixed31_32_le(arg, dal_fixed31_32_neg(a0))) 263 if (dc_fixpt_le(arg, dc_fixpt_neg(a0)))
264 264
265 linear = dal_fixed31_32_neg( 265 linear = dc_fixpt_neg(
266 dal_fixed31_32_pow( 266 dc_fixpt_pow(
267 dal_fixed31_32_div( 267 dc_fixpt_div(
268 dal_fixed31_32_sub(a2, arg), 268 dc_fixpt_sub(a2, arg),
269 dal_fixed31_32_add( 269 dc_fixpt_add(
270 dal_fixed31_32_one, a3)), gamma)); 270 dc_fixpt_one, a3)), gamma));
271 271
272 else if (dal_fixed31_32_le(dal_fixed31_32_neg(a0), arg) && 272 else if (dc_fixpt_le(dc_fixpt_neg(a0), arg) &&
273 dal_fixed31_32_le(arg, a0)) 273 dc_fixpt_le(arg, a0))
274 linear = dal_fixed31_32_div(arg, a1); 274 linear = dc_fixpt_div(arg, a1);
275 else 275 else
276 linear = dal_fixed31_32_pow( 276 linear = dc_fixpt_pow(
277 dal_fixed31_32_div( 277 dc_fixpt_div(
278 dal_fixed31_32_add(a2, arg), 278 dc_fixpt_add(a2, arg),
279 dal_fixed31_32_add( 279 dc_fixpt_add(
280 dal_fixed31_32_one, a3)), gamma); 280 dc_fixpt_one, a3)), gamma);
281 281
282 return linear; 282 return linear;
283} 283}
@@ -352,8 +352,8 @@ static bool find_software_points(
352 right = axis_x[max_number - 1].b; 352 right = axis_x[max_number - 1].b;
353 } 353 }
354 354
355 if (dal_fixed31_32_le(left, hw_point) && 355 if (dc_fixpt_le(left, hw_point) &&
356 dal_fixed31_32_le(hw_point, right)) { 356 dc_fixpt_le(hw_point, right)) {
357 *index_to_start = i; 357 *index_to_start = i;
358 *index_left = i; 358 *index_left = i;
359 359
@@ -366,7 +366,7 @@ static bool find_software_points(
366 366
367 return true; 367 return true;
368 } else if ((i == *index_to_start) && 368 } else if ((i == *index_to_start) &&
369 dal_fixed31_32_le(hw_point, left)) { 369 dc_fixpt_le(hw_point, left)) {
370 *index_to_start = i; 370 *index_to_start = i;
371 *index_left = i; 371 *index_left = i;
372 *index_right = i; 372 *index_right = i;
@@ -375,7 +375,7 @@ static bool find_software_points(
375 375
376 return true; 376 return true;
377 } else if ((i == max_number - 1) && 377 } else if ((i == max_number - 1) &&
378 dal_fixed31_32_le(right, hw_point)) { 378 dc_fixpt_le(right, hw_point)) {
379 *index_to_start = i; 379 *index_to_start = i;
380 *index_left = i; 380 *index_left = i;
381 *index_right = i; 381 *index_right = i;
@@ -457,17 +457,17 @@ static bool build_custom_gamma_mapping_coefficients_worker(
457 } 457 }
458 458
459 if (hw_pos == HW_POINT_POSITION_MIDDLE) 459 if (hw_pos == HW_POINT_POSITION_MIDDLE)
460 point->coeff = dal_fixed31_32_div( 460 point->coeff = dc_fixpt_div(
461 dal_fixed31_32_sub( 461 dc_fixpt_sub(
462 coord_x, 462 coord_x,
463 left_pos), 463 left_pos),
464 dal_fixed31_32_sub( 464 dc_fixpt_sub(
465 right_pos, 465 right_pos,
466 left_pos)); 466 left_pos));
467 else if (hw_pos == HW_POINT_POSITION_LEFT) 467 else if (hw_pos == HW_POINT_POSITION_LEFT)
468 point->coeff = dal_fixed31_32_zero; 468 point->coeff = dc_fixpt_zero;
469 else if (hw_pos == HW_POINT_POSITION_RIGHT) 469 else if (hw_pos == HW_POINT_POSITION_RIGHT)
470 point->coeff = dal_fixed31_32_from_int(2); 470 point->coeff = dc_fixpt_from_int(2);
471 else { 471 else {
472 BREAK_TO_DEBUGGER(); 472 BREAK_TO_DEBUGGER();
473 return false; 473 return false;
@@ -502,45 +502,45 @@ static struct fixed31_32 calculate_mapped_value(
502 502
503 if ((point->left_index < 0) || (point->left_index > max_index)) { 503 if ((point->left_index < 0) || (point->left_index > max_index)) {
504 BREAK_TO_DEBUGGER(); 504 BREAK_TO_DEBUGGER();
505 return dal_fixed31_32_zero; 505 return dc_fixpt_zero;
506 } 506 }
507 507
508 if ((point->right_index < 0) || (point->right_index > max_index)) { 508 if ((point->right_index < 0) || (point->right_index > max_index)) {
509 BREAK_TO_DEBUGGER(); 509 BREAK_TO_DEBUGGER();
510 return dal_fixed31_32_zero; 510 return dc_fixpt_zero;
511 } 511 }
512 512
513 if (point->pos == HW_POINT_POSITION_MIDDLE) 513 if (point->pos == HW_POINT_POSITION_MIDDLE)
514 if (channel == CHANNEL_NAME_RED) 514 if (channel == CHANNEL_NAME_RED)
515 result = dal_fixed31_32_add( 515 result = dc_fixpt_add(
516 dal_fixed31_32_mul( 516 dc_fixpt_mul(
517 point->coeff, 517 point->coeff,
518 dal_fixed31_32_sub( 518 dc_fixpt_sub(
519 rgb[point->right_index].r, 519 rgb[point->right_index].r,
520 rgb[point->left_index].r)), 520 rgb[point->left_index].r)),
521 rgb[point->left_index].r); 521 rgb[point->left_index].r);
522 else if (channel == CHANNEL_NAME_GREEN) 522 else if (channel == CHANNEL_NAME_GREEN)
523 result = dal_fixed31_32_add( 523 result = dc_fixpt_add(
524 dal_fixed31_32_mul( 524 dc_fixpt_mul(
525 point->coeff, 525 point->coeff,
526 dal_fixed31_32_sub( 526 dc_fixpt_sub(
527 rgb[point->right_index].g, 527 rgb[point->right_index].g,
528 rgb[point->left_index].g)), 528 rgb[point->left_index].g)),
529 rgb[point->left_index].g); 529 rgb[point->left_index].g);
530 else 530 else
531 result = dal_fixed31_32_add( 531 result = dc_fixpt_add(
532 dal_fixed31_32_mul( 532 dc_fixpt_mul(
533 point->coeff, 533 point->coeff,
534 dal_fixed31_32_sub( 534 dc_fixpt_sub(
535 rgb[point->right_index].b, 535 rgb[point->right_index].b,
536 rgb[point->left_index].b)), 536 rgb[point->left_index].b)),
537 rgb[point->left_index].b); 537 rgb[point->left_index].b);
538 else if (point->pos == HW_POINT_POSITION_LEFT) { 538 else if (point->pos == HW_POINT_POSITION_LEFT) {
539 BREAK_TO_DEBUGGER(); 539 BREAK_TO_DEBUGGER();
540 result = dal_fixed31_32_zero; 540 result = dc_fixpt_zero;
541 } else { 541 } else {
542 BREAK_TO_DEBUGGER(); 542 BREAK_TO_DEBUGGER();
543 result = dal_fixed31_32_one; 543 result = dc_fixpt_one;
544 } 544 }
545 545
546 return result; 546 return result;
@@ -558,7 +558,7 @@ static void build_pq(struct pwl_float_data_ex *rgb_regamma,
558 struct fixed31_32 x; 558 struct fixed31_32 x;
559 struct fixed31_32 output; 559 struct fixed31_32 output;
560 struct fixed31_32 scaling_factor = 560 struct fixed31_32 scaling_factor =
561 dal_fixed31_32_from_fraction(sdr_white_level, 10000); 561 dc_fixpt_from_fraction(sdr_white_level, 10000);
562 562
563 if (!pq_initialized && sdr_white_level == 80) { 563 if (!pq_initialized && sdr_white_level == 80) {
564 precompute_pq(); 564 precompute_pq();
@@ -579,15 +579,15 @@ static void build_pq(struct pwl_float_data_ex *rgb_regamma,
579 if (sdr_white_level == 80) { 579 if (sdr_white_level == 80) {
580 output = pq_table[i]; 580 output = pq_table[i];
581 } else { 581 } else {
582 x = dal_fixed31_32_mul(coord_x->x, scaling_factor); 582 x = dc_fixpt_mul(coord_x->x, scaling_factor);
583 compute_pq(x, &output); 583 compute_pq(x, &output);
584 } 584 }
585 585
586 /* should really not happen? */ 586 /* should really not happen? */
587 if (dal_fixed31_32_lt(output, dal_fixed31_32_zero)) 587 if (dc_fixpt_lt(output, dc_fixpt_zero))
588 output = dal_fixed31_32_zero; 588 output = dc_fixpt_zero;
589 else if (dal_fixed31_32_lt(dal_fixed31_32_one, output)) 589 else if (dc_fixpt_lt(dc_fixpt_one, output))
590 output = dal_fixed31_32_one; 590 output = dc_fixpt_one;
591 591
592 rgb->r = output; 592 rgb->r = output;
593 rgb->g = output; 593 rgb->g = output;
@@ -605,7 +605,7 @@ static void build_de_pq(struct pwl_float_data_ex *de_pq,
605 uint32_t i; 605 uint32_t i;
606 struct fixed31_32 output; 606 struct fixed31_32 output;
607 607
608 struct fixed31_32 scaling_factor = dal_fixed31_32_from_int(125); 608 struct fixed31_32 scaling_factor = dc_fixpt_from_int(125);
609 609
610 if (!de_pq_initialized) { 610 if (!de_pq_initialized) {
611 precompute_de_pq(); 611 precompute_de_pq();
@@ -616,9 +616,9 @@ static void build_de_pq(struct pwl_float_data_ex *de_pq,
616 for (i = 0; i <= hw_points_num; i++) { 616 for (i = 0; i <= hw_points_num; i++) {
617 output = de_pq_table[i]; 617 output = de_pq_table[i];
618 /* should really not happen? */ 618 /* should really not happen? */
619 if (dal_fixed31_32_lt(output, dal_fixed31_32_zero)) 619 if (dc_fixpt_lt(output, dc_fixpt_zero))
620 output = dal_fixed31_32_zero; 620 output = dc_fixpt_zero;
621 else if (dal_fixed31_32_lt(scaling_factor, output)) 621 else if (dc_fixpt_lt(scaling_factor, output))
622 output = scaling_factor; 622 output = scaling_factor;
623 de_pq[i].r = output; 623 de_pq[i].r = output;
624 de_pq[i].g = output; 624 de_pq[i].g = output;
@@ -670,9 +670,9 @@ static void build_degamma(struct pwl_float_data_ex *curve,
670 end_index = begin_index + 12 * NUM_PTS_IN_REGION; 670 end_index = begin_index + 12 * NUM_PTS_IN_REGION;
671 671
672 while (i != begin_index) { 672 while (i != begin_index) {
673 curve[i].r = dal_fixed31_32_zero; 673 curve[i].r = dc_fixpt_zero;
674 curve[i].g = dal_fixed31_32_zero; 674 curve[i].g = dc_fixpt_zero;
675 curve[i].b = dal_fixed31_32_zero; 675 curve[i].b = dc_fixpt_zero;
676 i++; 676 i++;
677 } 677 }
678 678
@@ -684,19 +684,19 @@ static void build_degamma(struct pwl_float_data_ex *curve,
684 i++; 684 i++;
685 } 685 }
686 while (i != hw_points_num + 1) { 686 while (i != hw_points_num + 1) {
687 curve[i].r = dal_fixed31_32_one; 687 curve[i].r = dc_fixpt_one;
688 curve[i].g = dal_fixed31_32_one; 688 curve[i].g = dc_fixpt_one;
689 curve[i].b = dal_fixed31_32_one; 689 curve[i].b = dc_fixpt_one;
690 i++; 690 i++;
691 } 691 }
692} 692}
693 693
694static bool scale_gamma(struct pwl_float_data *pwl_rgb, 694static void scale_gamma(struct pwl_float_data *pwl_rgb,
695 const struct dc_gamma *ramp, 695 const struct dc_gamma *ramp,
696 struct dividers dividers) 696 struct dividers dividers)
697{ 697{
698 const struct fixed31_32 max_driver = dal_fixed31_32_from_int(0xFFFF); 698 const struct fixed31_32 max_driver = dc_fixpt_from_int(0xFFFF);
699 const struct fixed31_32 max_os = dal_fixed31_32_from_int(0xFF00); 699 const struct fixed31_32 max_os = dc_fixpt_from_int(0xFF00);
700 struct fixed31_32 scaler = max_os; 700 struct fixed31_32 scaler = max_os;
701 uint32_t i; 701 uint32_t i;
702 struct pwl_float_data *rgb = pwl_rgb; 702 struct pwl_float_data *rgb = pwl_rgb;
@@ -705,9 +705,9 @@ static bool scale_gamma(struct pwl_float_data *pwl_rgb,
705 i = 0; 705 i = 0;
706 706
707 do { 707 do {
708 if (dal_fixed31_32_lt(max_os, ramp->entries.red[i]) || 708 if (dc_fixpt_lt(max_os, ramp->entries.red[i]) ||
709 dal_fixed31_32_lt(max_os, ramp->entries.green[i]) || 709 dc_fixpt_lt(max_os, ramp->entries.green[i]) ||
710 dal_fixed31_32_lt(max_os, ramp->entries.blue[i])) { 710 dc_fixpt_lt(max_os, ramp->entries.blue[i])) {
711 scaler = max_driver; 711 scaler = max_driver;
712 break; 712 break;
713 } 713 }
@@ -717,109 +717,170 @@ static bool scale_gamma(struct pwl_float_data *pwl_rgb,
717 i = 0; 717 i = 0;
718 718
719 do { 719 do {
720 rgb->r = dal_fixed31_32_div( 720 rgb->r = dc_fixpt_div(
721 ramp->entries.red[i], scaler); 721 ramp->entries.red[i], scaler);
722 rgb->g = dal_fixed31_32_div( 722 rgb->g = dc_fixpt_div(
723 ramp->entries.green[i], scaler); 723 ramp->entries.green[i], scaler);
724 rgb->b = dal_fixed31_32_div( 724 rgb->b = dc_fixpt_div(
725 ramp->entries.blue[i], scaler); 725 ramp->entries.blue[i], scaler);
726 726
727 ++rgb; 727 ++rgb;
728 ++i; 728 ++i;
729 } while (i != ramp->num_entries); 729 } while (i != ramp->num_entries);
730 730
731 rgb->r = dal_fixed31_32_mul(rgb_last->r, 731 rgb->r = dc_fixpt_mul(rgb_last->r,
732 dividers.divider1); 732 dividers.divider1);
733 rgb->g = dal_fixed31_32_mul(rgb_last->g, 733 rgb->g = dc_fixpt_mul(rgb_last->g,
734 dividers.divider1); 734 dividers.divider1);
735 rgb->b = dal_fixed31_32_mul(rgb_last->b, 735 rgb->b = dc_fixpt_mul(rgb_last->b,
736 dividers.divider1); 736 dividers.divider1);
737 737
738 ++rgb; 738 ++rgb;
739 739
740 rgb->r = dal_fixed31_32_mul(rgb_last->r, 740 rgb->r = dc_fixpt_mul(rgb_last->r,
741 dividers.divider2); 741 dividers.divider2);
742 rgb->g = dal_fixed31_32_mul(rgb_last->g, 742 rgb->g = dc_fixpt_mul(rgb_last->g,
743 dividers.divider2); 743 dividers.divider2);
744 rgb->b = dal_fixed31_32_mul(rgb_last->b, 744 rgb->b = dc_fixpt_mul(rgb_last->b,
745 dividers.divider2); 745 dividers.divider2);
746 746
747 ++rgb; 747 ++rgb;
748 748
749 rgb->r = dal_fixed31_32_mul(rgb_last->r, 749 rgb->r = dc_fixpt_mul(rgb_last->r,
750 dividers.divider3); 750 dividers.divider3);
751 rgb->g = dal_fixed31_32_mul(rgb_last->g, 751 rgb->g = dc_fixpt_mul(rgb_last->g,
752 dividers.divider3); 752 dividers.divider3);
753 rgb->b = dal_fixed31_32_mul(rgb_last->b, 753 rgb->b = dc_fixpt_mul(rgb_last->b,
754 dividers.divider3); 754 dividers.divider3);
755
756 return true;
757} 755}
758 756
759static bool scale_gamma_dx(struct pwl_float_data *pwl_rgb, 757static void scale_gamma_dx(struct pwl_float_data *pwl_rgb,
760 const struct dc_gamma *ramp, 758 const struct dc_gamma *ramp,
761 struct dividers dividers) 759 struct dividers dividers)
762{ 760{
763 uint32_t i; 761 uint32_t i;
764 struct fixed31_32 min = dal_fixed31_32_zero; 762 struct fixed31_32 min = dc_fixpt_zero;
765 struct fixed31_32 max = dal_fixed31_32_one; 763 struct fixed31_32 max = dc_fixpt_one;
766 764
767 struct fixed31_32 delta = dal_fixed31_32_zero; 765 struct fixed31_32 delta = dc_fixpt_zero;
768 struct fixed31_32 offset = dal_fixed31_32_zero; 766 struct fixed31_32 offset = dc_fixpt_zero;
769 767
770 for (i = 0 ; i < ramp->num_entries; i++) { 768 for (i = 0 ; i < ramp->num_entries; i++) {
771 if (dal_fixed31_32_lt(ramp->entries.red[i], min)) 769 if (dc_fixpt_lt(ramp->entries.red[i], min))
772 min = ramp->entries.red[i]; 770 min = ramp->entries.red[i];
773 771
774 if (dal_fixed31_32_lt(ramp->entries.green[i], min)) 772 if (dc_fixpt_lt(ramp->entries.green[i], min))
775 min = ramp->entries.green[i]; 773 min = ramp->entries.green[i];
776 774
777 if (dal_fixed31_32_lt(ramp->entries.blue[i], min)) 775 if (dc_fixpt_lt(ramp->entries.blue[i], min))
778 min = ramp->entries.blue[i]; 776 min = ramp->entries.blue[i];
779 777
780 if (dal_fixed31_32_lt(max, ramp->entries.red[i])) 778 if (dc_fixpt_lt(max, ramp->entries.red[i]))
781 max = ramp->entries.red[i]; 779 max = ramp->entries.red[i];
782 780
783 if (dal_fixed31_32_lt(max, ramp->entries.green[i])) 781 if (dc_fixpt_lt(max, ramp->entries.green[i]))
784 max = ramp->entries.green[i]; 782 max = ramp->entries.green[i];
785 783
786 if (dal_fixed31_32_lt(max, ramp->entries.blue[i])) 784 if (dc_fixpt_lt(max, ramp->entries.blue[i]))
787 max = ramp->entries.blue[i]; 785 max = ramp->entries.blue[i];
788 } 786 }
789 787
790 if (dal_fixed31_32_lt(min, dal_fixed31_32_zero)) 788 if (dc_fixpt_lt(min, dc_fixpt_zero))
791 delta = dal_fixed31_32_neg(min); 789 delta = dc_fixpt_neg(min);
792 790
793 offset = dal_fixed31_32_add(min, max); 791 offset = dc_fixpt_add(min, max);
794 792
795 for (i = 0 ; i < ramp->num_entries; i++) { 793 for (i = 0 ; i < ramp->num_entries; i++) {
796 pwl_rgb[i].r = dal_fixed31_32_div( 794 pwl_rgb[i].r = dc_fixpt_div(
797 dal_fixed31_32_add( 795 dc_fixpt_add(
798 ramp->entries.red[i], delta), offset); 796 ramp->entries.red[i], delta), offset);
799 pwl_rgb[i].g = dal_fixed31_32_div( 797 pwl_rgb[i].g = dc_fixpt_div(
800 dal_fixed31_32_add( 798 dc_fixpt_add(
801 ramp->entries.green[i], delta), offset); 799 ramp->entries.green[i], delta), offset);
802 pwl_rgb[i].b = dal_fixed31_32_div( 800 pwl_rgb[i].b = dc_fixpt_div(
803 dal_fixed31_32_add( 801 dc_fixpt_add(
804 ramp->entries.blue[i], delta), offset); 802 ramp->entries.blue[i], delta), offset);
805 803
806 } 804 }
807 805
808 pwl_rgb[i].r = dal_fixed31_32_sub(dal_fixed31_32_mul_int( 806 pwl_rgb[i].r = dc_fixpt_sub(dc_fixpt_mul_int(
809 pwl_rgb[i-1].r, 2), pwl_rgb[i-2].r); 807 pwl_rgb[i-1].r, 2), pwl_rgb[i-2].r);
810 pwl_rgb[i].g = dal_fixed31_32_sub(dal_fixed31_32_mul_int( 808 pwl_rgb[i].g = dc_fixpt_sub(dc_fixpt_mul_int(
811 pwl_rgb[i-1].g, 2), pwl_rgb[i-2].g); 809 pwl_rgb[i-1].g, 2), pwl_rgb[i-2].g);
812 pwl_rgb[i].b = dal_fixed31_32_sub(dal_fixed31_32_mul_int( 810 pwl_rgb[i].b = dc_fixpt_sub(dc_fixpt_mul_int(
813 pwl_rgb[i-1].b, 2), pwl_rgb[i-2].b); 811 pwl_rgb[i-1].b, 2), pwl_rgb[i-2].b);
814 ++i; 812 ++i;
815 pwl_rgb[i].r = dal_fixed31_32_sub(dal_fixed31_32_mul_int( 813 pwl_rgb[i].r = dc_fixpt_sub(dc_fixpt_mul_int(
816 pwl_rgb[i-1].r, 2), pwl_rgb[i-2].r); 814 pwl_rgb[i-1].r, 2), pwl_rgb[i-2].r);
817 pwl_rgb[i].g = dal_fixed31_32_sub(dal_fixed31_32_mul_int( 815 pwl_rgb[i].g = dc_fixpt_sub(dc_fixpt_mul_int(
818 pwl_rgb[i-1].g, 2), pwl_rgb[i-2].g); 816 pwl_rgb[i-1].g, 2), pwl_rgb[i-2].g);
819 pwl_rgb[i].b = dal_fixed31_32_sub(dal_fixed31_32_mul_int( 817 pwl_rgb[i].b = dc_fixpt_sub(dc_fixpt_mul_int(
820 pwl_rgb[i-1].b, 2), pwl_rgb[i-2].b); 818 pwl_rgb[i-1].b, 2), pwl_rgb[i-2].b);
819}
821 820
822 return true; 821/* todo: all these scale_gamma functions are inherently the same but
822 * take different structures as params or different format for ramp
823 * values. We could probably implement it in a more generic fashion
824 */
825static void scale_user_regamma_ramp(struct pwl_float_data *pwl_rgb,
826 const struct regamma_ramp *ramp,
827 struct dividers dividers)
828{
829 unsigned short max_driver = 0xFFFF;
830 unsigned short max_os = 0xFF00;
831 unsigned short scaler = max_os;
832 uint32_t i;
833 struct pwl_float_data *rgb = pwl_rgb;
834 struct pwl_float_data *rgb_last = rgb + GAMMA_RGB_256_ENTRIES - 1;
835
836 i = 0;
837 do {
838 if (ramp->gamma[i] > max_os ||
839 ramp->gamma[i + 256] > max_os ||
840 ramp->gamma[i + 512] > max_os) {
841 scaler = max_driver;
842 break;
843 }
844 i++;
845 } while (i != GAMMA_RGB_256_ENTRIES);
846
847 i = 0;
848 do {
849 rgb->r = dc_fixpt_from_fraction(
850 ramp->gamma[i], scaler);
851 rgb->g = dc_fixpt_from_fraction(
852 ramp->gamma[i + 256], scaler);
853 rgb->b = dc_fixpt_from_fraction(
854 ramp->gamma[i + 512], scaler);
855
856 ++rgb;
857 ++i;
858 } while (i != GAMMA_RGB_256_ENTRIES);
859
860 rgb->r = dc_fixpt_mul(rgb_last->r,
861 dividers.divider1);
862 rgb->g = dc_fixpt_mul(rgb_last->g,
863 dividers.divider1);
864 rgb->b = dc_fixpt_mul(rgb_last->b,
865 dividers.divider1);
866
867 ++rgb;
868
869 rgb->r = dc_fixpt_mul(rgb_last->r,
870 dividers.divider2);
871 rgb->g = dc_fixpt_mul(rgb_last->g,
872 dividers.divider2);
873 rgb->b = dc_fixpt_mul(rgb_last->b,
874 dividers.divider2);
875
876 ++rgb;
877
878 rgb->r = dc_fixpt_mul(rgb_last->r,
879 dividers.divider3);
880 rgb->g = dc_fixpt_mul(rgb_last->g,
881 dividers.divider3);
882 rgb->b = dc_fixpt_mul(rgb_last->b,
883 dividers.divider3);
823} 884}
824 885
825/* 886/*
@@ -852,7 +913,7 @@ static void apply_lut_1d(
852 struct fixed31_32 lut2; 913 struct fixed31_32 lut2;
853 const int max_lut_index = 4095; 914 const int max_lut_index = 4095;
854 const struct fixed31_32 max_lut_index_f = 915 const struct fixed31_32 max_lut_index_f =
855 dal_fixed31_32_from_int_nonconst(max_lut_index); 916 dc_fixpt_from_int(max_lut_index);
856 int32_t index = 0, index_next = 0; 917 int32_t index = 0, index_next = 0;
857 struct fixed31_32 index_f; 918 struct fixed31_32 index_f;
858 struct fixed31_32 delta_lut; 919 struct fixed31_32 delta_lut;
@@ -870,10 +931,10 @@ static void apply_lut_1d(
870 else 931 else
871 regamma_y = &tf_pts->blue[i]; 932 regamma_y = &tf_pts->blue[i];
872 933
873 norm_y = dal_fixed31_32_mul(max_lut_index_f, 934 norm_y = dc_fixpt_mul(max_lut_index_f,
874 *regamma_y); 935 *regamma_y);
875 index = dal_fixed31_32_floor(norm_y); 936 index = dc_fixpt_floor(norm_y);
876 index_f = dal_fixed31_32_from_int_nonconst(index); 937 index_f = dc_fixpt_from_int(index);
877 938
878 if (index < 0 || index > max_lut_index) 939 if (index < 0 || index > max_lut_index)
879 continue; 940 continue;
@@ -892,11 +953,11 @@ static void apply_lut_1d(
892 } 953 }
893 954
894 // we have everything now, so interpolate 955 // we have everything now, so interpolate
895 delta_lut = dal_fixed31_32_sub(lut2, lut1); 956 delta_lut = dc_fixpt_sub(lut2, lut1);
896 delta_index = dal_fixed31_32_sub(norm_y, index_f); 957 delta_index = dc_fixpt_sub(norm_y, index_f);
897 958
898 *regamma_y = dal_fixed31_32_add(lut1, 959 *regamma_y = dc_fixpt_add(lut1,
899 dal_fixed31_32_mul(delta_index, delta_lut)); 960 dc_fixpt_mul(delta_index, delta_lut));
900 } 961 }
901 } 962 }
902} 963}
@@ -912,7 +973,7 @@ static void build_evenly_distributed_points(
912 uint32_t i = 0; 973 uint32_t i = 0;
913 974
914 do { 975 do {
915 struct fixed31_32 value = dal_fixed31_32_from_fraction(i, 976 struct fixed31_32 value = dc_fixpt_from_fraction(i,
916 numberof_points - 1); 977 numberof_points - 1);
917 978
918 p->r = value; 979 p->r = value;
@@ -923,21 +984,21 @@ static void build_evenly_distributed_points(
923 ++i; 984 ++i;
924 } while (i != numberof_points); 985 } while (i != numberof_points);
925 986
926 p->r = dal_fixed31_32_div(p_last->r, dividers.divider1); 987 p->r = dc_fixpt_div(p_last->r, dividers.divider1);
927 p->g = dal_fixed31_32_div(p_last->g, dividers.divider1); 988 p->g = dc_fixpt_div(p_last->g, dividers.divider1);
928 p->b = dal_fixed31_32_div(p_last->b, dividers.divider1); 989 p->b = dc_fixpt_div(p_last->b, dividers.divider1);
929 990
930 ++p; 991 ++p;
931 992
932 p->r = dal_fixed31_32_div(p_last->r, dividers.divider2); 993 p->r = dc_fixpt_div(p_last->r, dividers.divider2);
933 p->g = dal_fixed31_32_div(p_last->g, dividers.divider2); 994 p->g = dc_fixpt_div(p_last->g, dividers.divider2);
934 p->b = dal_fixed31_32_div(p_last->b, dividers.divider2); 995 p->b = dc_fixpt_div(p_last->b, dividers.divider2);
935 996
936 ++p; 997 ++p;
937 998
938 p->r = dal_fixed31_32_div(p_last->r, dividers.divider3); 999 p->r = dc_fixpt_div(p_last->r, dividers.divider3);
939 p->g = dal_fixed31_32_div(p_last->g, dividers.divider3); 1000 p->g = dc_fixpt_div(p_last->g, dividers.divider3);
940 p->b = dal_fixed31_32_div(p_last->b, dividers.divider3); 1001 p->b = dc_fixpt_div(p_last->b, dividers.divider3);
941} 1002}
942 1003
943static inline void copy_rgb_regamma_to_coordinates_x( 1004static inline void copy_rgb_regamma_to_coordinates_x(
@@ -949,7 +1010,7 @@ static inline void copy_rgb_regamma_to_coordinates_x(
949 uint32_t i = 0; 1010 uint32_t i = 0;
950 const struct pwl_float_data_ex *rgb_regamma = rgb_ex; 1011 const struct pwl_float_data_ex *rgb_regamma = rgb_ex;
951 1012
952 while (i <= hw_points_num) { 1013 while (i <= hw_points_num + 1) {
953 coords->regamma_y_red = rgb_regamma->r; 1014 coords->regamma_y_red = rgb_regamma->r;
954 coords->regamma_y_green = rgb_regamma->g; 1015 coords->regamma_y_green = rgb_regamma->g;
955 coords->regamma_y_blue = rgb_regamma->b; 1016 coords->regamma_y_blue = rgb_regamma->b;
@@ -1002,6 +1063,102 @@ static bool calculate_interpolated_hardware_curve(
1002 return true; 1063 return true;
1003} 1064}
1004 1065
1066/* The "old" interpolation uses a complicated scheme to build an array of
1067 * coefficients while also using an array of 0-255 normalized to 0-1
1068 * Then there's another loop using both of the above + new scaled user ramp
1069 * and we concatenate them. It also searches for points of interpolation and
1070 * uses enums for positions.
1071 *
1072 * This function uses a different approach:
1073 * user ramp is always applied on X with 0/255, 1/255, 2/255, ..., 255/255
1074 * To find index for hwX , we notice the following:
1075 * i/255 <= hwX < (i+1)/255 <=> i <= 255*hwX < i+1
1076 * See apply_lut_1d which is the same principle, but on 4K entry 1D LUT
1077 *
1078 * Once the index is known, combined Y is simply:
1079 * user_ramp(index) + (hwX-index/255)*(user_ramp(index+1) - user_ramp(index)
1080 *
1081 * We should switch to this method in all cases, it's simpler and faster
1082 * ToDo one day - for now this only applies to ADL regamma to avoid regression
1083 * for regular use cases (sRGB and PQ)
1084 */
1085static void interpolate_user_regamma(uint32_t hw_points_num,
1086 struct pwl_float_data *rgb_user,
1087 bool apply_degamma,
1088 struct dc_transfer_func_distributed_points *tf_pts)
1089{
1090 uint32_t i;
1091 uint32_t color = 0;
1092 int32_t index;
1093 int32_t index_next;
1094 struct fixed31_32 *tf_point;
1095 struct fixed31_32 hw_x;
1096 struct fixed31_32 norm_factor =
1097 dc_fixpt_from_int(255);
1098 struct fixed31_32 norm_x;
1099 struct fixed31_32 index_f;
1100 struct fixed31_32 lut1;
1101 struct fixed31_32 lut2;
1102 struct fixed31_32 delta_lut;
1103 struct fixed31_32 delta_index;
1104
1105 i = 0;
1106 /* fixed_pt library has problems handling too small values */
1107 while (i != 32) {
1108 tf_pts->red[i] = dc_fixpt_zero;
1109 tf_pts->green[i] = dc_fixpt_zero;
1110 tf_pts->blue[i] = dc_fixpt_zero;
1111 ++i;
1112 }
1113 while (i <= hw_points_num + 1) {
1114 for (color = 0; color < 3; color++) {
1115 if (color == 0)
1116 tf_point = &tf_pts->red[i];
1117 else if (color == 1)
1118 tf_point = &tf_pts->green[i];
1119 else
1120 tf_point = &tf_pts->blue[i];
1121
1122 if (apply_degamma) {
1123 if (color == 0)
1124 hw_x = coordinates_x[i].regamma_y_red;
1125 else if (color == 1)
1126 hw_x = coordinates_x[i].regamma_y_green;
1127 else
1128 hw_x = coordinates_x[i].regamma_y_blue;
1129 } else
1130 hw_x = coordinates_x[i].x;
1131
1132 norm_x = dc_fixpt_mul(norm_factor, hw_x);
1133 index = dc_fixpt_floor(norm_x);
1134 if (index < 0 || index > 255)
1135 continue;
1136
1137 index_f = dc_fixpt_from_int(index);
1138 index_next = (index == 255) ? index : index + 1;
1139
1140 if (color == 0) {
1141 lut1 = rgb_user[index].r;
1142 lut2 = rgb_user[index_next].r;
1143 } else if (color == 1) {
1144 lut1 = rgb_user[index].g;
1145 lut2 = rgb_user[index_next].g;
1146 } else {
1147 lut1 = rgb_user[index].b;
1148 lut2 = rgb_user[index_next].b;
1149 }
1150
1151 // we have everything now, so interpolate
1152 delta_lut = dc_fixpt_sub(lut2, lut1);
1153 delta_index = dc_fixpt_sub(norm_x, index_f);
1154
1155 *tf_point = dc_fixpt_add(lut1,
1156 dc_fixpt_mul(delta_index, delta_lut));
1157 }
1158 ++i;
1159 }
1160}
1161
1005static void build_new_custom_resulted_curve( 1162static void build_new_custom_resulted_curve(
1006 uint32_t hw_points_num, 1163 uint32_t hw_points_num,
1007 struct dc_transfer_func_distributed_points *tf_pts) 1164 struct dc_transfer_func_distributed_points *tf_pts)
@@ -1011,16 +1168,39 @@ static void build_new_custom_resulted_curve(
1011 i = 0; 1168 i = 0;
1012 1169
1013 while (i != hw_points_num + 1) { 1170 while (i != hw_points_num + 1) {
1014 tf_pts->red[i] = dal_fixed31_32_clamp( 1171 tf_pts->red[i] = dc_fixpt_clamp(
1015 tf_pts->red[i], dal_fixed31_32_zero, 1172 tf_pts->red[i], dc_fixpt_zero,
1016 dal_fixed31_32_one); 1173 dc_fixpt_one);
1017 tf_pts->green[i] = dal_fixed31_32_clamp( 1174 tf_pts->green[i] = dc_fixpt_clamp(
1018 tf_pts->green[i], dal_fixed31_32_zero, 1175 tf_pts->green[i], dc_fixpt_zero,
1019 dal_fixed31_32_one); 1176 dc_fixpt_one);
1020 tf_pts->blue[i] = dal_fixed31_32_clamp( 1177 tf_pts->blue[i] = dc_fixpt_clamp(
1021 tf_pts->blue[i], dal_fixed31_32_zero, 1178 tf_pts->blue[i], dc_fixpt_zero,
1022 dal_fixed31_32_one); 1179 dc_fixpt_one);
1180
1181 ++i;
1182 }
1183}
1184
1185static void apply_degamma_for_user_regamma(struct pwl_float_data_ex *rgb_regamma,
1186 uint32_t hw_points_num)
1187{
1188 uint32_t i;
1189
1190 struct gamma_coefficients coeff;
1191 struct pwl_float_data_ex *rgb = rgb_regamma;
1192 const struct hw_x_point *coord_x = coordinates_x;
1193
1194 build_coefficients(&coeff, true);
1023 1195
1196 i = 0;
1197 while (i != hw_points_num + 1) {
1198 rgb->r = translate_from_linear_space_ex(
1199 coord_x->x, &coeff, 0);
1200 rgb->g = rgb->r;
1201 rgb->b = rgb->r;
1202 ++coord_x;
1203 ++rgb;
1024 ++i; 1204 ++i;
1025 } 1205 }
1026} 1206}
@@ -1062,6 +1242,7 @@ static bool map_regamma_hw_to_x_user(
1062 } 1242 }
1063 } 1243 }
1064 1244
1245 /* this should be named differently, all it does is clamp to 0-1 */
1065 build_new_custom_resulted_curve(hw_points_num, tf_pts); 1246 build_new_custom_resulted_curve(hw_points_num, tf_pts);
1066 1247
1067 return true; 1248 return true;
@@ -1109,9 +1290,9 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
1109 if (!coeff) 1290 if (!coeff)
1110 goto coeff_alloc_fail; 1291 goto coeff_alloc_fail;
1111 1292
1112 dividers.divider1 = dal_fixed31_32_from_fraction(3, 2); 1293 dividers.divider1 = dc_fixpt_from_fraction(3, 2);
1113 dividers.divider2 = dal_fixed31_32_from_int(2); 1294 dividers.divider2 = dc_fixpt_from_int(2);
1114 dividers.divider3 = dal_fixed31_32_from_fraction(5, 2); 1295 dividers.divider3 = dc_fixpt_from_fraction(5, 2);
1115 1296
1116 tf = output_tf->tf; 1297 tf = output_tf->tf;
1117 1298
@@ -1168,6 +1349,113 @@ rgb_user_alloc_fail:
1168 return ret; 1349 return ret;
1169} 1350}
1170 1351
1352bool calculate_user_regamma_coeff(struct dc_transfer_func *output_tf,
1353 const struct regamma_lut *regamma)
1354{
1355 struct gamma_coefficients coeff;
1356 const struct hw_x_point *coord_x = coordinates_x;
1357 uint32_t i = 0;
1358
1359 do {
1360 coeff.a0[i] = dc_fixpt_from_fraction(
1361 regamma->coeff.A0[i], 10000000);
1362 coeff.a1[i] = dc_fixpt_from_fraction(
1363 regamma->coeff.A1[i], 1000);
1364 coeff.a2[i] = dc_fixpt_from_fraction(
1365 regamma->coeff.A2[i], 1000);
1366 coeff.a3[i] = dc_fixpt_from_fraction(
1367 regamma->coeff.A3[i], 1000);
1368 coeff.user_gamma[i] = dc_fixpt_from_fraction(
1369 regamma->coeff.gamma[i], 1000);
1370
1371 ++i;
1372 } while (i != 3);
1373
1374 i = 0;
1375 /* fixed_pt library has problems handling too small values */
1376 while (i != 32) {
1377 output_tf->tf_pts.red[i] = dc_fixpt_zero;
1378 output_tf->tf_pts.green[i] = dc_fixpt_zero;
1379 output_tf->tf_pts.blue[i] = dc_fixpt_zero;
1380 ++coord_x;
1381 ++i;
1382 }
1383 while (i != MAX_HW_POINTS + 1) {
1384 output_tf->tf_pts.red[i] = translate_from_linear_space_ex(
1385 coord_x->x, &coeff, 0);
1386 output_tf->tf_pts.green[i] = translate_from_linear_space_ex(
1387 coord_x->x, &coeff, 1);
1388 output_tf->tf_pts.blue[i] = translate_from_linear_space_ex(
1389 coord_x->x, &coeff, 2);
1390 ++coord_x;
1391 ++i;
1392 }
1393
1394 // this function just clamps output to 0-1
1395 build_new_custom_resulted_curve(MAX_HW_POINTS, &output_tf->tf_pts);
1396 output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
1397
1398 return true;
1399}
1400
1401bool calculate_user_regamma_ramp(struct dc_transfer_func *output_tf,
1402 const struct regamma_lut *regamma)
1403{
1404 struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts;
1405 struct dividers dividers;
1406
1407 struct pwl_float_data *rgb_user = NULL;
1408 struct pwl_float_data_ex *rgb_regamma = NULL;
1409 bool ret = false;
1410
1411 if (regamma == NULL)
1412 return false;
1413
1414 output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
1415
1416 rgb_user = kzalloc(sizeof(*rgb_user) * (GAMMA_RGB_256_ENTRIES + _EXTRA_POINTS),
1417 GFP_KERNEL);
1418 if (!rgb_user)
1419 goto rgb_user_alloc_fail;
1420
1421 rgb_regamma = kzalloc(sizeof(*rgb_regamma) * (MAX_HW_POINTS + _EXTRA_POINTS),
1422 GFP_KERNEL);
1423 if (!rgb_regamma)
1424 goto rgb_regamma_alloc_fail;
1425
1426 dividers.divider1 = dc_fixpt_from_fraction(3, 2);
1427 dividers.divider2 = dc_fixpt_from_int(2);
1428 dividers.divider3 = dc_fixpt_from_fraction(5, 2);
1429
1430 scale_user_regamma_ramp(rgb_user, &regamma->ramp, dividers);
1431
1432 if (regamma->flags.bits.applyDegamma == 1) {
1433 apply_degamma_for_user_regamma(rgb_regamma, MAX_HW_POINTS);
1434 copy_rgb_regamma_to_coordinates_x(coordinates_x,
1435 MAX_HW_POINTS, rgb_regamma);
1436 }
1437
1438 interpolate_user_regamma(MAX_HW_POINTS, rgb_user,
1439 regamma->flags.bits.applyDegamma, tf_pts);
1440
1441 // no custom HDR curves!
1442 tf_pts->end_exponent = 0;
1443 tf_pts->x_point_at_y1_red = 1;
1444 tf_pts->x_point_at_y1_green = 1;
1445 tf_pts->x_point_at_y1_blue = 1;
1446
1447 // this function just clamps output to 0-1
1448 build_new_custom_resulted_curve(MAX_HW_POINTS, tf_pts);
1449
1450 ret = true;
1451
1452 kfree(rgb_regamma);
1453rgb_regamma_alloc_fail:
1454 kvfree(rgb_user);
1455rgb_user_alloc_fail:
1456 return ret;
1457}
1458
1171bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, 1459bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
1172 const struct dc_gamma *ramp, bool mapUserRamp) 1460 const struct dc_gamma *ramp, bool mapUserRamp)
1173{ 1461{
@@ -1208,9 +1496,9 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
1208 if (!coeff) 1496 if (!coeff)
1209 goto coeff_alloc_fail; 1497 goto coeff_alloc_fail;
1210 1498
1211 dividers.divider1 = dal_fixed31_32_from_fraction(3, 2); 1499 dividers.divider1 = dc_fixpt_from_fraction(3, 2);
1212 dividers.divider2 = dal_fixed31_32_from_int(2); 1500 dividers.divider2 = dc_fixpt_from_int(2);
1213 dividers.divider3 = dal_fixed31_32_from_fraction(5, 2); 1501 dividers.divider3 = dc_fixpt_from_fraction(5, 2);
1214 1502
1215 tf = input_tf->tf; 1503 tf = input_tf->tf;
1216 1504
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
index b7f9bc27d101..b64048991a95 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
@@ -32,6 +32,47 @@ struct dc_transfer_func_distributed_points;
32struct dc_rgb_fixed; 32struct dc_rgb_fixed;
33enum dc_transfer_func_predefined; 33enum dc_transfer_func_predefined;
34 34
35/* For SetRegamma ADL interface support
36 * Must match escape type
37 */
38union regamma_flags {
39 unsigned int raw;
40 struct {
41 unsigned int gammaRampArray :1; // RegammaRamp is in use
42 unsigned int gammaFromEdid :1; //gamma from edid is in use
43 unsigned int gammaFromEdidEx :1; //gamma from edid is in use , but only for Display Id 1.2
44 unsigned int gammaFromUser :1; //user custom gamma is used
45 unsigned int coeffFromUser :1; //coeff. A0-A3 from user is in use
46 unsigned int coeffFromEdid :1; //coeff. A0-A3 from edid is in use
47 unsigned int applyDegamma :1; //flag for additional degamma correction in driver
48 unsigned int gammaPredefinedSRGB :1; //flag for SRGB gamma
49 unsigned int gammaPredefinedPQ :1; //flag for PQ gamma
50 unsigned int gammaPredefinedPQ2084Interim :1; //flag for PQ gamma, lower max nits
51 unsigned int gammaPredefined36 :1; //flag for 3.6 gamma
52 unsigned int gammaPredefinedReset :1; //flag to return to previous gamma
53 } bits;
54};
55
56struct regamma_ramp {
57 unsigned short gamma[256*3]; // gamma ramp packed in same way as OS windows ,r , g & b
58};
59
60struct regamma_coeff {
61 int gamma[3];
62 int A0[3];
63 int A1[3];
64 int A2[3];
65 int A3[3];
66};
67
68struct regamma_lut {
69 union regamma_flags flags;
70 union {
71 struct regamma_ramp ramp;
72 struct regamma_coeff coeff;
73 };
74};
75
35void setup_x_points_distribution(void); 76void setup_x_points_distribution(void);
36void precompute_pq(void); 77void precompute_pq(void);
37void precompute_de_pq(void); 78void precompute_de_pq(void);
@@ -45,9 +86,14 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf,
45bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, 86bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
46 struct dc_transfer_func_distributed_points *points); 87 struct dc_transfer_func_distributed_points *points);
47 88
48bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, 89bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
49 struct dc_transfer_func_distributed_points *points); 90 struct dc_transfer_func_distributed_points *points);
50 91
92bool calculate_user_regamma_coeff(struct dc_transfer_func *output_tf,
93 const struct regamma_lut *regamma);
94
95bool calculate_user_regamma_ramp(struct dc_transfer_func *output_tf,
96 const struct regamma_lut *regamma);
51 97
52 98
53#endif /* COLOR_MOD_COLOR_GAMMA_H_ */ 99#endif /* COLOR_MOD_COLOR_GAMMA_H_ */
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h b/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h
index 3230e2adb870..3812094b52e8 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h
@@ -46,6 +46,10 @@ void mod_stats_dump(struct mod_stats *mod_stats);
46 46
47void mod_stats_reset_data(struct mod_stats *mod_stats); 47void mod_stats_reset_data(struct mod_stats *mod_stats);
48 48
49void mod_stats_update_event(struct mod_stats *mod_stats,
50 char *event_string,
51 unsigned int length);
52
49void mod_stats_update_flip(struct mod_stats *mod_stats, 53void mod_stats_update_flip(struct mod_stats *mod_stats,
50 unsigned long timestamp_in_ns); 54 unsigned long timestamp_in_ns);
51 55
diff --git a/drivers/gpu/drm/amd/display/modules/stats/stats.c b/drivers/gpu/drm/amd/display/modules/stats/stats.c
index 041f87b73d5f..3f7d47fdc367 100644
--- a/drivers/gpu/drm/amd/display/modules/stats/stats.c
+++ b/drivers/gpu/drm/amd/display/modules/stats/stats.c
@@ -36,9 +36,14 @@
36#define DAL_STATS_ENTRIES_REGKEY_DEFAULT 0x00350000 36#define DAL_STATS_ENTRIES_REGKEY_DEFAULT 0x00350000
37#define DAL_STATS_ENTRIES_REGKEY_MAX 0x01000000 37#define DAL_STATS_ENTRIES_REGKEY_MAX 0x01000000
38 38
39#define DAL_STATS_EVENT_ENTRIES_DEFAULT 0x00000100
40
39#define MOD_STATS_NUM_VSYNCS 5 41#define MOD_STATS_NUM_VSYNCS 5
42#define MOD_STATS_EVENT_STRING_MAX 512
40 43
41struct stats_time_cache { 44struct stats_time_cache {
45 unsigned int entry_id;
46
42 unsigned long flip_timestamp_in_ns; 47 unsigned long flip_timestamp_in_ns;
43 unsigned long vupdate_timestamp_in_ns; 48 unsigned long vupdate_timestamp_in_ns;
44 49
@@ -63,15 +68,26 @@ struct stats_time_cache {
63 unsigned int flags; 68 unsigned int flags;
64}; 69};
65 70
71struct stats_event_cache {
72 unsigned int entry_id;
73 char event_string[MOD_STATS_EVENT_STRING_MAX];
74};
75
66struct core_stats { 76struct core_stats {
67 struct mod_stats public; 77 struct mod_stats public;
68 struct dc *dc; 78 struct dc *dc;
69 79
80 bool enabled;
81 unsigned int entries;
82 unsigned int event_entries;
83 unsigned int entry_id;
84
70 struct stats_time_cache *time; 85 struct stats_time_cache *time;
71 unsigned int index; 86 unsigned int index;
72 87
73 bool enabled; 88 struct stats_event_cache *events;
74 unsigned int entries; 89 unsigned int event_index;
90
75}; 91};
76 92
77#define MOD_STATS_TO_CORE(mod_stats)\ 93#define MOD_STATS_TO_CORE(mod_stats)\
@@ -99,12 +115,12 @@ struct mod_stats *mod_stats_create(struct dc *dc)
99 unsigned int reg_data; 115 unsigned int reg_data;
100 int i = 0; 116 int i = 0;
101 117
118 if (dc == NULL)
119 goto fail_construct;
120
102 core_stats = kzalloc(sizeof(struct core_stats), GFP_KERNEL); 121 core_stats = kzalloc(sizeof(struct core_stats), GFP_KERNEL);
103 122
104 if (core_stats == NULL) 123 if (core_stats == NULL)
105 goto fail_alloc_context;
106
107 if (dc == NULL)
108 goto fail_construct; 124 goto fail_construct;
109 125
110 core_stats->dc = dc; 126 core_stats->dc = dc;
@@ -115,33 +131,55 @@ struct mod_stats *mod_stats_create(struct dc *dc)
115 &reg_data, sizeof(unsigned int), &flag)) 131 &reg_data, sizeof(unsigned int), &flag))
116 core_stats->enabled = reg_data; 132 core_stats->enabled = reg_data;
117 133
118 core_stats->entries = DAL_STATS_ENTRIES_REGKEY_DEFAULT; 134 if (core_stats->enabled) {
119 if (dm_read_persistent_data(dc->ctx, NULL, NULL, 135 core_stats->entries = DAL_STATS_ENTRIES_REGKEY_DEFAULT;
120 DAL_STATS_ENTRIES_REGKEY, 136 if (dm_read_persistent_data(dc->ctx, NULL, NULL,
121 &reg_data, sizeof(unsigned int), &flag)) { 137 DAL_STATS_ENTRIES_REGKEY,
122 if (reg_data > DAL_STATS_ENTRIES_REGKEY_MAX) 138 &reg_data, sizeof(unsigned int), &flag)) {
123 core_stats->entries = DAL_STATS_ENTRIES_REGKEY_MAX; 139 if (reg_data > DAL_STATS_ENTRIES_REGKEY_MAX)
124 else 140 core_stats->entries = DAL_STATS_ENTRIES_REGKEY_MAX;
125 core_stats->entries = reg_data; 141 else
126 } 142 core_stats->entries = reg_data;
143 }
144 core_stats->time = kzalloc(
145 sizeof(struct stats_time_cache) *
146 core_stats->entries,
147 GFP_KERNEL);
127 148
128 core_stats->time = kzalloc(sizeof(struct stats_time_cache) * core_stats->entries, 149 if (core_stats->time == NULL)
129 GFP_KERNEL); 150 goto fail_construct_time;
130 151
131 if (core_stats->time == NULL) 152 core_stats->event_entries = DAL_STATS_EVENT_ENTRIES_DEFAULT;
132 goto fail_construct; 153 core_stats->events = kzalloc(
154 sizeof(struct stats_event_cache) *
155 core_stats->event_entries,
156 GFP_KERNEL);
157
158 if (core_stats->events == NULL)
159 goto fail_construct_events;
160
161 } else {
162 core_stats->entries = 0;
163 }
133 164
134 /* Purposely leave index 0 unused so we don't need special logic to 165 /* Purposely leave index 0 unused so we don't need special logic to
135 * handle calculation cases that depend on previous flip data. 166 * handle calculation cases that depend on previous flip data.
136 */ 167 */
137 core_stats->index = 1; 168 core_stats->index = 1;
169 core_stats->event_index = 0;
170
171 // Keeps track of ordering within the different stats structures
172 core_stats->entry_id = 0;
138 173
139 return &core_stats->public; 174 return &core_stats->public;
140 175
141fail_construct: 176fail_construct_events:
177 kfree(core_stats->time);
178
179fail_construct_time:
142 kfree(core_stats); 180 kfree(core_stats);
143 181
144fail_alloc_context: 182fail_construct:
145 return NULL; 183 return NULL;
146} 184}
147 185
@@ -153,6 +191,9 @@ void mod_stats_destroy(struct mod_stats *mod_stats)
153 if (core_stats->time != NULL) 191 if (core_stats->time != NULL)
154 kfree(core_stats->time); 192 kfree(core_stats->time);
155 193
194 if (core_stats->events != NULL)
195 kfree(core_stats->events);
196
156 kfree(core_stats); 197 kfree(core_stats);
157 } 198 }
158} 199}
@@ -163,7 +204,11 @@ void mod_stats_dump(struct mod_stats *mod_stats)
163 struct dal_logger *logger = NULL; 204 struct dal_logger *logger = NULL;
164 struct core_stats *core_stats = NULL; 205 struct core_stats *core_stats = NULL;
165 struct stats_time_cache *time = NULL; 206 struct stats_time_cache *time = NULL;
207 struct stats_event_cache *events = NULL;
208 unsigned int time_index = 1;
209 unsigned int event_index = 0;
166 unsigned int index = 0; 210 unsigned int index = 0;
211 struct log_entry log_entry;
167 212
168 if (mod_stats == NULL) 213 if (mod_stats == NULL)
169 return; 214 return;
@@ -172,45 +217,62 @@ void mod_stats_dump(struct mod_stats *mod_stats)
172 dc = core_stats->dc; 217 dc = core_stats->dc;
173 logger = dc->ctx->logger; 218 logger = dc->ctx->logger;
174 time = core_stats->time; 219 time = core_stats->time;
175 220 events = core_stats->events;
176 //LogEntry* pLog = GetLog()->Open(LogMajor_ISR, LogMinor_ISR_FreeSyncSW); 221
177 222 DISPLAY_STATS_BEGIN(log_entry);
178 //if (!pLog->IsDummyEntry()) 223
179 { 224 DISPLAY_STATS("==Display Caps==\n");
180 dm_logger_write(logger, LOG_PROFILING, "==Display Caps==\n"); 225
181 dm_logger_write(logger, LOG_PROFILING, "\n"); 226 DISPLAY_STATS("==Display Stats==\n");
182 dm_logger_write(logger, LOG_PROFILING, "\n"); 227
183 228 DISPLAY_STATS("%10s %10s %10s %10s %10s"
184 dm_logger_write(logger, LOG_PROFILING, "==Stats==\n"); 229 " %11s %11s %17s %10s %14s"
185 dm_logger_write(logger, LOG_PROFILING, 230 " %10s %10s %10s %10s %10s"
186 "render avgRender minWindow midPoint maxWindow vsyncToFlip flipToVsync #vsyncBetweenFlip #frame insertDuration vTotalMin vTotalMax eventTrigs vSyncTime1 vSyncTime2 vSyncTime3 vSyncTime4 vSyncTime5 flags\n"); 231 " %10s %10s %10s %10s\n",
187 232 "render", "avgRender",
188 for (int i = 0; i < core_stats->index && i < core_stats->entries; i++) { 233 "minWindow", "midPoint", "maxWindow",
189 dm_logger_write(logger, LOG_PROFILING, 234 "vsyncToFlip", "flipToVsync", "vsyncsBetweenFlip",
190 "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u\n", 235 "numFrame", "insertDuration",
191 time[i].render_time_in_us, 236 "vTotalMin", "vTotalMax", "eventTrigs",
192 time[i].avg_render_time_in_us_last_ten, 237 "vSyncTime1", "vSyncTime2", "vSyncTime3",
193 time[i].min_window, 238 "vSyncTime4", "vSyncTime5", "flags");
194 time[i].lfc_mid_point_in_us, 239
195 time[i].max_window, 240 for (int i = 0; i < core_stats->entry_id; i++) {
196 time[i].vsync_to_flip_time_in_us, 241 if (event_index < core_stats->event_index &&
197 time[i].flip_to_vsync_time_in_us, 242 i == events[event_index].entry_id) {
198 time[i].num_vsync_between_flips, 243 DISPLAY_STATS("%s\n", events[event_index].event_string);
199 time[i].num_frames_inserted, 244 event_index++;
200 time[i].inserted_duration_in_us, 245 } else if (time_index < core_stats->index &&
201 time[i].v_total_min, 246 i == time[time_index].entry_id) {
202 time[i].v_total_max, 247 DISPLAY_STATS("%10u %10u %10u %10u %10u"
203 time[i].event_triggers, 248 " %11u %11u %17u %10u %14u"
204 time[i].v_sync_time_in_us[0], 249 " %10u %10u %10u %10u %10u"
205 time[i].v_sync_time_in_us[1], 250 " %10u %10u %10u %10u\n",
206 time[i].v_sync_time_in_us[2], 251 time[time_index].render_time_in_us,
207 time[i].v_sync_time_in_us[3], 252 time[time_index].avg_render_time_in_us_last_ten,
208 time[i].v_sync_time_in_us[4], 253 time[time_index].min_window,
209 time[i].flags); 254 time[time_index].lfc_mid_point_in_us,
255 time[time_index].max_window,
256 time[time_index].vsync_to_flip_time_in_us,
257 time[time_index].flip_to_vsync_time_in_us,
258 time[time_index].num_vsync_between_flips,
259 time[time_index].num_frames_inserted,
260 time[time_index].inserted_duration_in_us,
261 time[time_index].v_total_min,
262 time[time_index].v_total_max,
263 time[time_index].event_triggers,
264 time[time_index].v_sync_time_in_us[0],
265 time[time_index].v_sync_time_in_us[1],
266 time[time_index].v_sync_time_in_us[2],
267 time[time_index].v_sync_time_in_us[3],
268 time[time_index].v_sync_time_in_us[4],
269 time[time_index].flags);
270
271 time_index++;
210 } 272 }
211 } 273 }
212 //GetLog()->Close(pLog); 274
213 //GetLog()->UnSetLogMask(LogMajor_ISR, LogMinor_ISR_FreeSyncSW); 275 DISPLAY_STATS_END(log_entry);
214} 276}
215 277
216void mod_stats_reset_data(struct mod_stats *mod_stats) 278void mod_stats_reset_data(struct mod_stats *mod_stats)
@@ -227,7 +289,46 @@ void mod_stats_reset_data(struct mod_stats *mod_stats)
227 memset(core_stats->time, 0, 289 memset(core_stats->time, 0,
228 sizeof(struct stats_time_cache) * core_stats->entries); 290 sizeof(struct stats_time_cache) * core_stats->entries);
229 291
230 core_stats->index = 0; 292 memset(core_stats->events, 0,
293 sizeof(struct stats_event_cache) * core_stats->event_entries);
294
295 core_stats->index = 1;
296 core_stats->event_index = 0;
297
298 // Keeps track of ordering within the different stats structures
299 core_stats->entry_id = 0;
300}
301
302void mod_stats_update_event(struct mod_stats *mod_stats,
303 char *event_string,
304 unsigned int length)
305{
306 struct core_stats *core_stats = NULL;
307 struct stats_event_cache *events = NULL;
308 unsigned int index = 0;
309 unsigned int copy_length = 0;
310
311 if (mod_stats == NULL)
312 return;
313
314 core_stats = MOD_STATS_TO_CORE(mod_stats);
315
316 if (core_stats->event_index >= core_stats->event_entries)
317 return;
318
319 events = core_stats->events;
320 index = core_stats->event_index;
321
322 copy_length = length;
323 if (length > MOD_STATS_EVENT_STRING_MAX)
324 copy_length = MOD_STATS_EVENT_STRING_MAX;
325
326 memcpy(&events[index].event_string, event_string, copy_length);
327 events[index].event_string[copy_length - 1] = '\0';
328
329 events[index].entry_id = core_stats->entry_id;
330 core_stats->event_index++;
331 core_stats->entry_id++;
231} 332}
232 333
233void mod_stats_update_flip(struct mod_stats *mod_stats, 334void mod_stats_update_flip(struct mod_stats *mod_stats,
@@ -250,7 +351,7 @@ void mod_stats_update_flip(struct mod_stats *mod_stats,
250 351
251 time[index].flip_timestamp_in_ns = timestamp_in_ns; 352 time[index].flip_timestamp_in_ns = timestamp_in_ns;
252 time[index].render_time_in_us = 353 time[index].render_time_in_us =
253 timestamp_in_ns - time[index - 1].flip_timestamp_in_ns; 354 (timestamp_in_ns - time[index - 1].flip_timestamp_in_ns) / 1000;
254 355
255 if (index >= 10) { 356 if (index >= 10) {
256 for (unsigned int i = 0; i < 10; i++) 357 for (unsigned int i = 0; i < 10; i++)
@@ -261,12 +362,16 @@ void mod_stats_update_flip(struct mod_stats *mod_stats,
261 362
262 if (time[index].num_vsync_between_flips > 0) 363 if (time[index].num_vsync_between_flips > 0)
263 time[index].vsync_to_flip_time_in_us = 364 time[index].vsync_to_flip_time_in_us =
264 timestamp_in_ns - time[index].vupdate_timestamp_in_ns; 365 (timestamp_in_ns -
366 time[index].vupdate_timestamp_in_ns) / 1000;
265 else 367 else
266 time[index].vsync_to_flip_time_in_us = 368 time[index].vsync_to_flip_time_in_us =
267 timestamp_in_ns - time[index - 1].vupdate_timestamp_in_ns; 369 (timestamp_in_ns -
370 time[index - 1].vupdate_timestamp_in_ns) / 1000;
268 371
372 time[index].entry_id = core_stats->entry_id;
269 core_stats->index++; 373 core_stats->index++;
374 core_stats->entry_id++;
270} 375}
271 376
272void mod_stats_update_vupdate(struct mod_stats *mod_stats, 377void mod_stats_update_vupdate(struct mod_stats *mod_stats,
@@ -275,6 +380,8 @@ void mod_stats_update_vupdate(struct mod_stats *mod_stats,
275 struct core_stats *core_stats = NULL; 380 struct core_stats *core_stats = NULL;
276 struct stats_time_cache *time = NULL; 381 struct stats_time_cache *time = NULL;
277 unsigned int index = 0; 382 unsigned int index = 0;
383 unsigned int num_vsyncs = 0;
384 unsigned int prev_vsync_in_ns = 0;
278 385
279 if (mod_stats == NULL) 386 if (mod_stats == NULL)
280 return; 387 return;
@@ -286,14 +393,27 @@ void mod_stats_update_vupdate(struct mod_stats *mod_stats,
286 393
287 time = core_stats->time; 394 time = core_stats->time;
288 index = core_stats->index; 395 index = core_stats->index;
396 num_vsyncs = time[index].num_vsync_between_flips;
397
398 if (num_vsyncs < MOD_STATS_NUM_VSYNCS) {
399 if (num_vsyncs == 0) {
400 prev_vsync_in_ns =
401 time[index - 1].vupdate_timestamp_in_ns;
402
403 time[index].flip_to_vsync_time_in_us =
404 (timestamp_in_ns -
405 time[index - 1].flip_timestamp_in_ns) /
406 1000;
407 } else {
408 prev_vsync_in_ns =
409 time[index].vupdate_timestamp_in_ns;
410 }
289 411
290 time[index].vupdate_timestamp_in_ns = timestamp_in_ns; 412 time[index].v_sync_time_in_us[num_vsyncs] =
291 if (time[index].num_vsync_between_flips < MOD_STATS_NUM_VSYNCS) 413 (timestamp_in_ns - prev_vsync_in_ns) / 1000;
292 time[index].v_sync_time_in_us[time[index].num_vsync_between_flips] = 414 }
293 timestamp_in_ns - time[index - 1].vupdate_timestamp_in_ns;
294 time[index].flip_to_vsync_time_in_us =
295 timestamp_in_ns - time[index - 1].flip_timestamp_in_ns;
296 415
416 time[index].vupdate_timestamp_in_ns = timestamp_in_ns;
297 time[index].num_vsync_between_flips++; 417 time[index].num_vsync_between_flips++;
298} 418}
299 419
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h
index 9fa3aaef3f33..b178176b72ac 100644
--- a/drivers/gpu/drm/amd/include/amd_shared.h
+++ b/drivers/gpu/drm/amd/include/amd_shared.h
@@ -92,7 +92,7 @@ enum amd_powergating_state {
92#define AMD_CG_SUPPORT_GFX_3D_CGLS (1 << 21) 92#define AMD_CG_SUPPORT_GFX_3D_CGLS (1 << 21)
93#define AMD_CG_SUPPORT_DRM_MGCG (1 << 22) 93#define AMD_CG_SUPPORT_DRM_MGCG (1 << 22)
94#define AMD_CG_SUPPORT_DF_MGCG (1 << 23) 94#define AMD_CG_SUPPORT_DF_MGCG (1 << 23)
95 95#define AMD_CG_SUPPORT_VCN_MGCG (1 << 24)
96/* PG flags */ 96/* PG flags */
97#define AMD_PG_SUPPORT_GFX_PG (1 << 0) 97#define AMD_PG_SUPPORT_GFX_PG (1 << 0)
98#define AMD_PG_SUPPORT_GFX_SMG (1 << 1) 98#define AMD_PG_SUPPORT_GFX_SMG (1 << 1)
@@ -108,6 +108,27 @@ enum amd_powergating_state {
108#define AMD_PG_SUPPORT_GFX_QUICK_MG (1 << 11) 108#define AMD_PG_SUPPORT_GFX_QUICK_MG (1 << 11)
109#define AMD_PG_SUPPORT_GFX_PIPELINE (1 << 12) 109#define AMD_PG_SUPPORT_GFX_PIPELINE (1 << 12)
110#define AMD_PG_SUPPORT_MMHUB (1 << 13) 110#define AMD_PG_SUPPORT_MMHUB (1 << 13)
111#define AMD_PG_SUPPORT_VCN (1 << 14)
112
113enum PP_FEATURE_MASK {
114 PP_SCLK_DPM_MASK = 0x1,
115 PP_MCLK_DPM_MASK = 0x2,
116 PP_PCIE_DPM_MASK = 0x4,
117 PP_SCLK_DEEP_SLEEP_MASK = 0x8,
118 PP_POWER_CONTAINMENT_MASK = 0x10,
119 PP_UVD_HANDSHAKE_MASK = 0x20,
120 PP_SMC_VOLTAGE_CONTROL_MASK = 0x40,
121 PP_VBI_TIME_SUPPORT_MASK = 0x80,
122 PP_ULV_MASK = 0x100,
123 PP_ENABLE_GFX_CG_THRU_SMU = 0x200,
124 PP_CLOCK_STRETCH_MASK = 0x400,
125 PP_OD_FUZZY_FAN_CONTROL_MASK = 0x800,
126 PP_SOCCLK_DPM_MASK = 0x1000,
127 PP_DCEFCLK_DPM_MASK = 0x2000,
128 PP_OVERDRIVE_MASK = 0x4000,
129 PP_GFXOFF_MASK = 0x8000,
130 PP_ACG_MASK = 0x10000,
131};
111 132
112struct amd_ip_funcs { 133struct amd_ip_funcs {
113 /* Name of IP block */ 134 /* Name of IP block */
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h
index f730d0629020..b6f74bf4af02 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h
@@ -2095,6 +2095,18 @@
2095#define mmDC_GPIO_AUX_CTRL_2_BASE_IDX 2 2095#define mmDC_GPIO_AUX_CTRL_2_BASE_IDX 2
2096#define mmDC_GPIO_RXEN 0x212f 2096#define mmDC_GPIO_RXEN 0x212f
2097#define mmDC_GPIO_RXEN_BASE_IDX 2 2097#define mmDC_GPIO_RXEN_BASE_IDX 2
2098#define mmDC_GPIO_AUX_CTRL_3 0x2130
2099#define mmDC_GPIO_AUX_CTRL_3_BASE_IDX 2
2100#define mmDC_GPIO_AUX_CTRL_4 0x2131
2101#define mmDC_GPIO_AUX_CTRL_4_BASE_IDX 2
2102#define mmDC_GPIO_AUX_CTRL_5 0x2132
2103#define mmDC_GPIO_AUX_CTRL_5_BASE_IDX 2
2104#define mmAUXI2C_PAD_ALL_PWR_OK 0x2133
2105#define mmAUXI2C_PAD_ALL_PWR_OK_BASE_IDX 2
2106#define mmDC_GPIO_PULLUPEN 0x2134
2107#define mmDC_GPIO_PULLUPEN_BASE_IDX 2
2108#define mmDC_GPIO_AUX_CTRL_6 0x2135
2109#define mmDC_GPIO_AUX_CTRL_6_BASE_IDX 2
2098#define mmBPHYC_DAC_MACRO_CNTL 0x2136 2110#define mmBPHYC_DAC_MACRO_CNTL 0x2136
2099#define mmBPHYC_DAC_MACRO_CNTL_BASE_IDX 2 2111#define mmBPHYC_DAC_MACRO_CNTL_BASE_IDX 2
2100#define mmDAC_MACRO_CNTL_RESERVED0 0x2136 2112#define mmDAC_MACRO_CNTL_RESERVED0 0x2136
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_sh_mask.h
index 6d3162c42957..bcd190a3fcdd 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_sh_mask.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_sh_mask.h
@@ -10971,6 +10971,158 @@
10971#define DC_GPIO_RXEN__DC_GPIO_BLON_RXEN_MASK 0x00100000L 10971#define DC_GPIO_RXEN__DC_GPIO_BLON_RXEN_MASK 0x00100000L
10972#define DC_GPIO_RXEN__DC_GPIO_DIGON_RXEN_MASK 0x00200000L 10972#define DC_GPIO_RXEN__DC_GPIO_DIGON_RXEN_MASK 0x00200000L
10973#define DC_GPIO_RXEN__DC_GPIO_ENA_BL_RXEN_MASK 0x00400000L 10973#define DC_GPIO_RXEN__DC_GPIO_ENA_BL_RXEN_MASK 0x00400000L
10974//DC_GPIO_AUX_CTRL_3
10975#define DC_GPIO_AUX_CTRL_3__AUX1_NEN_RTERM__SHIFT 0x0
10976#define DC_GPIO_AUX_CTRL_3__AUX2_NEN_RTERM__SHIFT 0x1
10977#define DC_GPIO_AUX_CTRL_3__AUX3_NEN_RTERM__SHIFT 0x2
10978#define DC_GPIO_AUX_CTRL_3__AUX4_NEN_RTERM__SHIFT 0x3
10979#define DC_GPIO_AUX_CTRL_3__AUX5_NEN_RTERM__SHIFT 0x4
10980#define DC_GPIO_AUX_CTRL_3__AUX6_NEN_RTERM__SHIFT 0x5
10981#define DC_GPIO_AUX_CTRL_3__AUX1_DP_DN_SWAP__SHIFT 0x8
10982#define DC_GPIO_AUX_CTRL_3__AUX2_DP_DN_SWAP__SHIFT 0x9
10983#define DC_GPIO_AUX_CTRL_3__AUX3_DP_DN_SWAP__SHIFT 0xa
10984#define DC_GPIO_AUX_CTRL_3__AUX4_DP_DN_SWAP__SHIFT 0xb
10985#define DC_GPIO_AUX_CTRL_3__AUX5_DP_DN_SWAP__SHIFT 0xc
10986#define DC_GPIO_AUX_CTRL_3__AUX6_DP_DN_SWAP__SHIFT 0xd
10987#define DC_GPIO_AUX_CTRL_3__AUX1_HYS_TUNE__SHIFT 0x10
10988#define DC_GPIO_AUX_CTRL_3__AUX2_HYS_TUNE__SHIFT 0x12
10989#define DC_GPIO_AUX_CTRL_3__AUX3_HYS_TUNE__SHIFT 0x14
10990#define DC_GPIO_AUX_CTRL_3__AUX4_HYS_TUNE__SHIFT 0x16
10991#define DC_GPIO_AUX_CTRL_3__AUX5_HYS_TUNE__SHIFT 0x18
10992#define DC_GPIO_AUX_CTRL_3__AUX6_HYS_TUNE__SHIFT 0x1a
10993#define DC_GPIO_AUX_CTRL_3__AUX1_NEN_RTERM_MASK 0x00000001L
10994#define DC_GPIO_AUX_CTRL_3__AUX2_NEN_RTERM_MASK 0x00000002L
10995#define DC_GPIO_AUX_CTRL_3__AUX3_NEN_RTERM_MASK 0x00000004L
10996#define DC_GPIO_AUX_CTRL_3__AUX4_NEN_RTERM_MASK 0x00000008L
10997#define DC_GPIO_AUX_CTRL_3__AUX5_NEN_RTERM_MASK 0x00000010L
10998#define DC_GPIO_AUX_CTRL_3__AUX6_NEN_RTERM_MASK 0x00000020L
10999#define DC_GPIO_AUX_CTRL_3__AUX1_DP_DN_SWAP_MASK 0x00000100L
11000#define DC_GPIO_AUX_CTRL_3__AUX2_DP_DN_SWAP_MASK 0x00000200L
11001#define DC_GPIO_AUX_CTRL_3__AUX3_DP_DN_SWAP_MASK 0x00000400L
11002#define DC_GPIO_AUX_CTRL_3__AUX4_DP_DN_SWAP_MASK 0x00000800L
11003#define DC_GPIO_AUX_CTRL_3__AUX5_DP_DN_SWAP_MASK 0x00001000L
11004#define DC_GPIO_AUX_CTRL_3__AUX6_DP_DN_SWAP_MASK 0x00002000L
11005#define DC_GPIO_AUX_CTRL_3__AUX1_HYS_TUNE_MASK 0x00030000L
11006#define DC_GPIO_AUX_CTRL_3__AUX2_HYS_TUNE_MASK 0x000C0000L
11007#define DC_GPIO_AUX_CTRL_3__AUX3_HYS_TUNE_MASK 0x00300000L
11008#define DC_GPIO_AUX_CTRL_3__AUX4_HYS_TUNE_MASK 0x00C00000L
11009#define DC_GPIO_AUX_CTRL_3__AUX5_HYS_TUNE_MASK 0x03000000L
11010#define DC_GPIO_AUX_CTRL_3__AUX6_HYS_TUNE_MASK 0x0C000000L
11011//DC_GPIO_AUX_CTRL_4
11012#define DC_GPIO_AUX_CTRL_4__AUX1_AUX_CTRL__SHIFT 0x0
11013#define DC_GPIO_AUX_CTRL_4__AUX2_AUX_CTRL__SHIFT 0x4
11014#define DC_GPIO_AUX_CTRL_4__AUX3_AUX_CTRL__SHIFT 0x8
11015#define DC_GPIO_AUX_CTRL_4__AUX4_AUX_CTRL__SHIFT 0xc
11016#define DC_GPIO_AUX_CTRL_4__AUX5_AUX_CTRL__SHIFT 0x10
11017#define DC_GPIO_AUX_CTRL_4__AUX6_AUX_CTRL__SHIFT 0x14
11018#define DC_GPIO_AUX_CTRL_4__AUX1_AUX_CTRL_MASK 0x0000000FL
11019#define DC_GPIO_AUX_CTRL_4__AUX2_AUX_CTRL_MASK 0x000000F0L
11020#define DC_GPIO_AUX_CTRL_4__AUX3_AUX_CTRL_MASK 0x00000F00L
11021#define DC_GPIO_AUX_CTRL_4__AUX4_AUX_CTRL_MASK 0x0000F000L
11022#define DC_GPIO_AUX_CTRL_4__AUX5_AUX_CTRL_MASK 0x000F0000L
11023#define DC_GPIO_AUX_CTRL_4__AUX6_AUX_CTRL_MASK 0x00F00000L
11024//DC_GPIO_AUX_CTRL_5
11025#define DC_GPIO_AUX_CTRL_5__AUX1_VOD_TUNE__SHIFT 0x0
11026#define DC_GPIO_AUX_CTRL_5__AUX2_VOD_TUNE__SHIFT 0x2
11027#define DC_GPIO_AUX_CTRL_5__AUX3_VOD_TUNE__SHIFT 0x4
11028#define DC_GPIO_AUX_CTRL_5__AUX4_VOD_TUNE__SHIFT 0x6
11029#define DC_GPIO_AUX_CTRL_5__AUX5_VOD_TUNE__SHIFT 0x8
11030#define DC_GPIO_AUX_CTRL_5__AUX6_VOD_TUNE__SHIFT 0xa
11031#define DC_GPIO_AUX_CTRL_5__DDC_PAD1_I2CMODE__SHIFT 0xc
11032#define DC_GPIO_AUX_CTRL_5__DDC_PAD2_I2CMODE__SHIFT 0xd
11033#define DC_GPIO_AUX_CTRL_5__DDC_PAD3_I2CMODE__SHIFT 0xe
11034#define DC_GPIO_AUX_CTRL_5__DDC_PAD4_I2CMODE__SHIFT 0xf
11035#define DC_GPIO_AUX_CTRL_5__DDC_PAD5_I2CMODE__SHIFT 0x10
11036#define DC_GPIO_AUX_CTRL_5__DDC_PAD6_I2CMODE__SHIFT 0x11
11037#define DC_GPIO_AUX_CTRL_5__DDC1_I2C_VPH_1V2_EN__SHIFT 0x12
11038#define DC_GPIO_AUX_CTRL_5__DDC2_I2C_VPH_1V2_EN__SHIFT 0x13
11039#define DC_GPIO_AUX_CTRL_5__DDC3_I2C_VPH_1V2_EN__SHIFT 0x14
11040#define DC_GPIO_AUX_CTRL_5__DDC4_I2C_VPH_1V2_EN__SHIFT 0x15
11041#define DC_GPIO_AUX_CTRL_5__DDC5_I2C_VPH_1V2_EN__SHIFT 0x16
11042#define DC_GPIO_AUX_CTRL_5__DDC6_I2C_VPH_1V2_EN__SHIFT 0x17
11043#define DC_GPIO_AUX_CTRL_5__DDC1_PAD_I2C_CTRL__SHIFT 0x18
11044#define DC_GPIO_AUX_CTRL_5__DDC2_PAD_I2C_CTRL__SHIFT 0x19
11045#define DC_GPIO_AUX_CTRL_5__DDC3_PAD_I2C_CTRL__SHIFT 0x1a
11046#define DC_GPIO_AUX_CTRL_5__DDC4_PAD_I2C_CTRL__SHIFT 0x1b
11047#define DC_GPIO_AUX_CTRL_5__DDC5_PAD_I2C_CTRL__SHIFT 0x1c
11048#define DC_GPIO_AUX_CTRL_5__DDC6_PAD_I2C_CTRL__SHIFT 0x1d
11049#define DC_GPIO_AUX_CTRL_5__AUX1_VOD_TUNE_MASK 0x00000003L
11050#define DC_GPIO_AUX_CTRL_5__AUX2_VOD_TUNE_MASK 0x0000000CL
11051#define DC_GPIO_AUX_CTRL_5__AUX3_VOD_TUNE_MASK 0x00000030L
11052#define DC_GPIO_AUX_CTRL_5__AUX4_VOD_TUNE_MASK 0x000000C0L
11053#define DC_GPIO_AUX_CTRL_5__AUX5_VOD_TUNE_MASK 0x00000300L
11054#define DC_GPIO_AUX_CTRL_5__AUX6_VOD_TUNE_MASK 0x00000C00L
11055#define DC_GPIO_AUX_CTRL_5__DDC_PAD1_I2CMODE_MASK 0x00001000L
11056#define DC_GPIO_AUX_CTRL_5__DDC_PAD2_I2CMODE_MASK 0x00002000L
11057#define DC_GPIO_AUX_CTRL_5__DDC_PAD3_I2CMODE_MASK 0x00004000L
11058#define DC_GPIO_AUX_CTRL_5__DDC_PAD4_I2CMODE_MASK 0x00008000L
11059#define DC_GPIO_AUX_CTRL_5__DDC_PAD5_I2CMODE_MASK 0x00010000L
11060#define DC_GPIO_AUX_CTRL_5__DDC_PAD6_I2CMODE_MASK 0x00020000L
11061#define DC_GPIO_AUX_CTRL_5__DDC1_I2C_VPH_1V2_EN_MASK 0x00040000L
11062#define DC_GPIO_AUX_CTRL_5__DDC2_I2C_VPH_1V2_EN_MASK 0x00080000L
11063#define DC_GPIO_AUX_CTRL_5__DDC3_I2C_VPH_1V2_EN_MASK 0x00100000L
11064#define DC_GPIO_AUX_CTRL_5__DDC4_I2C_VPH_1V2_EN_MASK 0x00200000L
11065#define DC_GPIO_AUX_CTRL_5__DDC5_I2C_VPH_1V2_EN_MASK 0x00400000L
11066#define DC_GPIO_AUX_CTRL_5__DDC6_I2C_VPH_1V2_EN_MASK 0x00800000L
11067#define DC_GPIO_AUX_CTRL_5__DDC1_PAD_I2C_CTRL_MASK 0x01000000L
11068#define DC_GPIO_AUX_CTRL_5__DDC2_PAD_I2C_CTRL_MASK 0x02000000L
11069#define DC_GPIO_AUX_CTRL_5__DDC3_PAD_I2C_CTRL_MASK 0x04000000L
11070#define DC_GPIO_AUX_CTRL_5__DDC4_PAD_I2C_CTRL_MASK 0x08000000L
11071#define DC_GPIO_AUX_CTRL_5__DDC5_PAD_I2C_CTRL_MASK 0x10000000L
11072#define DC_GPIO_AUX_CTRL_5__DDC6_PAD_I2C_CTRL_MASK 0x20000000L
11073//AUXI2C_PAD_ALL_PWR_OK
11074#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY1_ALL_PWR_OK__SHIFT 0x0
11075#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY2_ALL_PWR_OK__SHIFT 0x1
11076#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY3_ALL_PWR_OK__SHIFT 0x2
11077#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY4_ALL_PWR_OK__SHIFT 0x3
11078#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY5_ALL_PWR_OK__SHIFT 0x4
11079#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY6_ALL_PWR_OK__SHIFT 0x5
11080#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY1_ALL_PWR_OK_MASK 0x00000001L
11081#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY2_ALL_PWR_OK_MASK 0x00000002L
11082#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY3_ALL_PWR_OK_MASK 0x00000004L
11083#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY4_ALL_PWR_OK_MASK 0x00000008L
11084#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY5_ALL_PWR_OK_MASK 0x00000010L
11085#define AUXI2C_PAD_ALL_PWR_OK__AUXI2C_PHY6_ALL_PWR_OK_MASK 0x00000020L
11086//DC_GPIO_PULLUPEN
11087#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICA_PU_EN__SHIFT 0x0
11088#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICB_PU_EN__SHIFT 0x1
11089#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICC_PU_EN__SHIFT 0x2
11090#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICD_PU_EN__SHIFT 0x3
11091#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICE_PU_EN__SHIFT 0x4
11092#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICF_PU_EN__SHIFT 0x5
11093#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICG_PU_EN__SHIFT 0x6
11094#define DC_GPIO_PULLUPEN__DC_GPIO_HSYNCA_PU_EN__SHIFT 0x8
11095#define DC_GPIO_PULLUPEN__DC_GPIO_VSYNCA_PU_EN__SHIFT 0x9
11096#define DC_GPIO_PULLUPEN__DC_GPIO_HPD1_PU_EN__SHIFT 0xe
11097#define DC_GPIO_PULLUPEN__DC_GPIO_BLON_PU_EN__SHIFT 0x14
11098#define DC_GPIO_PULLUPEN__DC_GPIO_DIGON_PU_EN__SHIFT 0x15
11099#define DC_GPIO_PULLUPEN__DC_GPIO_ENA_BL_PU_EN__SHIFT 0x16
11100#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICA_PU_EN_MASK 0x00000001L
11101#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICB_PU_EN_MASK 0x00000002L
11102#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICC_PU_EN_MASK 0x00000004L
11103#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICD_PU_EN_MASK 0x00000008L
11104#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICE_PU_EN_MASK 0x00000010L
11105#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICF_PU_EN_MASK 0x00000020L
11106#define DC_GPIO_PULLUPEN__DC_GPIO_GENERICG_PU_EN_MASK 0x00000040L
11107#define DC_GPIO_PULLUPEN__DC_GPIO_HSYNCA_PU_EN_MASK 0x00000100L
11108#define DC_GPIO_PULLUPEN__DC_GPIO_VSYNCA_PU_EN_MASK 0x00000200L
11109#define DC_GPIO_PULLUPEN__DC_GPIO_HPD1_PU_EN_MASK 0x00004000L
11110#define DC_GPIO_PULLUPEN__DC_GPIO_BLON_PU_EN_MASK 0x00100000L
11111#define DC_GPIO_PULLUPEN__DC_GPIO_DIGON_PU_EN_MASK 0x00200000L
11112#define DC_GPIO_PULLUPEN__DC_GPIO_ENA_BL_PU_EN_MASK 0x00400000L
11113//DC_GPIO_AUX_CTRL_6
11114#define DC_GPIO_AUX_CTRL_6__AUX1_PAD_RXSEL__SHIFT 0x0
11115#define DC_GPIO_AUX_CTRL_6__AUX2_PAD_RXSEL__SHIFT 0x2
11116#define DC_GPIO_AUX_CTRL_6__AUX3_PAD_RXSEL__SHIFT 0x4
11117#define DC_GPIO_AUX_CTRL_6__AUX4_PAD_RXSEL__SHIFT 0x6
11118#define DC_GPIO_AUX_CTRL_6__AUX5_PAD_RXSEL__SHIFT 0x8
11119#define DC_GPIO_AUX_CTRL_6__AUX6_PAD_RXSEL__SHIFT 0xa
11120#define DC_GPIO_AUX_CTRL_6__AUX1_PAD_RXSEL_MASK 0x00000003L
11121#define DC_GPIO_AUX_CTRL_6__AUX2_PAD_RXSEL_MASK 0x0000000CL
11122#define DC_GPIO_AUX_CTRL_6__AUX3_PAD_RXSEL_MASK 0x00000030L
11123#define DC_GPIO_AUX_CTRL_6__AUX4_PAD_RXSEL_MASK 0x000000C0L
11124#define DC_GPIO_AUX_CTRL_6__AUX5_PAD_RXSEL_MASK 0x00000300L
11125#define DC_GPIO_AUX_CTRL_6__AUX6_PAD_RXSEL_MASK 0x00000C00L
10974//BPHYC_DAC_MACRO_CNTL 11126//BPHYC_DAC_MACRO_CNTL
10975#define BPHYC_DAC_MACRO_CNTL__BPHYC_DAC_WHITE_LEVEL__SHIFT 0x0 11127#define BPHYC_DAC_MACRO_CNTL__BPHYC_DAC_WHITE_LEVEL__SHIFT 0x0
10976#define BPHYC_DAC_MACRO_CNTL__BPHYC_DAC_WHITE_FINE_CONTROL__SHIFT 0x8 11128#define BPHYC_DAC_MACRO_CNTL__BPHYC_DAC_WHITE_FINE_CONTROL__SHIFT 0x8
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h
index 4ccf9681c45d..721c61171045 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h
@@ -3895,6 +3895,10 @@
3895#define mmCM0_CM_MEM_PWR_CTRL_BASE_IDX 2 3895#define mmCM0_CM_MEM_PWR_CTRL_BASE_IDX 2
3896#define mmCM0_CM_MEM_PWR_STATUS 0x0d33 3896#define mmCM0_CM_MEM_PWR_STATUS 0x0d33
3897#define mmCM0_CM_MEM_PWR_STATUS_BASE_IDX 2 3897#define mmCM0_CM_MEM_PWR_STATUS_BASE_IDX 2
3898#define mmCM0_CM_TEST_DEBUG_INDEX 0x0d35
3899#define mmCM0_CM_TEST_DEBUG_INDEX_BASE_IDX 2
3900#define mmCM0_CM_TEST_DEBUG_DATA 0x0d36
3901#define mmCM0_CM_TEST_DEBUG_DATA_BASE_IDX 2
3898 3902
3899 3903
3900// addressBlock: dce_dc_dpp0_dispdec_dpp_dcperfmon_dc_perfmon_dispdec 3904// addressBlock: dce_dc_dpp0_dispdec_dpp_dcperfmon_dc_perfmon_dispdec
@@ -4367,7 +4371,10 @@
4367#define mmCM1_CM_MEM_PWR_CTRL_BASE_IDX 2 4371#define mmCM1_CM_MEM_PWR_CTRL_BASE_IDX 2
4368#define mmCM1_CM_MEM_PWR_STATUS 0x0e4e 4372#define mmCM1_CM_MEM_PWR_STATUS 0x0e4e
4369#define mmCM1_CM_MEM_PWR_STATUS_BASE_IDX 2 4373#define mmCM1_CM_MEM_PWR_STATUS_BASE_IDX 2
4370 4374#define mmCM1_CM_TEST_DEBUG_INDEX 0x0e50
4375#define mmCM1_CM_TEST_DEBUG_INDEX_BASE_IDX 2
4376#define mmCM1_CM_TEST_DEBUG_DATA 0x0e51
4377#define mmCM1_CM_TEST_DEBUG_DATA_BASE_IDX 2
4371 4378
4372// addressBlock: dce_dc_dpp1_dispdec_dpp_dcperfmon_dc_perfmon_dispdec 4379// addressBlock: dce_dc_dpp1_dispdec_dpp_dcperfmon_dc_perfmon_dispdec
4373// base address: 0x399c 4380// base address: 0x399c
@@ -4839,7 +4846,10 @@
4839#define mmCM2_CM_MEM_PWR_CTRL_BASE_IDX 2 4846#define mmCM2_CM_MEM_PWR_CTRL_BASE_IDX 2
4840#define mmCM2_CM_MEM_PWR_STATUS 0x0f69 4847#define mmCM2_CM_MEM_PWR_STATUS 0x0f69
4841#define mmCM2_CM_MEM_PWR_STATUS_BASE_IDX 2 4848#define mmCM2_CM_MEM_PWR_STATUS_BASE_IDX 2
4842 4849#define mmCM2_CM_TEST_DEBUG_INDEX 0x0f6b
4850#define mmCM2_CM_TEST_DEBUG_INDEX_BASE_IDX 2
4851#define mmCM2_CM_TEST_DEBUG_DATA 0x0f6c
4852#define mmCM2_CM_TEST_DEBUG_DATA_BASE_IDX 2
4843 4853
4844// addressBlock: dce_dc_dpp2_dispdec_dpp_dcperfmon_dc_perfmon_dispdec 4854// addressBlock: dce_dc_dpp2_dispdec_dpp_dcperfmon_dc_perfmon_dispdec
4845// base address: 0x3e08 4855// base address: 0x3e08
@@ -5311,7 +5321,10 @@
5311#define mmCM3_CM_MEM_PWR_CTRL_BASE_IDX 2 5321#define mmCM3_CM_MEM_PWR_CTRL_BASE_IDX 2
5312#define mmCM3_CM_MEM_PWR_STATUS 0x1084 5322#define mmCM3_CM_MEM_PWR_STATUS 0x1084
5313#define mmCM3_CM_MEM_PWR_STATUS_BASE_IDX 2 5323#define mmCM3_CM_MEM_PWR_STATUS_BASE_IDX 2
5314 5324#define mmCM3_CM_TEST_DEBUG_INDEX 0x1086
5325#define mmCM3_CM_TEST_DEBUG_INDEX_BASE_IDX 2
5326#define mmCM3_CM_TEST_DEBUG_DATA 0x1087
5327#define mmCM3_CM_TEST_DEBUG_DATA_BASE_IDX 2
5315 5328
5316// addressBlock: dce_dc_dpp3_dispdec_dpp_dcperfmon_dc_perfmon_dispdec 5329// addressBlock: dce_dc_dpp3_dispdec_dpp_dcperfmon_dc_perfmon_dispdec
5317// base address: 0x4274 5330// base address: 0x4274
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_sh_mask.h
index e2a2f114bd8e..e7c0cad41081 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_sh_mask.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_sh_mask.h
@@ -14049,6 +14049,14 @@
14049#define CM0_CM_MEM_PWR_STATUS__RGAM_MEM_PWR_STATE__SHIFT 0x2 14049#define CM0_CM_MEM_PWR_STATUS__RGAM_MEM_PWR_STATE__SHIFT 0x2
14050#define CM0_CM_MEM_PWR_STATUS__SHARED_MEM_PWR_STATE_MASK 0x00000003L 14050#define CM0_CM_MEM_PWR_STATUS__SHARED_MEM_PWR_STATE_MASK 0x00000003L
14051#define CM0_CM_MEM_PWR_STATUS__RGAM_MEM_PWR_STATE_MASK 0x0000000CL 14051#define CM0_CM_MEM_PWR_STATUS__RGAM_MEM_PWR_STATE_MASK 0x0000000CL
14052//CM0_CM_TEST_DEBUG_INDEX
14053#define CM0_CM_TEST_DEBUG_INDEX__CM_TEST_DEBUG_INDEX__SHIFT 0x0
14054#define CM0_CM_TEST_DEBUG_INDEX__CM_TEST_DEBUG_WRITE_EN__SHIFT 0x8
14055#define CM0_CM_TEST_DEBUG_INDEX__CM_TEST_DEBUG_INDEX_MASK 0x000000FFL
14056#define CM0_CM_TEST_DEBUG_INDEX__CM_TEST_DEBUG_WRITE_EN_MASK 0x00000100L
14057//CM0_CM_TEST_DEBUG_DATA
14058#define CM0_CM_TEST_DEBUG_DATA__CM_TEST_DEBUG_DATA__SHIFT 0x0
14059#define CM0_CM_TEST_DEBUG_DATA__CM_TEST_DEBUG_DATA_MASK 0xFFFFFFFFL
14052 14060
14053 14061
14054// addressBlock: dce_dc_dpp0_dispdec_dpp_dcperfmon_dc_perfmon_dispdec 14062// addressBlock: dce_dc_dpp0_dispdec_dpp_dcperfmon_dc_perfmon_dispdec
diff --git a/drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_default.h b/drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_default.h
new file mode 100644
index 000000000000..9e19e723081b
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_default.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21#ifndef _df_1_7_DEFAULT_HEADER
22#define _df_1_7_DEFAULT_HEADER
23
24#define mmFabricConfigAccessControl_DEFAULT 0x00000000
25
26#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_offset.h b/drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_offset.h
new file mode 100644
index 000000000000..e6044e27a913
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_offset.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (C) 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21#ifndef _df_1_7_OFFSET_HEADER
22#define _df_1_7_OFFSET_HEADER
23
24#define mmFabricConfigAccessControl 0x0410
25#define mmFabricConfigAccessControl_BASE_IDX 0
26
27#define mmDF_PIE_AON0_DfGlobalClkGater 0x00fc
28#define mmDF_PIE_AON0_DfGlobalClkGater_BASE_IDX 0
29
30#define mmDF_CS_AON0_DramBaseAddress0 0x0044
31#define mmDF_CS_AON0_DramBaseAddress0_BASE_IDX 0
32
33#define mmDF_CS_AON0_CoherentSlaveModeCtrlA0 0x0214
34#define mmDF_CS_AON0_CoherentSlaveModeCtrlA0_BASE_IDX 0
35
36
37#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_sh_mask.h
new file mode 100644
index 000000000000..a78c99480e2d
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/df/df_1_7_sh_mask.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (C) 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21#ifndef _df_1_7_SH_MASK_HEADER
22#define _df_1_7_SH_MASK_HEADER
23
24/* FabricConfigAccessControl */
25#define FabricConfigAccessControl__CfgRegInstAccEn__SHIFT 0x0
26#define FabricConfigAccessControl__CfgRegInstAccRegLock__SHIFT 0x1
27#define FabricConfigAccessControl__CfgRegInstID__SHIFT 0x10
28#define FabricConfigAccessControl__CfgRegInstAccEn_MASK 0x00000001L
29#define FabricConfigAccessControl__CfgRegInstAccRegLock_MASK 0x00000002L
30#define FabricConfigAccessControl__CfgRegInstID_MASK 0x00FF0000L
31
32/* DF_PIE_AON0_DfGlobalClkGater */
33#define DF_PIE_AON0_DfGlobalClkGater__MGCGMode__SHIFT 0x0
34#define DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK 0x0000000FL
35
36/* DF_CS_AON0_DramBaseAddress0 */
37#define DF_CS_AON0_DramBaseAddress0__AddrRngVal__SHIFT 0x0
38#define DF_CS_AON0_DramBaseAddress0__LgcyMmioHoleEn__SHIFT 0x1
39#define DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT 0x4
40#define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel__SHIFT 0x8
41#define DF_CS_AON0_DramBaseAddress0__DramBaseAddr__SHIFT 0xc
42#define DF_CS_AON0_DramBaseAddress0__AddrRngVal_MASK 0x00000001L
43#define DF_CS_AON0_DramBaseAddress0__LgcyMmioHoleEn_MASK 0x00000002L
44#define DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK 0x000000F0L
45#define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel_MASK 0x00000700L
46#define DF_CS_AON0_DramBaseAddress0__DramBaseAddr_MASK 0xFFFFF000L
47
48//DF_CS_AON0_CoherentSlaveModeCtrlA0
49#define DF_CS_AON0_CoherentSlaveModeCtrlA0__ForceParWrRMW__SHIFT 0x3
50#define DF_CS_AON0_CoherentSlaveModeCtrlA0__ForceParWrRMW_MASK 0x00000008L
51
52#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_default.h b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_default.h
new file mode 100644
index 000000000000..e58c207ac980
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_default.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21#ifndef _df_3_6_DEFAULT_HEADER
22#define _df_3_6_DEFAULT_HEADER
23
24#define mmFabricConfigAccessControl_DEFAULT 0x00000000
25
26#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_offset.h b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_offset.h
new file mode 100644
index 000000000000..a9575db8d7aa
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_offset.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21#ifndef _df_3_6_OFFSET_HEADER
22#define _df_3_6_OFFSET_HEADER
23
24#define mmFabricConfigAccessControl 0x0410
25#define mmFabricConfigAccessControl_BASE_IDX 0
26
27#define mmDF_PIE_AON0_DfGlobalClkGater 0x00fc
28#define mmDF_PIE_AON0_DfGlobalClkGater_BASE_IDX 0
29
30#define mmDF_CS_UMC_AON0_DramBaseAddress0 0x0044
31#define mmDF_CS_UMC_AON0_DramBaseAddress0_BASE_IDX 0
32
33#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_sh_mask.h
new file mode 100644
index 000000000000..88f7c69df6b9
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_sh_mask.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21#ifndef _df_3_6_SH_MASK_HEADER
22#define _df_3_6_SH_MASK_HEADER
23
24/* FabricConfigAccessControl */
25#define FabricConfigAccessControl__CfgRegInstAccEn__SHIFT 0x0
26#define FabricConfigAccessControl__CfgRegInstAccRegLock__SHIFT 0x1
27#define FabricConfigAccessControl__CfgRegInstID__SHIFT 0x10
28#define FabricConfigAccessControl__CfgRegInstAccEn_MASK 0x00000001L
29#define FabricConfigAccessControl__CfgRegInstAccRegLock_MASK 0x00000002L
30#define FabricConfigAccessControl__CfgRegInstID_MASK 0x00FF0000L
31
32/* DF_PIE_AON0_DfGlobalClkGater */
33#define DF_PIE_AON0_DfGlobalClkGater__MGCGMode__SHIFT 0x0
34#define DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK 0x0000000FL
35
36/* DF_CS_AON0_DramBaseAddress0 */
37#define DF_CS_UMC_AON0_DramBaseAddress0__AddrRngVal__SHIFT 0x0
38#define DF_CS_UMC_AON0_DramBaseAddress0__LgcyMmioHoleEn__SHIFT 0x1
39#define DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan__SHIFT 0x4
40#define DF_CS_UMC_AON0_DramBaseAddress0__IntLvAddrSel__SHIFT 0x8
41#define DF_CS_UMC_AON0_DramBaseAddress0__DramBaseAddr__SHIFT 0xc
42#define DF_CS_UMC_AON0_DramBaseAddress0__AddrRngVal_MASK 0x00000001L
43#define DF_CS_UMC_AON0_DramBaseAddress0__LgcyMmioHoleEn_MASK 0x00000002L
44#define DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan_MASK 0x000000F0L
45#define DF_CS_UMC_AON0_DramBaseAddress0__IntLvAddrSel_MASK 0x00000700L
46#define DF_CS_UMC_AON0_DramBaseAddress0__DramBaseAddr_MASK 0xFFFFF000L
47
48#endif
diff --git a/drivers/gpu/drm/amd/include/atombios.h b/drivers/gpu/drm/amd/include/atombios.h
index f696bbb643ef..7931502fa54f 100644
--- a/drivers/gpu/drm/amd/include/atombios.h
+++ b/drivers/gpu/drm/amd/include/atombios.h
@@ -632,6 +632,13 @@ typedef struct _COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_2
632 ULONG ulReserved; 632 ULONG ulReserved;
633}COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_2; 633}COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_2;
634 634
635typedef struct _COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_3
636{
637 COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 ulClock;
638 USHORT usMclk_fcw_frac; //fractional divider of fcw = usSclk_fcw_frac/65536
639 USHORT usMclk_fcw_int; //integer divider of fcwc
640}COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_3;
641
635//Input parameter of DynamicMemorySettingsTable 642//Input parameter of DynamicMemorySettingsTable
636//when ATOM_COMPUTE_CLOCK_FREQ.ulComputeClockFlag = COMPUTE_MEMORY_PLL_PARAM 643//when ATOM_COMPUTE_CLOCK_FREQ.ulComputeClockFlag = COMPUTE_MEMORY_PLL_PARAM
637typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER 644typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index de177ce8ca80..c6c1666ac120 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -1219,6 +1219,41 @@ struct atom_gfx_info_v2_3 {
1219 uint32_t rm21_sram_vmin_value; 1219 uint32_t rm21_sram_vmin_value;
1220}; 1220};
1221 1221
1222struct atom_gfx_info_v2_4 {
1223 struct atom_common_table_header table_header;
1224 uint8_t gfxip_min_ver;
1225 uint8_t gfxip_max_ver;
1226 uint8_t gc_num_se;
1227 uint8_t max_tile_pipes;
1228 uint8_t gc_num_cu_per_sh;
1229 uint8_t gc_num_sh_per_se;
1230 uint8_t gc_num_rb_per_se;
1231 uint8_t gc_num_tccs;
1232 uint32_t regaddr_cp_dma_src_addr;
1233 uint32_t regaddr_cp_dma_src_addr_hi;
1234 uint32_t regaddr_cp_dma_dst_addr;
1235 uint32_t regaddr_cp_dma_dst_addr_hi;
1236 uint32_t regaddr_cp_dma_command;
1237 uint32_t regaddr_cp_status;
1238 uint32_t regaddr_rlc_gpu_clock_32;
1239 uint32_t rlc_gpu_timer_refclk;
1240 uint8_t active_cu_per_sh;
1241 uint8_t active_rb_per_se;
1242 uint16_t gcgoldenoffset;
1243 uint16_t gc_num_gprs;
1244 uint16_t gc_gsprim_buff_depth;
1245 uint16_t gc_parameter_cache_depth;
1246 uint16_t gc_wave_size;
1247 uint16_t gc_max_waves_per_simd;
1248 uint16_t gc_lds_size;
1249 uint8_t gc_num_max_gs_thds;
1250 uint8_t gc_gs_table_depth;
1251 uint8_t gc_double_offchip_lds_buffer;
1252 uint8_t gc_max_scratch_slots_per_cu;
1253 uint32_t sram_rm_fuses_val;
1254 uint32_t sram_custom_rm_fuses_val;
1255};
1256
1222/* 1257/*
1223 *************************************************************************** 1258 ***************************************************************************
1224 Data Table smu_info structure 1259 Data Table smu_info structure
diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h
index f2814ae7ecdd..a69deb3a2ac0 100644
--- a/drivers/gpu/drm/amd/include/cgs_common.h
+++ b/drivers/gpu/drm/amd/include/cgs_common.h
@@ -42,20 +42,6 @@ enum cgs_ind_reg {
42 CGS_IND_REG__AUDIO_ENDPT 42 CGS_IND_REG__AUDIO_ENDPT
43}; 43};
44 44
45/**
46 * enum cgs_engine - Engines that can be statically power-gated
47 */
48enum cgs_engine {
49 CGS_ENGINE__UVD,
50 CGS_ENGINE__VCE,
51 CGS_ENGINE__VP8,
52 CGS_ENGINE__ACP_DMA,
53 CGS_ENGINE__ACP_DSP0,
54 CGS_ENGINE__ACP_DSP1,
55 CGS_ENGINE__ISP,
56 /* ... */
57};
58
59/* 45/*
60 * enum cgs_ucode_id - Firmware types for different IPs 46 * enum cgs_ucode_id - Firmware types for different IPs
61 */ 47 */
@@ -76,17 +62,6 @@ enum cgs_ucode_id {
76 CGS_UCODE_ID_MAXIMUM, 62 CGS_UCODE_ID_MAXIMUM,
77}; 63};
78 64
79/*
80 * enum cgs_resource_type - GPU resource type
81 */
82enum cgs_resource_type {
83 CGS_RESOURCE_TYPE_MMIO = 0,
84 CGS_RESOURCE_TYPE_FB,
85 CGS_RESOURCE_TYPE_IO,
86 CGS_RESOURCE_TYPE_DOORBELL,
87 CGS_RESOURCE_TYPE_ROM,
88};
89
90/** 65/**
91 * struct cgs_firmware_info - Firmware information 66 * struct cgs_firmware_info - Firmware information
92 */ 67 */
@@ -104,17 +79,6 @@ struct cgs_firmware_info {
104 bool is_kicker; 79 bool is_kicker;
105}; 80};
106 81
107struct cgs_mode_info {
108 uint32_t refresh_rate;
109 uint32_t vblank_time_us;
110};
111
112struct cgs_display_info {
113 uint32_t display_count;
114 uint32_t active_display_mask;
115 struct cgs_mode_info *mode_info;
116};
117
118typedef unsigned long cgs_handle_t; 82typedef unsigned long cgs_handle_t;
119 83
120/** 84/**
@@ -170,119 +134,18 @@ typedef void (*cgs_write_ind_register_t)(struct cgs_device *cgs_device, enum cgs
170#define CGS_WREG32_FIELD_IND(device, space, reg, field, val) \ 134#define CGS_WREG32_FIELD_IND(device, space, reg, field, val) \
171 cgs_write_ind_register(device, space, ix##reg, (cgs_read_ind_register(device, space, ix##reg) & ~CGS_REG_FIELD_MASK(reg, field)) | (val) << CGS_REG_FIELD_SHIFT(reg, field)) 135 cgs_write_ind_register(device, space, ix##reg, (cgs_read_ind_register(device, space, ix##reg) & ~CGS_REG_FIELD_MASK(reg, field)) | (val) << CGS_REG_FIELD_SHIFT(reg, field))
172 136
173/**
174 * cgs_get_pci_resource() - provide access to a device resource (PCI BAR)
175 * @cgs_device: opaque device handle
176 * @resource_type: Type of Resource (MMIO, IO, ROM, FB, DOORBELL)
177 * @size: size of the region
178 * @offset: offset from the start of the region
179 * @resource_base: base address (not including offset) returned
180 *
181 * Return: 0 on success, -errno otherwise
182 */
183typedef int (*cgs_get_pci_resource_t)(struct cgs_device *cgs_device,
184 enum cgs_resource_type resource_type,
185 uint64_t size,
186 uint64_t offset,
187 uint64_t *resource_base);
188
189/**
190 * cgs_atom_get_data_table() - Get a pointer to an ATOM BIOS data table
191 * @cgs_device: opaque device handle
192 * @table: data table index
193 * @size: size of the table (output, may be NULL)
194 * @frev: table format revision (output, may be NULL)
195 * @crev: table content revision (output, may be NULL)
196 *
197 * Return: Pointer to start of the table, or NULL on failure
198 */
199typedef const void *(*cgs_atom_get_data_table_t)(
200 struct cgs_device *cgs_device, unsigned table,
201 uint16_t *size, uint8_t *frev, uint8_t *crev);
202
203/**
204 * cgs_atom_get_cmd_table_revs() - Get ATOM BIOS command table revisions
205 * @cgs_device: opaque device handle
206 * @table: data table index
207 * @frev: table format revision (output, may be NULL)
208 * @crev: table content revision (output, may be NULL)
209 *
210 * Return: 0 on success, -errno otherwise
211 */
212typedef int (*cgs_atom_get_cmd_table_revs_t)(struct cgs_device *cgs_device, unsigned table,
213 uint8_t *frev, uint8_t *crev);
214
215/**
216 * cgs_atom_exec_cmd_table() - Execute an ATOM BIOS command table
217 * @cgs_device: opaque device handle
218 * @table: command table index
219 * @args: arguments
220 *
221 * Return: 0 on success, -errno otherwise
222 */
223typedef int (*cgs_atom_exec_cmd_table_t)(struct cgs_device *cgs_device,
224 unsigned table, void *args);
225
226/**
227 * cgs_get_firmware_info - Get the firmware information from core driver
228 * @cgs_device: opaque device handle
229 * @type: the firmware type
230 * @info: returend firmware information
231 *
232 * Return: 0 on success, -errno otherwise
233 */
234typedef int (*cgs_get_firmware_info)(struct cgs_device *cgs_device, 137typedef int (*cgs_get_firmware_info)(struct cgs_device *cgs_device,
235 enum cgs_ucode_id type, 138 enum cgs_ucode_id type,
236 struct cgs_firmware_info *info); 139 struct cgs_firmware_info *info);
237 140
238typedef int (*cgs_rel_firmware)(struct cgs_device *cgs_device,
239 enum cgs_ucode_id type);
240
241typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device,
242 enum amd_ip_block_type block_type,
243 enum amd_powergating_state state);
244
245typedef int(*cgs_set_clockgating_state)(struct cgs_device *cgs_device,
246 enum amd_ip_block_type block_type,
247 enum amd_clockgating_state state);
248
249typedef int(*cgs_get_active_displays_info)(
250 struct cgs_device *cgs_device,
251 struct cgs_display_info *info);
252
253typedef int (*cgs_notify_dpm_enabled)(struct cgs_device *cgs_device, bool enabled);
254
255typedef int (*cgs_is_virtualization_enabled_t)(void *cgs_device);
256
257typedef int (*cgs_enter_safe_mode)(struct cgs_device *cgs_device, bool en);
258
259typedef void (*cgs_lock_grbm_idx)(struct cgs_device *cgs_device, bool lock);
260
261struct cgs_ops { 141struct cgs_ops {
262 /* MMIO access */ 142 /* MMIO access */
263 cgs_read_register_t read_register; 143 cgs_read_register_t read_register;
264 cgs_write_register_t write_register; 144 cgs_write_register_t write_register;
265 cgs_read_ind_register_t read_ind_register; 145 cgs_read_ind_register_t read_ind_register;
266 cgs_write_ind_register_t write_ind_register; 146 cgs_write_ind_register_t write_ind_register;
267 /* PCI resources */
268 cgs_get_pci_resource_t get_pci_resource;
269 /* ATOM BIOS */
270 cgs_atom_get_data_table_t atom_get_data_table;
271 cgs_atom_get_cmd_table_revs_t atom_get_cmd_table_revs;
272 cgs_atom_exec_cmd_table_t atom_exec_cmd_table;
273 /* Firmware Info */ 147 /* Firmware Info */
274 cgs_get_firmware_info get_firmware_info; 148 cgs_get_firmware_info get_firmware_info;
275 cgs_rel_firmware rel_firmware;
276 /* cg pg interface*/
277 cgs_set_powergating_state set_powergating_state;
278 cgs_set_clockgating_state set_clockgating_state;
279 /* display manager */
280 cgs_get_active_displays_info get_active_displays_info;
281 /* notify dpm enabled */
282 cgs_notify_dpm_enabled notify_dpm_enabled;
283 cgs_is_virtualization_enabled_t is_virtualization_enabled;
284 cgs_enter_safe_mode enter_safe_mode;
285 cgs_lock_grbm_idx lock_grbm_idx;
286}; 149};
287 150
288struct cgs_os_ops; /* To be define in OS-specific CGS header */ 151struct cgs_os_ops; /* To be define in OS-specific CGS header */
@@ -309,40 +172,7 @@ struct cgs_device
309#define cgs_write_ind_register(dev,space,index,value) \ 172#define cgs_write_ind_register(dev,space,index,value) \
310 CGS_CALL(write_ind_register,dev,space,index,value) 173 CGS_CALL(write_ind_register,dev,space,index,value)
311 174
312#define cgs_atom_get_data_table(dev,table,size,frev,crev) \
313 CGS_CALL(atom_get_data_table,dev,table,size,frev,crev)
314#define cgs_atom_get_cmd_table_revs(dev,table,frev,crev) \
315 CGS_CALL(atom_get_cmd_table_revs,dev,table,frev,crev)
316#define cgs_atom_exec_cmd_table(dev,table,args) \
317 CGS_CALL(atom_exec_cmd_table,dev,table,args)
318
319#define cgs_get_firmware_info(dev, type, info) \ 175#define cgs_get_firmware_info(dev, type, info) \
320 CGS_CALL(get_firmware_info, dev, type, info) 176 CGS_CALL(get_firmware_info, dev, type, info)
321#define cgs_rel_firmware(dev, type) \
322 CGS_CALL(rel_firmware, dev, type)
323#define cgs_set_powergating_state(dev, block_type, state) \
324 CGS_CALL(set_powergating_state, dev, block_type, state)
325#define cgs_set_clockgating_state(dev, block_type, state) \
326 CGS_CALL(set_clockgating_state, dev, block_type, state)
327#define cgs_notify_dpm_enabled(dev, enabled) \
328 CGS_CALL(notify_dpm_enabled, dev, enabled)
329
330#define cgs_get_active_displays_info(dev, info) \
331 CGS_CALL(get_active_displays_info, dev, info)
332
333#define cgs_get_pci_resource(cgs_device, resource_type, size, offset, \
334 resource_base) \
335 CGS_CALL(get_pci_resource, cgs_device, resource_type, size, offset, \
336 resource_base)
337
338#define cgs_is_virtualization_enabled(cgs_device) \
339 CGS_CALL(is_virtualization_enabled, cgs_device)
340
341#define cgs_enter_safe_mode(cgs_device, en) \
342 CGS_CALL(enter_safe_mode, cgs_device, en)
343
344#define cgs_lock_grbm_idx(cgs_device, lock) \
345 CGS_CALL(lock_grbm_idx, cgs_device, lock)
346
347 177
348#endif /* _CGS_COMMON_H */ 178#endif /* _CGS_COMMON_H */
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
index 237289a72bb7..5733fbee07f7 100644
--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
@@ -100,6 +100,21 @@ struct kgd2kfd_shared_resources {
100 /* Bit n == 1 means Queue n is available for KFD */ 100 /* Bit n == 1 means Queue n is available for KFD */
101 DECLARE_BITMAP(queue_bitmap, KGD_MAX_QUEUES); 101 DECLARE_BITMAP(queue_bitmap, KGD_MAX_QUEUES);
102 102
103 /* Doorbell assignments (SOC15 and later chips only). Only
104 * specific doorbells are routed to each SDMA engine. Others
105 * are routed to IH and VCN. They are not usable by the CP.
106 *
107 * Any doorbell number D that satisfies the following condition
108 * is reserved: (D & reserved_doorbell_mask) == reserved_doorbell_val
109 *
110 * KFD currently uses 1024 (= 0x3ff) doorbells per process. If
111 * doorbells 0x0f0-0x0f7 and 0x2f-0x2f7 are reserved, that means
112 * mask would be set to 0x1f8 and val set to 0x0f0.
113 */
114 unsigned int sdma_doorbell[2][2];
115 unsigned int reserved_doorbell_mask;
116 unsigned int reserved_doorbell_val;
117
103 /* Base address of doorbell aperture. */ 118 /* Base address of doorbell aperture. */
104 phys_addr_t doorbell_physical_address; 119 phys_addr_t doorbell_physical_address;
105 120
@@ -173,8 +188,6 @@ struct tile_config {
173 * @set_pasid_vmid_mapping: Exposes pasid/vmid pair to the H/W for no cp 188 * @set_pasid_vmid_mapping: Exposes pasid/vmid pair to the H/W for no cp
174 * scheduling mode. Only used for no cp scheduling mode. 189 * scheduling mode. Only used for no cp scheduling mode.
175 * 190 *
176 * @init_pipeline: Initialized the compute pipelines.
177 *
178 * @hqd_load: Loads the mqd structure to a H/W hqd slot. used only for no cp 191 * @hqd_load: Loads the mqd structure to a H/W hqd slot. used only for no cp
179 * sceduling mode. 192 * sceduling mode.
180 * 193 *
@@ -274,9 +287,6 @@ struct kfd2kgd_calls {
274 int (*set_pasid_vmid_mapping)(struct kgd_dev *kgd, unsigned int pasid, 287 int (*set_pasid_vmid_mapping)(struct kgd_dev *kgd, unsigned int pasid,
275 unsigned int vmid); 288 unsigned int vmid);
276 289
277 int (*init_pipeline)(struct kgd_dev *kgd, uint32_t pipe_id,
278 uint32_t hpd_size, uint64_t hpd_gpu_addr);
279
280 int (*init_interrupts)(struct kgd_dev *kgd, uint32_t pipe_id); 290 int (*init_interrupts)(struct kgd_dev *kgd, uint32_t pipe_id);
281 291
282 int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, 292 int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
@@ -382,6 +392,10 @@ struct kfd2kgd_calls {
382 * 392 *
383 * @resume: Notifies amdkfd about a resume action done to a kgd device 393 * @resume: Notifies amdkfd about a resume action done to a kgd device
384 * 394 *
395 * @quiesce_mm: Quiesce all user queue access to specified MM address space
396 *
397 * @resume_mm: Resume user queue access to specified MM address space
398 *
385 * @schedule_evict_and_restore_process: Schedules work queue that will prepare 399 * @schedule_evict_and_restore_process: Schedules work queue that will prepare
386 * for safe eviction of KFD BOs that belong to the specified process. 400 * for safe eviction of KFD BOs that belong to the specified process.
387 * 401 *
@@ -399,6 +413,8 @@ struct kgd2kfd_calls {
399 void (*interrupt)(struct kfd_dev *kfd, const void *ih_ring_entry); 413 void (*interrupt)(struct kfd_dev *kfd, const void *ih_ring_entry);
400 void (*suspend)(struct kfd_dev *kfd); 414 void (*suspend)(struct kfd_dev *kfd);
401 int (*resume)(struct kfd_dev *kfd); 415 int (*resume)(struct kfd_dev *kfd);
416 int (*quiesce_mm)(struct mm_struct *mm);
417 int (*resume_mm)(struct mm_struct *mm);
402 int (*schedule_evict_and_restore_process)(struct mm_struct *mm, 418 int (*schedule_evict_and_restore_process)(struct mm_struct *mm,
403 struct dma_fence *fence); 419 struct dma_fence *fence);
404}; 420};
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 5c840c022b52..06f08f34a110 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -94,6 +94,7 @@ enum pp_clock_type {
94 PP_PCIE, 94 PP_PCIE,
95 OD_SCLK, 95 OD_SCLK,
96 OD_MCLK, 96 OD_MCLK,
97 OD_RANGE,
97}; 98};
98 99
99enum amd_pp_sensors { 100enum amd_pp_sensors {
@@ -149,13 +150,6 @@ struct pp_states_info {
149 uint32_t states[16]; 150 uint32_t states[16];
150}; 151};
151 152
152struct pp_gpu_power {
153 uint32_t vddc_power;
154 uint32_t vddci_power;
155 uint32_t max_gpu_power;
156 uint32_t average_gpu_power;
157};
158
159#define PP_GROUP_MASK 0xF0000000 153#define PP_GROUP_MASK 0xF0000000
160#define PP_GROUP_SHIFT 28 154#define PP_GROUP_SHIFT 28
161 155
@@ -246,11 +240,6 @@ struct amd_pm_funcs {
246 int (*load_firmware)(void *handle); 240 int (*load_firmware)(void *handle);
247 int (*wait_for_fw_loading_complete)(void *handle); 241 int (*wait_for_fw_loading_complete)(void *handle);
248 int (*set_clockgating_by_smu)(void *handle, uint32_t msg_id); 242 int (*set_clockgating_by_smu)(void *handle, uint32_t msg_id);
249 int (*notify_smu_memory_info)(void *handle, uint32_t virtual_addr_low,
250 uint32_t virtual_addr_hi,
251 uint32_t mc_addr_low,
252 uint32_t mc_addr_hi,
253 uint32_t size);
254 int (*set_power_limit)(void *handle, uint32_t n); 243 int (*set_power_limit)(void *handle, uint32_t n);
255 int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit); 244 int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit);
256/* export to DC */ 245/* export to DC */
diff --git a/drivers/gpu/drm/amd/include/soc15_ih_clientid.h b/drivers/gpu/drm/amd/include/soc15_ih_clientid.h
index a12d4f27cfa4..12e196c15bbe 100644
--- a/drivers/gpu/drm/amd/include/soc15_ih_clientid.h
+++ b/drivers/gpu/drm/amd/include/soc15_ih_clientid.h
@@ -43,6 +43,7 @@ enum soc15_ih_clientid {
43 SOC15_IH_CLIENTID_SE2SH = 0x0c, 43 SOC15_IH_CLIENTID_SE2SH = 0x0c,
44 SOC15_IH_CLIENTID_SE3SH = 0x0d, 44 SOC15_IH_CLIENTID_SE3SH = 0x0d,
45 SOC15_IH_CLIENTID_SYSHUB = 0x0e, 45 SOC15_IH_CLIENTID_SYSHUB = 0x0e,
46 SOC15_IH_CLIENTID_UVD1 = 0x0e,
46 SOC15_IH_CLIENTID_THM = 0x0f, 47 SOC15_IH_CLIENTID_THM = 0x0f,
47 SOC15_IH_CLIENTID_UVD = 0x10, 48 SOC15_IH_CLIENTID_UVD = 0x10,
48 SOC15_IH_CLIENTID_VCE0 = 0x11, 49 SOC15_IH_CLIENTID_VCE0 = 0x11,
diff --git a/drivers/gpu/drm/amd/include/v9_structs.h b/drivers/gpu/drm/amd/include/v9_structs.h
index 2fb25abaf7c8..ceaf4932258d 100644
--- a/drivers/gpu/drm/amd/include/v9_structs.h
+++ b/drivers/gpu/drm/amd/include/v9_structs.h
@@ -29,10 +29,10 @@ struct v9_sdma_mqd {
29 uint32_t sdmax_rlcx_rb_base; 29 uint32_t sdmax_rlcx_rb_base;
30 uint32_t sdmax_rlcx_rb_base_hi; 30 uint32_t sdmax_rlcx_rb_base_hi;
31 uint32_t sdmax_rlcx_rb_rptr; 31 uint32_t sdmax_rlcx_rb_rptr;
32 uint32_t sdmax_rlcx_rb_rptr_hi;
32 uint32_t sdmax_rlcx_rb_wptr; 33 uint32_t sdmax_rlcx_rb_wptr;
34 uint32_t sdmax_rlcx_rb_wptr_hi;
33 uint32_t sdmax_rlcx_rb_wptr_poll_cntl; 35 uint32_t sdmax_rlcx_rb_wptr_poll_cntl;
34 uint32_t sdmax_rlcx_rb_wptr_poll_addr_hi;
35 uint32_t sdmax_rlcx_rb_wptr_poll_addr_lo;
36 uint32_t sdmax_rlcx_rb_rptr_addr_hi; 36 uint32_t sdmax_rlcx_rb_rptr_addr_hi;
37 uint32_t sdmax_rlcx_rb_rptr_addr_lo; 37 uint32_t sdmax_rlcx_rb_rptr_addr_lo;
38 uint32_t sdmax_rlcx_ib_cntl; 38 uint32_t sdmax_rlcx_ib_cntl;
@@ -44,29 +44,29 @@ struct v9_sdma_mqd {
44 uint32_t sdmax_rlcx_skip_cntl; 44 uint32_t sdmax_rlcx_skip_cntl;
45 uint32_t sdmax_rlcx_context_status; 45 uint32_t sdmax_rlcx_context_status;
46 uint32_t sdmax_rlcx_doorbell; 46 uint32_t sdmax_rlcx_doorbell;
47 uint32_t sdmax_rlcx_virtual_addr; 47 uint32_t sdmax_rlcx_status;
48 uint32_t sdmax_rlcx_ape1_cntl;
49 uint32_t sdmax_rlcx_doorbell_log; 48 uint32_t sdmax_rlcx_doorbell_log;
50 uint32_t reserved_22; 49 uint32_t sdmax_rlcx_watermark;
51 uint32_t reserved_23; 50 uint32_t sdmax_rlcx_doorbell_offset;
52 uint32_t reserved_24; 51 uint32_t sdmax_rlcx_csa_addr_lo;
53 uint32_t reserved_25; 52 uint32_t sdmax_rlcx_csa_addr_hi;
54 uint32_t reserved_26; 53 uint32_t sdmax_rlcx_ib_sub_remain;
55 uint32_t reserved_27; 54 uint32_t sdmax_rlcx_preempt;
56 uint32_t reserved_28; 55 uint32_t sdmax_rlcx_dummy_reg;
57 uint32_t reserved_29; 56 uint32_t sdmax_rlcx_rb_wptr_poll_addr_hi;
58 uint32_t reserved_30; 57 uint32_t sdmax_rlcx_rb_wptr_poll_addr_lo;
59 uint32_t reserved_31; 58 uint32_t sdmax_rlcx_rb_aql_cntl;
60 uint32_t reserved_32; 59 uint32_t sdmax_rlcx_minor_ptr_update;
61 uint32_t reserved_33; 60 uint32_t sdmax_rlcx_midcmd_data0;
62 uint32_t reserved_34; 61 uint32_t sdmax_rlcx_midcmd_data1;
63 uint32_t reserved_35; 62 uint32_t sdmax_rlcx_midcmd_data2;
64 uint32_t reserved_36; 63 uint32_t sdmax_rlcx_midcmd_data3;
65 uint32_t reserved_37; 64 uint32_t sdmax_rlcx_midcmd_data4;
66 uint32_t reserved_38; 65 uint32_t sdmax_rlcx_midcmd_data5;
67 uint32_t reserved_39; 66 uint32_t sdmax_rlcx_midcmd_data6;
68 uint32_t reserved_40; 67 uint32_t sdmax_rlcx_midcmd_data7;
69 uint32_t reserved_41; 68 uint32_t sdmax_rlcx_midcmd_data8;
69 uint32_t sdmax_rlcx_midcmd_cntl;
70 uint32_t reserved_42; 70 uint32_t reserved_42;
71 uint32_t reserved_43; 71 uint32_t reserved_43;
72 uint32_t reserved_44; 72 uint32_t reserved_44;
diff --git a/drivers/gpu/drm/amd/include/vega20_ip_offset.h b/drivers/gpu/drm/amd/include/vega20_ip_offset.h
new file mode 100644
index 000000000000..2a2a9cc8bedb
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/vega20_ip_offset.h
@@ -0,0 +1,1051 @@
1/*
2 * Copyright (C) 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21#ifndef _vega20_ip_offset_HEADER
22#define _vega20_ip_offset_HEADER
23
24#define MAX_INSTANCE 6
25#define MAX_SEGMENT 6
26
27
28struct IP_BASE_INSTANCE
29{
30 unsigned int segment[MAX_SEGMENT];
31};
32
33struct IP_BASE
34{
35 struct IP_BASE_INSTANCE instance[MAX_INSTANCE];
36};
37
38
39static const struct IP_BASE ATHUB_BASE ={ { { { 0x00000C20, 0, 0, 0, 0, 0 } },
40 { { 0, 0, 0, 0, 0, 0 } },
41 { { 0, 0, 0, 0, 0, 0 } },
42 { { 0, 0, 0, 0, 0, 0 } },
43 { { 0, 0, 0, 0, 0, 0 } },
44 { { 0, 0, 0, 0, 0, 0 } } } };
45static const struct IP_BASE CLK_BASE ={ { { { 0x00016C00, 0x00016E00, 0x00017000, 0x00017200, 0x0001B000, 0x0001B200 } },
46 { { 0, 0, 0, 0, 0, 0 } },
47 { { 0, 0, 0, 0, 0, 0 } },
48 { { 0, 0, 0, 0, 0, 0 } },
49 { { 0, 0, 0, 0, 0, 0 } },
50 { { 0, 0, 0, 0, 0, 0 } } } };
51static const struct IP_BASE DCE_BASE ={ { { { 0x00000012, 0x000000C0, 0x000034C0, 0, 0, 0 } },
52 { { 0, 0, 0, 0, 0, 0 } },
53 { { 0, 0, 0, 0, 0, 0 } },
54 { { 0, 0, 0, 0, 0, 0 } },
55 { { 0, 0, 0, 0, 0, 0 } },
56 { { 0, 0, 0, 0, 0, 0 } } } };
57static const struct IP_BASE DF_BASE ={ { { { 0x00007000, 0, 0, 0, 0, 0 } },
58 { { 0, 0, 0, 0, 0, 0 } },
59 { { 0, 0, 0, 0, 0, 0 } },
60 { { 0, 0, 0, 0, 0, 0 } },
61 { { 0, 0, 0, 0, 0, 0 } },
62 { { 0, 0, 0, 0, 0, 0 } } } };
63static const struct IP_BASE FUSE_BASE ={ { { { 0x00017400, 0, 0, 0, 0, 0 } },
64 { { 0, 0, 0, 0, 0, 0 } },
65 { { 0, 0, 0, 0, 0, 0 } },
66 { { 0, 0, 0, 0, 0, 0 } },
67 { { 0, 0, 0, 0, 0, 0 } },
68 { { 0, 0, 0, 0, 0, 0 } } } };
69static const struct IP_BASE GC_BASE ={ { { { 0x00002000, 0x0000A000, 0, 0, 0, 0 } },
70 { { 0, 0, 0, 0, 0, 0 } },
71 { { 0, 0, 0, 0, 0, 0 } },
72 { { 0, 0, 0, 0, 0, 0 } },
73 { { 0, 0, 0, 0, 0, 0 } },
74 { { 0, 0, 0, 0, 0, 0 } } } };
75static const struct IP_BASE HDP_BASE ={ { { { 0x00000F20, 0, 0, 0, 0, 0 } },
76 { { 0, 0, 0, 0, 0, 0 } },
77 { { 0, 0, 0, 0, 0, 0 } },
78 { { 0, 0, 0, 0, 0, 0 } },
79 { { 0, 0, 0, 0, 0, 0 } },
80 { { 0, 0, 0, 0, 0, 0 } } } };
81static const struct IP_BASE MMHUB_BASE ={ { { { 0x0001A000, 0, 0, 0, 0, 0 } },
82 { { 0, 0, 0, 0, 0, 0 } },
83 { { 0, 0, 0, 0, 0, 0 } },
84 { { 0, 0, 0, 0, 0, 0 } },
85 { { 0, 0, 0, 0, 0, 0 } },
86 { { 0, 0, 0, 0, 0, 0 } } } };
87static const struct IP_BASE MP0_BASE ={ { { { 0x00016000, 0, 0, 0, 0, 0 } },
88 { { 0, 0, 0, 0, 0, 0 } },
89 { { 0, 0, 0, 0, 0, 0 } },
90 { { 0, 0, 0, 0, 0, 0 } },
91 { { 0, 0, 0, 0, 0, 0 } },
92 { { 0, 0, 0, 0, 0, 0 } } } };
93static const struct IP_BASE MP1_BASE ={ { { { 0x00016000, 0, 0, 0, 0, 0 } },
94 { { 0, 0, 0, 0, 0, 0 } },
95 { { 0, 0, 0, 0, 0, 0 } },
96 { { 0, 0, 0, 0, 0, 0 } },
97 { { 0, 0, 0, 0, 0, 0 } },
98 { { 0, 0, 0, 0, 0, 0 } } } };
99static const struct IP_BASE NBIO_BASE ={ { { { 0x00000000, 0x00000014, 0x00000D20, 0x00010400, 0, 0 } },
100 { { 0, 0, 0, 0, 0, 0 } },
101 { { 0, 0, 0, 0, 0, 0 } },
102 { { 0, 0, 0, 0, 0, 0 } },
103 { { 0, 0, 0, 0, 0, 0 } },
104 { { 0, 0, 0, 0, 0, 0 } } } };
105static const struct IP_BASE OSSSYS_BASE ={ { { { 0x000010A0, 0, 0, 0, 0, 0 } },
106 { { 0, 0, 0, 0, 0, 0 } },
107 { { 0, 0, 0, 0, 0, 0 } },
108 { { 0, 0, 0, 0, 0, 0 } },
109 { { 0, 0, 0, 0, 0, 0 } },
110 { { 0, 0, 0, 0, 0, 0 } } } };
111static const struct IP_BASE SDMA0_BASE ={ { { { 0x00001260, 0, 0, 0, 0, 0 } },
112 { { 0, 0, 0, 0, 0, 0 } },
113 { { 0, 0, 0, 0, 0, 0 } },
114 { { 0, 0, 0, 0, 0, 0 } },
115 { { 0, 0, 0, 0, 0, 0 } },
116 { { 0, 0, 0, 0, 0, 0 } } } };
117static const struct IP_BASE SDMA1_BASE ={ { { { 0x00001860, 0, 0, 0, 0, 0 } },
118 { { 0, 0, 0, 0, 0, 0 } },
119 { { 0, 0, 0, 0, 0, 0 } },
120 { { 0, 0, 0, 0, 0, 0 } },
121 { { 0, 0, 0, 0, 0, 0 } },
122 { { 0, 0, 0, 0, 0, 0 } } } };
123static const struct IP_BASE SMUIO_BASE ={ { { { 0x00016800, 0x00016A00, 0, 0, 0, 0 } },
124 { { 0, 0, 0, 0, 0, 0 } },
125 { { 0, 0, 0, 0, 0, 0 } },
126 { { 0, 0, 0, 0, 0, 0 } },
127 { { 0, 0, 0, 0, 0, 0 } },
128 { { 0, 0, 0, 0, 0, 0 } } } };
129static const struct IP_BASE THM_BASE ={ { { { 0x00016600, 0, 0, 0, 0, 0 } },
130 { { 0, 0, 0, 0, 0, 0 } },
131 { { 0, 0, 0, 0, 0, 0 } },
132 { { 0, 0, 0, 0, 0, 0 } },
133 { { 0, 0, 0, 0, 0, 0 } },
134 { { 0, 0, 0, 0, 0, 0 } } } };
135static const struct IP_BASE UMC_BASE ={ { { { 0x00014000, 0, 0, 0, 0, 0 } },
136 { { 0, 0, 0, 0, 0, 0 } },
137 { { 0, 0, 0, 0, 0, 0 } },
138 { { 0, 0, 0, 0, 0, 0 } },
139 { { 0, 0, 0, 0, 0, 0 } },
140 { { 0, 0, 0, 0, 0, 0 } } } };
141static const struct IP_BASE UVD_BASE ={ { { { 0x00007800, 0x00007E00, 0, 0, 0, 0 } },
142 { { 0, 0x00009000, 0, 0, 0, 0 } },
143 { { 0, 0, 0, 0, 0, 0 } },
144 { { 0, 0, 0, 0, 0, 0 } },
145 { { 0, 0, 0, 0, 0, 0 } },
146 { { 0, 0, 0, 0, 0, 0 } } } };
147/* Adjust VCE_BASE to make vce_4_1 use vce_4_0 offset header files*/
148static const struct IP_BASE VCE_BASE ={ { { { 0x00007E00/* 0x00008800 */, 0, 0, 0, 0, 0 } },
149 { { 0, 0, 0, 0, 0, 0 } },
150 { { 0, 0, 0, 0, 0, 0 } },
151 { { 0, 0, 0, 0, 0, 0 } },
152 { { 0, 0, 0, 0, 0, 0 } },
153 { { 0, 0, 0, 0, 0, 0 } } } };
154static const struct IP_BASE XDMA_BASE ={ { { { 0x00003400, 0, 0, 0, 0, 0 } },
155 { { 0, 0, 0, 0, 0, 0 } },
156 { { 0, 0, 0, 0, 0, 0 } },
157 { { 0, 0, 0, 0, 0, 0 } },
158 { { 0, 0, 0, 0, 0, 0 } },
159 { { 0, 0, 0, 0, 0, 0 } } } };
160static const struct IP_BASE RSMU_BASE ={ { { { 0x00012000, 0, 0, 0, 0, 0 } },
161 { { 0, 0, 0, 0, 0, 0 } },
162 { { 0, 0, 0, 0, 0, 0 } },
163 { { 0, 0, 0, 0, 0, 0 } },
164 { { 0, 0, 0, 0, 0, 0 } },
165 { { 0, 0, 0, 0, 0, 0 } } } };
166
167
168#define ATHUB_BASE__INST0_SEG0 0x00000C20
169#define ATHUB_BASE__INST0_SEG1 0
170#define ATHUB_BASE__INST0_SEG2 0
171#define ATHUB_BASE__INST0_SEG3 0
172#define ATHUB_BASE__INST0_SEG4 0
173#define ATHUB_BASE__INST0_SEG5 0
174
175#define ATHUB_BASE__INST1_SEG0 0
176#define ATHUB_BASE__INST1_SEG1 0
177#define ATHUB_BASE__INST1_SEG2 0
178#define ATHUB_BASE__INST1_SEG3 0
179#define ATHUB_BASE__INST1_SEG4 0
180#define ATHUB_BASE__INST1_SEG5 0
181
182#define ATHUB_BASE__INST2_SEG0 0
183#define ATHUB_BASE__INST2_SEG1 0
184#define ATHUB_BASE__INST2_SEG2 0
185#define ATHUB_BASE__INST2_SEG3 0
186#define ATHUB_BASE__INST2_SEG4 0
187#define ATHUB_BASE__INST2_SEG5 0
188
189#define ATHUB_BASE__INST3_SEG0 0
190#define ATHUB_BASE__INST3_SEG1 0
191#define ATHUB_BASE__INST3_SEG2 0
192#define ATHUB_BASE__INST3_SEG3 0
193#define ATHUB_BASE__INST3_SEG4 0
194#define ATHUB_BASE__INST3_SEG5 0
195
196#define ATHUB_BASE__INST4_SEG0 0
197#define ATHUB_BASE__INST4_SEG1 0
198#define ATHUB_BASE__INST4_SEG2 0
199#define ATHUB_BASE__INST4_SEG3 0
200#define ATHUB_BASE__INST4_SEG4 0
201#define ATHUB_BASE__INST4_SEG5 0
202
203#define ATHUB_BASE__INST5_SEG0 0
204#define ATHUB_BASE__INST5_SEG1 0
205#define ATHUB_BASE__INST5_SEG2 0
206#define ATHUB_BASE__INST5_SEG3 0
207#define ATHUB_BASE__INST5_SEG4 0
208#define ATHUB_BASE__INST5_SEG5 0
209
210#define CLK_BASE__INST0_SEG0 0x00016C00
211#define CLK_BASE__INST0_SEG1 0x00016E00
212#define CLK_BASE__INST0_SEG2 0x00017000
213#define CLK_BASE__INST0_SEG3 0x00017200
214#define CLK_BASE__INST0_SEG4 0x0001B000
215#define CLK_BASE__INST0_SEG5 0x0001B200
216
217#define CLK_BASE__INST1_SEG0 0
218#define CLK_BASE__INST1_SEG1 0
219#define CLK_BASE__INST1_SEG2 0
220#define CLK_BASE__INST1_SEG3 0
221#define CLK_BASE__INST1_SEG4 0
222#define CLK_BASE__INST1_SEG5 0
223
224#define CLK_BASE__INST2_SEG0 0
225#define CLK_BASE__INST2_SEG1 0
226#define CLK_BASE__INST2_SEG2 0
227#define CLK_BASE__INST2_SEG3 0
228#define CLK_BASE__INST2_SEG4 0
229#define CLK_BASE__INST2_SEG5 0
230
231#define CLK_BASE__INST3_SEG0 0
232#define CLK_BASE__INST3_SEG1 0
233#define CLK_BASE__INST3_SEG2 0
234#define CLK_BASE__INST3_SEG3 0
235#define CLK_BASE__INST3_SEG4 0
236#define CLK_BASE__INST3_SEG5 0
237
238#define CLK_BASE__INST4_SEG0 0
239#define CLK_BASE__INST4_SEG1 0
240#define CLK_BASE__INST4_SEG2 0
241#define CLK_BASE__INST4_SEG3 0
242#define CLK_BASE__INST4_SEG4 0
243#define CLK_BASE__INST4_SEG5 0
244
245#define CLK_BASE__INST5_SEG0 0
246#define CLK_BASE__INST5_SEG1 0
247#define CLK_BASE__INST5_SEG2 0
248#define CLK_BASE__INST5_SEG3 0
249#define CLK_BASE__INST5_SEG4 0
250#define CLK_BASE__INST5_SEG5 0
251
252#define DCE_BASE__INST0_SEG0 0x00000012
253#define DCE_BASE__INST0_SEG1 0x000000C0
254#define DCE_BASE__INST0_SEG2 0x000034C0
255#define DCE_BASE__INST0_SEG3 0
256#define DCE_BASE__INST0_SEG4 0
257#define DCE_BASE__INST0_SEG5 0
258
259#define DCE_BASE__INST1_SEG0 0
260#define DCE_BASE__INST1_SEG1 0
261#define DCE_BASE__INST1_SEG2 0
262#define DCE_BASE__INST1_SEG3 0
263#define DCE_BASE__INST1_SEG4 0
264#define DCE_BASE__INST1_SEG5 0
265
266#define DCE_BASE__INST2_SEG0 0
267#define DCE_BASE__INST2_SEG1 0
268#define DCE_BASE__INST2_SEG2 0
269#define DCE_BASE__INST2_SEG3 0
270#define DCE_BASE__INST2_SEG4 0
271#define DCE_BASE__INST2_SEG5 0
272
273#define DCE_BASE__INST3_SEG0 0
274#define DCE_BASE__INST3_SEG1 0
275#define DCE_BASE__INST3_SEG2 0
276#define DCE_BASE__INST3_SEG3 0
277#define DCE_BASE__INST3_SEG4 0
278#define DCE_BASE__INST3_SEG5 0
279
280#define DCE_BASE__INST4_SEG0 0
281#define DCE_BASE__INST4_SEG1 0
282#define DCE_BASE__INST4_SEG2 0
283#define DCE_BASE__INST4_SEG3 0
284#define DCE_BASE__INST4_SEG4 0
285#define DCE_BASE__INST4_SEG5 0
286
287#define DCE_BASE__INST5_SEG0 0
288#define DCE_BASE__INST5_SEG1 0
289#define DCE_BASE__INST5_SEG2 0
290#define DCE_BASE__INST5_SEG3 0
291#define DCE_BASE__INST5_SEG4 0
292#define DCE_BASE__INST5_SEG5 0
293
294#define DF_BASE__INST0_SEG0 0x00007000
295#define DF_BASE__INST0_SEG1 0
296#define DF_BASE__INST0_SEG2 0
297#define DF_BASE__INST0_SEG3 0
298#define DF_BASE__INST0_SEG4 0
299#define DF_BASE__INST0_SEG5 0
300
301#define DF_BASE__INST1_SEG0 0
302#define DF_BASE__INST1_SEG1 0
303#define DF_BASE__INST1_SEG2 0
304#define DF_BASE__INST1_SEG3 0
305#define DF_BASE__INST1_SEG4 0
306#define DF_BASE__INST1_SEG5 0
307
308#define DF_BASE__INST2_SEG0 0
309#define DF_BASE__INST2_SEG1 0
310#define DF_BASE__INST2_SEG2 0
311#define DF_BASE__INST2_SEG3 0
312#define DF_BASE__INST2_SEG4 0
313#define DF_BASE__INST2_SEG5 0
314
315#define DF_BASE__INST3_SEG0 0
316#define DF_BASE__INST3_SEG1 0
317#define DF_BASE__INST3_SEG2 0
318#define DF_BASE__INST3_SEG3 0
319#define DF_BASE__INST3_SEG4 0
320#define DF_BASE__INST3_SEG5 0
321
322#define DF_BASE__INST4_SEG0 0
323#define DF_BASE__INST4_SEG1 0
324#define DF_BASE__INST4_SEG2 0
325#define DF_BASE__INST4_SEG3 0
326#define DF_BASE__INST4_SEG4 0
327#define DF_BASE__INST4_SEG5 0
328
329#define DF_BASE__INST5_SEG0 0
330#define DF_BASE__INST5_SEG1 0
331#define DF_BASE__INST5_SEG2 0
332#define DF_BASE__INST5_SEG3 0
333#define DF_BASE__INST5_SEG4 0
334#define DF_BASE__INST5_SEG5 0
335
336#define FUSE_BASE__INST0_SEG0 0x00017400
337#define FUSE_BASE__INST0_SEG1 0
338#define FUSE_BASE__INST0_SEG2 0
339#define FUSE_BASE__INST0_SEG3 0
340#define FUSE_BASE__INST0_SEG4 0
341#define FUSE_BASE__INST0_SEG5 0
342
343#define FUSE_BASE__INST1_SEG0 0
344#define FUSE_BASE__INST1_SEG1 0
345#define FUSE_BASE__INST1_SEG2 0
346#define FUSE_BASE__INST1_SEG3 0
347#define FUSE_BASE__INST1_SEG4 0
348#define FUSE_BASE__INST1_SEG5 0
349
350#define FUSE_BASE__INST2_SEG0 0
351#define FUSE_BASE__INST2_SEG1 0
352#define FUSE_BASE__INST2_SEG2 0
353#define FUSE_BASE__INST2_SEG3 0
354#define FUSE_BASE__INST2_SEG4 0
355#define FUSE_BASE__INST2_SEG5 0
356
357#define FUSE_BASE__INST3_SEG0 0
358#define FUSE_BASE__INST3_SEG1 0
359#define FUSE_BASE__INST3_SEG2 0
360#define FUSE_BASE__INST3_SEG3 0
361#define FUSE_BASE__INST3_SEG4 0
362#define FUSE_BASE__INST3_SEG5 0
363
364#define FUSE_BASE__INST4_SEG0 0
365#define FUSE_BASE__INST4_SEG1 0
366#define FUSE_BASE__INST4_SEG2 0
367#define FUSE_BASE__INST4_SEG3 0
368#define FUSE_BASE__INST4_SEG4 0
369#define FUSE_BASE__INST4_SEG5 0
370
371#define FUSE_BASE__INST5_SEG0 0
372#define FUSE_BASE__INST5_SEG1 0
373#define FUSE_BASE__INST5_SEG2 0
374#define FUSE_BASE__INST5_SEG3 0
375#define FUSE_BASE__INST5_SEG4 0
376#define FUSE_BASE__INST5_SEG5 0
377
378#define GC_BASE__INST0_SEG0 0x00002000
379#define GC_BASE__INST0_SEG1 0x0000A000
380#define GC_BASE__INST0_SEG2 0
381#define GC_BASE__INST0_SEG3 0
382#define GC_BASE__INST0_SEG4 0
383#define GC_BASE__INST0_SEG5 0
384
385#define GC_BASE__INST1_SEG0 0
386#define GC_BASE__INST1_SEG1 0
387#define GC_BASE__INST1_SEG2 0
388#define GC_BASE__INST1_SEG3 0
389#define GC_BASE__INST1_SEG4 0
390#define GC_BASE__INST1_SEG5 0
391
392#define GC_BASE__INST2_SEG0 0
393#define GC_BASE__INST2_SEG1 0
394#define GC_BASE__INST2_SEG2 0
395#define GC_BASE__INST2_SEG3 0
396#define GC_BASE__INST2_SEG4 0
397#define GC_BASE__INST2_SEG5 0
398
399#define GC_BASE__INST3_SEG0 0
400#define GC_BASE__INST3_SEG1 0
401#define GC_BASE__INST3_SEG2 0
402#define GC_BASE__INST3_SEG3 0
403#define GC_BASE__INST3_SEG4 0
404#define GC_BASE__INST3_SEG5 0
405
406#define GC_BASE__INST4_SEG0 0
407#define GC_BASE__INST4_SEG1 0
408#define GC_BASE__INST4_SEG2 0
409#define GC_BASE__INST4_SEG3 0
410#define GC_BASE__INST4_SEG4 0
411#define GC_BASE__INST4_SEG5 0
412
413#define GC_BASE__INST5_SEG0 0
414#define GC_BASE__INST5_SEG1 0
415#define GC_BASE__INST5_SEG2 0
416#define GC_BASE__INST5_SEG3 0
417#define GC_BASE__INST5_SEG4 0
418#define GC_BASE__INST5_SEG5 0
419
420#define HDP_BASE__INST0_SEG0 0x00000F20
421#define HDP_BASE__INST0_SEG1 0
422#define HDP_BASE__INST0_SEG2 0
423#define HDP_BASE__INST0_SEG3 0
424#define HDP_BASE__INST0_SEG4 0
425#define HDP_BASE__INST0_SEG5 0
426
427#define HDP_BASE__INST1_SEG0 0
428#define HDP_BASE__INST1_SEG1 0
429#define HDP_BASE__INST1_SEG2 0
430#define HDP_BASE__INST1_SEG3 0
431#define HDP_BASE__INST1_SEG4 0
432#define HDP_BASE__INST1_SEG5 0
433
434#define HDP_BASE__INST2_SEG0 0
435#define HDP_BASE__INST2_SEG1 0
436#define HDP_BASE__INST2_SEG2 0
437#define HDP_BASE__INST2_SEG3 0
438#define HDP_BASE__INST2_SEG4 0
439#define HDP_BASE__INST2_SEG5 0
440
441#define HDP_BASE__INST3_SEG0 0
442#define HDP_BASE__INST3_SEG1 0
443#define HDP_BASE__INST3_SEG2 0
444#define HDP_BASE__INST3_SEG3 0
445#define HDP_BASE__INST3_SEG4 0
446#define HDP_BASE__INST3_SEG5 0
447
448#define HDP_BASE__INST4_SEG0 0
449#define HDP_BASE__INST4_SEG1 0
450#define HDP_BASE__INST4_SEG2 0
451#define HDP_BASE__INST4_SEG3 0
452#define HDP_BASE__INST4_SEG4 0
453#define HDP_BASE__INST4_SEG5 0
454
455#define HDP_BASE__INST5_SEG0 0
456#define HDP_BASE__INST5_SEG1 0
457#define HDP_BASE__INST5_SEG2 0
458#define HDP_BASE__INST5_SEG3 0
459#define HDP_BASE__INST5_SEG4 0
460#define HDP_BASE__INST5_SEG5 0
461
462#define MMHUB_BASE__INST0_SEG0 0x0001A000
463#define MMHUB_BASE__INST0_SEG1 0
464#define MMHUB_BASE__INST0_SEG2 0
465#define MMHUB_BASE__INST0_SEG3 0
466#define MMHUB_BASE__INST0_SEG4 0
467#define MMHUB_BASE__INST0_SEG5 0
468
469#define MMHUB_BASE__INST1_SEG0 0
470#define MMHUB_BASE__INST1_SEG1 0
471#define MMHUB_BASE__INST1_SEG2 0
472#define MMHUB_BASE__INST1_SEG3 0
473#define MMHUB_BASE__INST1_SEG4 0
474#define MMHUB_BASE__INST1_SEG5 0
475
476#define MMHUB_BASE__INST2_SEG0 0
477#define MMHUB_BASE__INST2_SEG1 0
478#define MMHUB_BASE__INST2_SEG2 0
479#define MMHUB_BASE__INST2_SEG3 0
480#define MMHUB_BASE__INST2_SEG4 0
481#define MMHUB_BASE__INST2_SEG5 0
482
483#define MMHUB_BASE__INST3_SEG0 0
484#define MMHUB_BASE__INST3_SEG1 0
485#define MMHUB_BASE__INST3_SEG2 0
486#define MMHUB_BASE__INST3_SEG3 0
487#define MMHUB_BASE__INST3_SEG4 0
488#define MMHUB_BASE__INST3_SEG5 0
489
490#define MMHUB_BASE__INST4_SEG0 0
491#define MMHUB_BASE__INST4_SEG1 0
492#define MMHUB_BASE__INST4_SEG2 0
493#define MMHUB_BASE__INST4_SEG3 0
494#define MMHUB_BASE__INST4_SEG4 0
495#define MMHUB_BASE__INST4_SEG5 0
496
497#define MMHUB_BASE__INST5_SEG0 0
498#define MMHUB_BASE__INST5_SEG1 0
499#define MMHUB_BASE__INST5_SEG2 0
500#define MMHUB_BASE__INST5_SEG3 0
501#define MMHUB_BASE__INST5_SEG4 0
502#define MMHUB_BASE__INST5_SEG5 0
503
504#define MP0_BASE__INST0_SEG0 0x00016000
505#define MP0_BASE__INST0_SEG1 0
506#define MP0_BASE__INST0_SEG2 0
507#define MP0_BASE__INST0_SEG3 0
508#define MP0_BASE__INST0_SEG4 0
509#define MP0_BASE__INST0_SEG5 0
510
511#define MP0_BASE__INST1_SEG0 0
512#define MP0_BASE__INST1_SEG1 0
513#define MP0_BASE__INST1_SEG2 0
514#define MP0_BASE__INST1_SEG3 0
515#define MP0_BASE__INST1_SEG4 0
516#define MP0_BASE__INST1_SEG5 0
517
518#define MP0_BASE__INST2_SEG0 0
519#define MP0_BASE__INST2_SEG1 0
520#define MP0_BASE__INST2_SEG2 0
521#define MP0_BASE__INST2_SEG3 0
522#define MP0_BASE__INST2_SEG4 0
523#define MP0_BASE__INST2_SEG5 0
524
525#define MP0_BASE__INST3_SEG0 0
526#define MP0_BASE__INST3_SEG1 0
527#define MP0_BASE__INST3_SEG2 0
528#define MP0_BASE__INST3_SEG3 0
529#define MP0_BASE__INST3_SEG4 0
530#define MP0_BASE__INST3_SEG5 0
531
532#define MP0_BASE__INST4_SEG0 0
533#define MP0_BASE__INST4_SEG1 0
534#define MP0_BASE__INST4_SEG2 0
535#define MP0_BASE__INST4_SEG3 0
536#define MP0_BASE__INST4_SEG4 0
537#define MP0_BASE__INST4_SEG5 0
538
539#define MP0_BASE__INST5_SEG0 0
540#define MP0_BASE__INST5_SEG1 0
541#define MP0_BASE__INST5_SEG2 0
542#define MP0_BASE__INST5_SEG3 0
543#define MP0_BASE__INST5_SEG4 0
544#define MP0_BASE__INST5_SEG5 0
545
546#define MP1_BASE__INST0_SEG0 0x00016000
547#define MP1_BASE__INST0_SEG1 0
548#define MP1_BASE__INST0_SEG2 0
549#define MP1_BASE__INST0_SEG3 0
550#define MP1_BASE__INST0_SEG4 0
551#define MP1_BASE__INST0_SEG5 0
552
553#define MP1_BASE__INST1_SEG0 0
554#define MP1_BASE__INST1_SEG1 0
555#define MP1_BASE__INST1_SEG2 0
556#define MP1_BASE__INST1_SEG3 0
557#define MP1_BASE__INST1_SEG4 0
558#define MP1_BASE__INST1_SEG5 0
559
560#define MP1_BASE__INST2_SEG0 0
561#define MP1_BASE__INST2_SEG1 0
562#define MP1_BASE__INST2_SEG2 0
563#define MP1_BASE__INST2_SEG3 0
564#define MP1_BASE__INST2_SEG4 0
565#define MP1_BASE__INST2_SEG5 0
566
567#define MP1_BASE__INST3_SEG0 0
568#define MP1_BASE__INST3_SEG1 0
569#define MP1_BASE__INST3_SEG2 0
570#define MP1_BASE__INST3_SEG3 0
571#define MP1_BASE__INST3_SEG4 0
572#define MP1_BASE__INST3_SEG5 0
573
574#define MP1_BASE__INST4_SEG0 0
575#define MP1_BASE__INST4_SEG1 0
576#define MP1_BASE__INST4_SEG2 0
577#define MP1_BASE__INST4_SEG3 0
578#define MP1_BASE__INST4_SEG4 0
579#define MP1_BASE__INST4_SEG5 0
580
581#define MP1_BASE__INST5_SEG0 0
582#define MP1_BASE__INST5_SEG1 0
583#define MP1_BASE__INST5_SEG2 0
584#define MP1_BASE__INST5_SEG3 0
585#define MP1_BASE__INST5_SEG4 0
586#define MP1_BASE__INST5_SEG5 0
587
588#define NBIO_BASE__INST0_SEG0 0x00000000
589#define NBIO_BASE__INST0_SEG1 0x00000014
590#define NBIO_BASE__INST0_SEG2 0x00000D20
591#define NBIO_BASE__INST0_SEG3 0x00010400
592#define NBIO_BASE__INST0_SEG4 0
593#define NBIO_BASE__INST0_SEG5 0
594
595#define NBIO_BASE__INST1_SEG0 0
596#define NBIO_BASE__INST1_SEG1 0
597#define NBIO_BASE__INST1_SEG2 0
598#define NBIO_BASE__INST1_SEG3 0
599#define NBIO_BASE__INST1_SEG4 0
600#define NBIO_BASE__INST1_SEG5 0
601
602#define NBIO_BASE__INST2_SEG0 0
603#define NBIO_BASE__INST2_SEG1 0
604#define NBIO_BASE__INST2_SEG2 0
605#define NBIO_BASE__INST2_SEG3 0
606#define NBIO_BASE__INST2_SEG4 0
607#define NBIO_BASE__INST2_SEG5 0
608
609#define NBIO_BASE__INST3_SEG0 0
610#define NBIO_BASE__INST3_SEG1 0
611#define NBIO_BASE__INST3_SEG2 0
612#define NBIO_BASE__INST3_SEG3 0
613#define NBIO_BASE__INST3_SEG4 0
614#define NBIO_BASE__INST3_SEG5 0
615
616#define NBIO_BASE__INST4_SEG0 0
617#define NBIO_BASE__INST4_SEG1 0
618#define NBIO_BASE__INST4_SEG2 0
619#define NBIO_BASE__INST4_SEG3 0
620#define NBIO_BASE__INST4_SEG4 0
621#define NBIO_BASE__INST4_SEG5 0
622
623#define NBIO_BASE__INST5_SEG0 0
624#define NBIO_BASE__INST5_SEG1 0
625#define NBIO_BASE__INST5_SEG2 0
626#define NBIO_BASE__INST5_SEG3 0
627#define NBIO_BASE__INST5_SEG4 0
628#define NBIO_BASE__INST5_SEG5 0
629
630#define OSSSYS_BASE__INST0_SEG0 0x000010A0
631#define OSSSYS_BASE__INST0_SEG1 0
632#define OSSSYS_BASE__INST0_SEG2 0
633#define OSSSYS_BASE__INST0_SEG3 0
634#define OSSSYS_BASE__INST0_SEG4 0
635#define OSSSYS_BASE__INST0_SEG5 0
636
637#define OSSSYS_BASE__INST1_SEG0 0
638#define OSSSYS_BASE__INST1_SEG1 0
639#define OSSSYS_BASE__INST1_SEG2 0
640#define OSSSYS_BASE__INST1_SEG3 0
641#define OSSSYS_BASE__INST1_SEG4 0
642#define OSSSYS_BASE__INST1_SEG5 0
643
644#define OSSSYS_BASE__INST2_SEG0 0
645#define OSSSYS_BASE__INST2_SEG1 0
646#define OSSSYS_BASE__INST2_SEG2 0
647#define OSSSYS_BASE__INST2_SEG3 0
648#define OSSSYS_BASE__INST2_SEG4 0
649#define OSSSYS_BASE__INST2_SEG5 0
650
651#define OSSSYS_BASE__INST3_SEG0 0
652#define OSSSYS_BASE__INST3_SEG1 0
653#define OSSSYS_BASE__INST3_SEG2 0
654#define OSSSYS_BASE__INST3_SEG3 0
655#define OSSSYS_BASE__INST3_SEG4 0
656#define OSSSYS_BASE__INST3_SEG5 0
657
658#define OSSSYS_BASE__INST4_SEG0 0
659#define OSSSYS_BASE__INST4_SEG1 0
660#define OSSSYS_BASE__INST4_SEG2 0
661#define OSSSYS_BASE__INST4_SEG3 0
662#define OSSSYS_BASE__INST4_SEG4 0
663#define OSSSYS_BASE__INST4_SEG5 0
664
665#define OSSSYS_BASE__INST5_SEG0 0
666#define OSSSYS_BASE__INST5_SEG1 0
667#define OSSSYS_BASE__INST5_SEG2 0
668#define OSSSYS_BASE__INST5_SEG3 0
669#define OSSSYS_BASE__INST5_SEG4 0
670#define OSSSYS_BASE__INST5_SEG5 0
671
672#define SDMA0_BASE__INST0_SEG0 0x00001260
673#define SDMA0_BASE__INST0_SEG1 0
674#define SDMA0_BASE__INST0_SEG2 0
675#define SDMA0_BASE__INST0_SEG3 0
676#define SDMA0_BASE__INST0_SEG4 0
677#define SDMA0_BASE__INST0_SEG5 0
678
679#define SDMA0_BASE__INST1_SEG0 0
680#define SDMA0_BASE__INST1_SEG1 0
681#define SDMA0_BASE__INST1_SEG2 0
682#define SDMA0_BASE__INST1_SEG3 0
683#define SDMA0_BASE__INST1_SEG4 0
684#define SDMA0_BASE__INST1_SEG5 0
685
686#define SDMA0_BASE__INST2_SEG0 0
687#define SDMA0_BASE__INST2_SEG1 0
688#define SDMA0_BASE__INST2_SEG2 0
689#define SDMA0_BASE__INST2_SEG3 0
690#define SDMA0_BASE__INST2_SEG4 0
691#define SDMA0_BASE__INST2_SEG5 0
692
693#define SDMA0_BASE__INST3_SEG0 0
694#define SDMA0_BASE__INST3_SEG1 0
695#define SDMA0_BASE__INST3_SEG2 0
696#define SDMA0_BASE__INST3_SEG3 0
697#define SDMA0_BASE__INST3_SEG4 0
698#define SDMA0_BASE__INST3_SEG5 0
699
700#define SDMA0_BASE__INST4_SEG0 0
701#define SDMA0_BASE__INST4_SEG1 0
702#define SDMA0_BASE__INST4_SEG2 0
703#define SDMA0_BASE__INST4_SEG3 0
704#define SDMA0_BASE__INST4_SEG4 0
705#define SDMA0_BASE__INST4_SEG5 0
706
707#define SDMA0_BASE__INST5_SEG0 0
708#define SDMA0_BASE__INST5_SEG1 0
709#define SDMA0_BASE__INST5_SEG2 0
710#define SDMA0_BASE__INST5_SEG3 0
711#define SDMA0_BASE__INST5_SEG4 0
712#define SDMA0_BASE__INST5_SEG5 0
713
714#define SDMA1_BASE__INST0_SEG0 0x00001860
715#define SDMA1_BASE__INST0_SEG1 0
716#define SDMA1_BASE__INST0_SEG2 0
717#define SDMA1_BASE__INST0_SEG3 0
718#define SDMA1_BASE__INST0_SEG4 0
719#define SDMA1_BASE__INST0_SEG5 0
720
721#define SDMA1_BASE__INST1_SEG0 0
722#define SDMA1_BASE__INST1_SEG1 0
723#define SDMA1_BASE__INST1_SEG2 0
724#define SDMA1_BASE__INST1_SEG3 0
725#define SDMA1_BASE__INST1_SEG4 0
726#define SDMA1_BASE__INST1_SEG5 0
727
728#define SDMA1_BASE__INST2_SEG0 0
729#define SDMA1_BASE__INST2_SEG1 0
730#define SDMA1_BASE__INST2_SEG2 0
731#define SDMA1_BASE__INST2_SEG3 0
732#define SDMA1_BASE__INST2_SEG4 0
733#define SDMA1_BASE__INST2_SEG5 0
734
735#define SDMA1_BASE__INST3_SEG0 0
736#define SDMA1_BASE__INST3_SEG1 0
737#define SDMA1_BASE__INST3_SEG2 0
738#define SDMA1_BASE__INST3_SEG3 0
739#define SDMA1_BASE__INST3_SEG4 0
740#define SDMA1_BASE__INST3_SEG5 0
741
742#define SDMA1_BASE__INST4_SEG0 0
743#define SDMA1_BASE__INST4_SEG1 0
744#define SDMA1_BASE__INST4_SEG2 0
745#define SDMA1_BASE__INST4_SEG3 0
746#define SDMA1_BASE__INST4_SEG4 0
747#define SDMA1_BASE__INST4_SEG5 0
748
749#define SDMA1_BASE__INST5_SEG0 0
750#define SDMA1_BASE__INST5_SEG1 0
751#define SDMA1_BASE__INST5_SEG2 0
752#define SDMA1_BASE__INST5_SEG3 0
753#define SDMA1_BASE__INST5_SEG4 0
754#define SDMA1_BASE__INST5_SEG5 0
755
756#define SMUIO_BASE__INST0_SEG0 0x00016800
757#define SMUIO_BASE__INST0_SEG1 0x00016A00
758#define SMUIO_BASE__INST0_SEG2 0
759#define SMUIO_BASE__INST0_SEG3 0
760#define SMUIO_BASE__INST0_SEG4 0
761#define SMUIO_BASE__INST0_SEG5 0
762
763#define SMUIO_BASE__INST1_SEG0 0
764#define SMUIO_BASE__INST1_SEG1 0
765#define SMUIO_BASE__INST1_SEG2 0
766#define SMUIO_BASE__INST1_SEG3 0
767#define SMUIO_BASE__INST1_SEG4 0
768#define SMUIO_BASE__INST1_SEG5 0
769
770#define SMUIO_BASE__INST2_SEG0 0
771#define SMUIO_BASE__INST2_SEG1 0
772#define SMUIO_BASE__INST2_SEG2 0
773#define SMUIO_BASE__INST2_SEG3 0
774#define SMUIO_BASE__INST2_SEG4 0
775#define SMUIO_BASE__INST2_SEG5 0
776
777#define SMUIO_BASE__INST3_SEG0 0
778#define SMUIO_BASE__INST3_SEG1 0
779#define SMUIO_BASE__INST3_SEG2 0
780#define SMUIO_BASE__INST3_SEG3 0
781#define SMUIO_BASE__INST3_SEG4 0
782#define SMUIO_BASE__INST3_SEG5 0
783
784#define SMUIO_BASE__INST4_SEG0 0
785#define SMUIO_BASE__INST4_SEG1 0
786#define SMUIO_BASE__INST4_SEG2 0
787#define SMUIO_BASE__INST4_SEG3 0
788#define SMUIO_BASE__INST4_SEG4 0
789#define SMUIO_BASE__INST4_SEG5 0
790
791#define SMUIO_BASE__INST5_SEG0 0
792#define SMUIO_BASE__INST5_SEG1 0
793#define SMUIO_BASE__INST5_SEG2 0
794#define SMUIO_BASE__INST5_SEG3 0
795#define SMUIO_BASE__INST5_SEG4 0
796#define SMUIO_BASE__INST5_SEG5 0
797
798#define THM_BASE__INST0_SEG0 0x00016600
799#define THM_BASE__INST0_SEG1 0
800#define THM_BASE__INST0_SEG2 0
801#define THM_BASE__INST0_SEG3 0
802#define THM_BASE__INST0_SEG4 0
803#define THM_BASE__INST0_SEG5 0
804
805#define THM_BASE__INST1_SEG0 0
806#define THM_BASE__INST1_SEG1 0
807#define THM_BASE__INST1_SEG2 0
808#define THM_BASE__INST1_SEG3 0
809#define THM_BASE__INST1_SEG4 0
810#define THM_BASE__INST1_SEG5 0
811
812#define THM_BASE__INST2_SEG0 0
813#define THM_BASE__INST2_SEG1 0
814#define THM_BASE__INST2_SEG2 0
815#define THM_BASE__INST2_SEG3 0
816#define THM_BASE__INST2_SEG4 0
817#define THM_BASE__INST2_SEG5 0
818
819#define THM_BASE__INST3_SEG0 0
820#define THM_BASE__INST3_SEG1 0
821#define THM_BASE__INST3_SEG2 0
822#define THM_BASE__INST3_SEG3 0
823#define THM_BASE__INST3_SEG4 0
824#define THM_BASE__INST3_SEG5 0
825
826#define THM_BASE__INST4_SEG0 0
827#define THM_BASE__INST4_SEG1 0
828#define THM_BASE__INST4_SEG2 0
829#define THM_BASE__INST4_SEG3 0
830#define THM_BASE__INST4_SEG4 0
831#define THM_BASE__INST4_SEG5 0
832
833#define THM_BASE__INST5_SEG0 0
834#define THM_BASE__INST5_SEG1 0
835#define THM_BASE__INST5_SEG2 0
836#define THM_BASE__INST5_SEG3 0
837#define THM_BASE__INST5_SEG4 0
838#define THM_BASE__INST5_SEG5 0
839
840#define UMC_BASE__INST0_SEG0 0x00014000
841#define UMC_BASE__INST0_SEG1 0
842#define UMC_BASE__INST0_SEG2 0
843#define UMC_BASE__INST0_SEG3 0
844#define UMC_BASE__INST0_SEG4 0
845#define UMC_BASE__INST0_SEG5 0
846
847#define UMC_BASE__INST1_SEG0 0
848#define UMC_BASE__INST1_SEG1 0
849#define UMC_BASE__INST1_SEG2 0
850#define UMC_BASE__INST1_SEG3 0
851#define UMC_BASE__INST1_SEG4 0
852#define UMC_BASE__INST1_SEG5 0
853
854#define UMC_BASE__INST2_SEG0 0
855#define UMC_BASE__INST2_SEG1 0
856#define UMC_BASE__INST2_SEG2 0
857#define UMC_BASE__INST2_SEG3 0
858#define UMC_BASE__INST2_SEG4 0
859#define UMC_BASE__INST2_SEG5 0
860
861#define UMC_BASE__INST3_SEG0 0
862#define UMC_BASE__INST3_SEG1 0
863#define UMC_BASE__INST3_SEG2 0
864#define UMC_BASE__INST3_SEG3 0
865#define UMC_BASE__INST3_SEG4 0
866#define UMC_BASE__INST3_SEG5 0
867
868#define UMC_BASE__INST4_SEG0 0
869#define UMC_BASE__INST4_SEG1 0
870#define UMC_BASE__INST4_SEG2 0
871#define UMC_BASE__INST4_SEG3 0
872#define UMC_BASE__INST4_SEG4 0
873#define UMC_BASE__INST4_SEG5 0
874
875#define UMC_BASE__INST5_SEG0 0
876#define UMC_BASE__INST5_SEG1 0
877#define UMC_BASE__INST5_SEG2 0
878#define UMC_BASE__INST5_SEG3 0
879#define UMC_BASE__INST5_SEG4 0
880#define UMC_BASE__INST5_SEG5 0
881
882#define UVD_BASE__INST0_SEG0 0x00007800
883#define UVD_BASE__INST0_SEG1 0x00007E00
884#define UVD_BASE__INST0_SEG2 0
885#define UVD_BASE__INST0_SEG3 0
886#define UVD_BASE__INST0_SEG4 0
887#define UVD_BASE__INST0_SEG5 0
888
889#define UVD_BASE__INST1_SEG0 0
890#define UVD_BASE__INST1_SEG1 0x00009000
891#define UVD_BASE__INST1_SEG2 0
892#define UVD_BASE__INST1_SEG3 0
893#define UVD_BASE__INST1_SEG4 0
894#define UVD_BASE__INST1_SEG5 0
895
896#define UVD_BASE__INST2_SEG0 0
897#define UVD_BASE__INST2_SEG1 0
898#define UVD_BASE__INST2_SEG2 0
899#define UVD_BASE__INST2_SEG3 0
900#define UVD_BASE__INST2_SEG4 0
901#define UVD_BASE__INST2_SEG5 0
902
903#define UVD_BASE__INST3_SEG0 0
904#define UVD_BASE__INST3_SEG1 0
905#define UVD_BASE__INST3_SEG2 0
906#define UVD_BASE__INST3_SEG3 0
907#define UVD_BASE__INST3_SEG4 0
908#define UVD_BASE__INST3_SEG5 0
909
910#define UVD_BASE__INST4_SEG0 0
911#define UVD_BASE__INST4_SEG1 0
912#define UVD_BASE__INST4_SEG2 0
913#define UVD_BASE__INST4_SEG3 0
914#define UVD_BASE__INST4_SEG4 0
915#define UVD_BASE__INST4_SEG5 0
916
917#define UVD_BASE__INST5_SEG0 0
918#define UVD_BASE__INST5_SEG1 0
919#define UVD_BASE__INST5_SEG2 0
920#define UVD_BASE__INST5_SEG3 0
921#define UVD_BASE__INST5_SEG4 0
922#define UVD_BASE__INST5_SEG5 0
923
924#define VCE_BASE__INST0_SEG0 0x00008800
925#define VCE_BASE__INST0_SEG1 0
926#define VCE_BASE__INST0_SEG2 0
927#define VCE_BASE__INST0_SEG3 0
928#define VCE_BASE__INST0_SEG4 0
929#define VCE_BASE__INST0_SEG5 0
930
931#define VCE_BASE__INST1_SEG0 0
932#define VCE_BASE__INST1_SEG1 0
933#define VCE_BASE__INST1_SEG2 0
934#define VCE_BASE__INST1_SEG3 0
935#define VCE_BASE__INST1_SEG4 0
936#define VCE_BASE__INST1_SEG5 0
937
938#define VCE_BASE__INST2_SEG0 0
939#define VCE_BASE__INST2_SEG1 0
940#define VCE_BASE__INST2_SEG2 0
941#define VCE_BASE__INST2_SEG3 0
942#define VCE_BASE__INST2_SEG4 0
943#define VCE_BASE__INST2_SEG5 0
944
945#define VCE_BASE__INST3_SEG0 0
946#define VCE_BASE__INST3_SEG1 0
947#define VCE_BASE__INST3_SEG2 0
948#define VCE_BASE__INST3_SEG3 0
949#define VCE_BASE__INST3_SEG4 0
950#define VCE_BASE__INST3_SEG5 0
951
952#define VCE_BASE__INST4_SEG0 0
953#define VCE_BASE__INST4_SEG1 0
954#define VCE_BASE__INST4_SEG2 0
955#define VCE_BASE__INST4_SEG3 0
956#define VCE_BASE__INST4_SEG4 0
957#define VCE_BASE__INST4_SEG5 0
958
959#define VCE_BASE__INST5_SEG0 0
960#define VCE_BASE__INST5_SEG1 0
961#define VCE_BASE__INST5_SEG2 0
962#define VCE_BASE__INST5_SEG3 0
963#define VCE_BASE__INST5_SEG4 0
964#define VCE_BASE__INST5_SEG5 0
965
966#define XDMA_BASE__INST0_SEG0 0x00003400
967#define XDMA_BASE__INST0_SEG1 0
968#define XDMA_BASE__INST0_SEG2 0
969#define XDMA_BASE__INST0_SEG3 0
970#define XDMA_BASE__INST0_SEG4 0
971#define XDMA_BASE__INST0_SEG5 0
972
973#define XDMA_BASE__INST1_SEG0 0
974#define XDMA_BASE__INST1_SEG1 0
975#define XDMA_BASE__INST1_SEG2 0
976#define XDMA_BASE__INST1_SEG3 0
977#define XDMA_BASE__INST1_SEG4 0
978#define XDMA_BASE__INST1_SEG5 0
979
980#define XDMA_BASE__INST2_SEG0 0
981#define XDMA_BASE__INST2_SEG1 0
982#define XDMA_BASE__INST2_SEG2 0
983#define XDMA_BASE__INST2_SEG3 0
984#define XDMA_BASE__INST2_SEG4 0
985#define XDMA_BASE__INST2_SEG5 0
986
987#define XDMA_BASE__INST3_SEG0 0
988#define XDMA_BASE__INST3_SEG1 0
989#define XDMA_BASE__INST3_SEG2 0
990#define XDMA_BASE__INST3_SEG3 0
991#define XDMA_BASE__INST3_SEG4 0
992#define XDMA_BASE__INST3_SEG5 0
993
994#define XDMA_BASE__INST4_SEG0 0
995#define XDMA_BASE__INST4_SEG1 0
996#define XDMA_BASE__INST4_SEG2 0
997#define XDMA_BASE__INST4_SEG3 0
998#define XDMA_BASE__INST4_SEG4 0
999#define XDMA_BASE__INST4_SEG5 0
1000
1001#define XDMA_BASE__INST5_SEG0 0
1002#define XDMA_BASE__INST5_SEG1 0
1003#define XDMA_BASE__INST5_SEG2 0
1004#define XDMA_BASE__INST5_SEG3 0
1005#define XDMA_BASE__INST5_SEG4 0
1006#define XDMA_BASE__INST5_SEG5 0
1007
1008#define RSMU_BASE__INST0_SEG0 0x00012000
1009#define RSMU_BASE__INST0_SEG1 0
1010#define RSMU_BASE__INST0_SEG2 0
1011#define RSMU_BASE__INST0_SEG3 0
1012#define RSMU_BASE__INST0_SEG4 0
1013#define RSMU_BASE__INST0_SEG5 0
1014
1015#define RSMU_BASE__INST1_SEG0 0
1016#define RSMU_BASE__INST1_SEG1 0
1017#define RSMU_BASE__INST1_SEG2 0
1018#define RSMU_BASE__INST1_SEG3 0
1019#define RSMU_BASE__INST1_SEG4 0
1020#define RSMU_BASE__INST1_SEG5 0
1021
1022#define RSMU_BASE__INST2_SEG0 0
1023#define RSMU_BASE__INST2_SEG1 0
1024#define RSMU_BASE__INST2_SEG2 0
1025#define RSMU_BASE__INST2_SEG3 0
1026#define RSMU_BASE__INST2_SEG4 0
1027#define RSMU_BASE__INST2_SEG5 0
1028
1029#define RSMU_BASE__INST3_SEG0 0
1030#define RSMU_BASE__INST3_SEG1 0
1031#define RSMU_BASE__INST3_SEG2 0
1032#define RSMU_BASE__INST3_SEG3 0
1033#define RSMU_BASE__INST3_SEG4 0
1034#define RSMU_BASE__INST3_SEG5 0
1035
1036#define RSMU_BASE__INST4_SEG0 0
1037#define RSMU_BASE__INST4_SEG1 0
1038#define RSMU_BASE__INST4_SEG2 0
1039#define RSMU_BASE__INST4_SEG3 0
1040#define RSMU_BASE__INST4_SEG4 0
1041#define RSMU_BASE__INST4_SEG5 0
1042
1043#define RSMU_BASE__INST5_SEG0 0
1044#define RSMU_BASE__INST5_SEG1 0
1045#define RSMU_BASE__INST5_SEG2 0
1046#define RSMU_BASE__INST5_SEG3 0
1047#define RSMU_BASE__INST5_SEG4 0
1048#define RSMU_BASE__INST5_SEG5 0
1049
1050#endif
1051
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index 7e8ad30d98e2..b493369e6d0f 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -25,30 +25,16 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/gfp.h> 26#include <linux/gfp.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/firmware.h>
28#include "amd_shared.h" 29#include "amd_shared.h"
29#include "amd_powerplay.h" 30#include "amd_powerplay.h"
30#include "power_state.h" 31#include "power_state.h"
31#include "amdgpu.h" 32#include "amdgpu.h"
32#include "hwmgr.h" 33#include "hwmgr.h"
33 34
34#define PP_DPM_DISABLED 0xCCCC
35
36static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id,
37 enum amd_pm_state_type *user_state);
38 35
39static const struct amd_pm_funcs pp_dpm_funcs; 36static const struct amd_pm_funcs pp_dpm_funcs;
40 37
41static inline int pp_check(struct pp_hwmgr *hwmgr)
42{
43 if (hwmgr == NULL || hwmgr->smumgr_funcs == NULL)
44 return -EINVAL;
45
46 if (hwmgr->pm_en == 0 || hwmgr->hwmgr_func == NULL)
47 return PP_DPM_DISABLED;
48
49 return 0;
50}
51
52static int amd_powerplay_create(struct amdgpu_device *adev) 38static int amd_powerplay_create(struct amdgpu_device *adev)
53{ 39{
54 struct pp_hwmgr *hwmgr; 40 struct pp_hwmgr *hwmgr;
@@ -61,19 +47,21 @@ static int amd_powerplay_create(struct amdgpu_device *adev)
61 return -ENOMEM; 47 return -ENOMEM;
62 48
63 hwmgr->adev = adev; 49 hwmgr->adev = adev;
64 hwmgr->pm_en = (amdgpu_dpm != 0 && !amdgpu_sriov_vf(adev)) ? true : false; 50 hwmgr->not_vf = !amdgpu_sriov_vf(adev);
51 hwmgr->pm_en = (amdgpu_dpm && hwmgr->not_vf) ? true : false;
65 hwmgr->device = amdgpu_cgs_create_device(adev); 52 hwmgr->device = amdgpu_cgs_create_device(adev);
66 mutex_init(&hwmgr->smu_lock); 53 mutex_init(&hwmgr->smu_lock);
67 hwmgr->chip_family = adev->family; 54 hwmgr->chip_family = adev->family;
68 hwmgr->chip_id = adev->asic_type; 55 hwmgr->chip_id = adev->asic_type;
69 hwmgr->feature_mask = amdgpu_pp_feature_mask; 56 hwmgr->feature_mask = adev->powerplay.pp_feature;
57 hwmgr->display_config = &adev->pm.pm_display_cfg;
70 adev->powerplay.pp_handle = hwmgr; 58 adev->powerplay.pp_handle = hwmgr;
71 adev->powerplay.pp_funcs = &pp_dpm_funcs; 59 adev->powerplay.pp_funcs = &pp_dpm_funcs;
72 return 0; 60 return 0;
73} 61}
74 62
75 63
76static int amd_powerplay_destroy(struct amdgpu_device *adev) 64static void amd_powerplay_destroy(struct amdgpu_device *adev)
77{ 65{
78 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 66 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
79 67
@@ -82,8 +70,6 @@ static int amd_powerplay_destroy(struct amdgpu_device *adev)
82 70
83 kfree(hwmgr); 71 kfree(hwmgr);
84 hwmgr = NULL; 72 hwmgr = NULL;
85
86 return 0;
87} 73}
88 74
89static int pp_early_init(void *handle) 75static int pp_early_init(void *handle)
@@ -109,18 +95,9 @@ static int pp_sw_init(void *handle)
109 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 95 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
110 int ret = 0; 96 int ret = 0;
111 97
112 ret = pp_check(hwmgr); 98 ret = hwmgr_sw_init(hwmgr);
113
114 if (ret >= 0) {
115 if (hwmgr->smumgr_funcs->smu_init == NULL)
116 return -EINVAL;
117
118 ret = hwmgr->smumgr_funcs->smu_init(hwmgr);
119 99
120 phm_register_irq_handlers(hwmgr); 100 pr_debug("powerplay sw init %s\n", ret ? "failed" : "successfully");
121
122 pr_debug("amdgpu: powerplay sw initialized\n");
123 }
124 101
125 return ret; 102 return ret;
126} 103}
@@ -129,16 +106,14 @@ static int pp_sw_fini(void *handle)
129{ 106{
130 struct amdgpu_device *adev = handle; 107 struct amdgpu_device *adev = handle;
131 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 108 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
132 int ret = 0;
133 109
134 ret = pp_check(hwmgr); 110 hwmgr_sw_fini(hwmgr);
135 if (ret >= 0) {
136 if (hwmgr->smumgr_funcs->smu_fini != NULL)
137 hwmgr->smumgr_funcs->smu_fini(hwmgr);
138 }
139 111
140 if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) 112 if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) {
113 release_firmware(adev->pm.fw);
114 adev->pm.fw = NULL;
141 amdgpu_ucode_fini_bo(adev); 115 amdgpu_ucode_fini_bo(adev);
116 }
142 117
143 return 0; 118 return 0;
144} 119}
@@ -152,55 +127,76 @@ static int pp_hw_init(void *handle)
152 if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) 127 if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU)
153 amdgpu_ucode_init_bo(adev); 128 amdgpu_ucode_init_bo(adev);
154 129
155 ret = pp_check(hwmgr); 130 ret = hwmgr_hw_init(hwmgr);
156 131
157 if (ret >= 0) { 132 if (ret)
158 if (hwmgr->smumgr_funcs->start_smu == NULL) 133 pr_err("powerplay hw init failed\n");
159 return -EINVAL;
160 134
161 if (hwmgr->smumgr_funcs->start_smu(hwmgr)) {
162 pr_err("smc start failed\n");
163 hwmgr->smumgr_funcs->smu_fini(hwmgr);
164 return -EINVAL;
165 }
166 if (ret == PP_DPM_DISABLED)
167 goto exit;
168 ret = hwmgr_hw_init(hwmgr);
169 if (ret)
170 goto exit;
171 }
172 return ret; 135 return ret;
173exit:
174 hwmgr->pm_en = 0;
175 cgs_notify_dpm_enabled(hwmgr->device, false);
176 return 0;
177
178} 136}
179 137
180static int pp_hw_fini(void *handle) 138static int pp_hw_fini(void *handle)
181{ 139{
182 struct amdgpu_device *adev = handle; 140 struct amdgpu_device *adev = handle;
183 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 141 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
184 int ret = 0;
185 142
186 ret = pp_check(hwmgr); 143 hwmgr_hw_fini(hwmgr);
187 if (ret == 0)
188 hwmgr_hw_fini(hwmgr);
189 144
190 return 0; 145 return 0;
191} 146}
192 147
148static void pp_reserve_vram_for_smu(struct amdgpu_device *adev)
149{
150 int r = -EINVAL;
151 void *cpu_ptr = NULL;
152 uint64_t gpu_addr;
153 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
154
155 if (amdgpu_bo_create_kernel(adev, adev->pm.smu_prv_buffer_size,
156 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
157 &adev->pm.smu_prv_buffer,
158 &gpu_addr,
159 &cpu_ptr)) {
160 DRM_ERROR("amdgpu: failed to create smu prv buffer\n");
161 return;
162 }
163
164 if (hwmgr->hwmgr_func->notify_cac_buffer_info)
165 r = hwmgr->hwmgr_func->notify_cac_buffer_info(hwmgr,
166 lower_32_bits((unsigned long)cpu_ptr),
167 upper_32_bits((unsigned long)cpu_ptr),
168 lower_32_bits(gpu_addr),
169 upper_32_bits(gpu_addr),
170 adev->pm.smu_prv_buffer_size);
171
172 if (r) {
173 amdgpu_bo_free_kernel(&adev->pm.smu_prv_buffer, NULL, NULL);
174 adev->pm.smu_prv_buffer = NULL;
175 DRM_ERROR("amdgpu: failed to notify SMU buffer address\n");
176 }
177}
178
193static int pp_late_init(void *handle) 179static int pp_late_init(void *handle)
194{ 180{
195 struct amdgpu_device *adev = handle; 181 struct amdgpu_device *adev = handle;
196 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 182 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
197 int ret = 0; 183 int ret;
198
199 ret = pp_check(hwmgr);
200 184
201 if (ret == 0) 185 if (hwmgr && hwmgr->pm_en) {
202 pp_dpm_dispatch_tasks(hwmgr, 186 mutex_lock(&hwmgr->smu_lock);
187 hwmgr_handle_task(hwmgr,
203 AMD_PP_TASK_COMPLETE_INIT, NULL); 188 AMD_PP_TASK_COMPLETE_INIT, NULL);
189 mutex_unlock(&hwmgr->smu_lock);
190 }
191 if (adev->pm.smu_prv_buffer_size != 0)
192 pp_reserve_vram_for_smu(adev);
193
194 if (hwmgr->hwmgr_func->gfx_off_control &&
195 (hwmgr->feature_mask & PP_GFXOFF_MASK)) {
196 ret = hwmgr->hwmgr_func->gfx_off_control(hwmgr, true);
197 if (ret)
198 pr_err("gfx off enabling failed!\n");
199 }
204 200
205 return 0; 201 return 0;
206} 202}
@@ -209,6 +205,8 @@ static void pp_late_fini(void *handle)
209{ 205{
210 struct amdgpu_device *adev = handle; 206 struct amdgpu_device *adev = handle;
211 207
208 if (adev->pm.smu_prv_buffer)
209 amdgpu_bo_free_kernel(&adev->pm.smu_prv_buffer, NULL, NULL);
212 amd_powerplay_destroy(adev); 210 amd_powerplay_destroy(adev);
213} 211}
214 212
@@ -233,12 +231,18 @@ static int pp_set_powergating_state(void *handle,
233{ 231{
234 struct amdgpu_device *adev = handle; 232 struct amdgpu_device *adev = handle;
235 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 233 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
236 int ret = 0; 234 int ret;
237 235
238 ret = pp_check(hwmgr); 236 if (!hwmgr || !hwmgr->pm_en)
237 return 0;
239 238
240 if (ret) 239 if (hwmgr->hwmgr_func->gfx_off_control) {
241 return ret; 240 /* Enable/disable GFX off through SMU */
241 ret = hwmgr->hwmgr_func->gfx_off_control(hwmgr,
242 state == AMD_PG_STATE_GATE);
243 if (ret)
244 pr_err("gfx off control failed!\n");
245 }
242 246
243 if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) { 247 if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) {
244 pr_info("%s was not implemented.\n", __func__); 248 pr_info("%s was not implemented.\n", __func__);
@@ -254,38 +258,16 @@ static int pp_suspend(void *handle)
254{ 258{
255 struct amdgpu_device *adev = handle; 259 struct amdgpu_device *adev = handle;
256 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 260 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
257 int ret = 0;
258 261
259 ret = pp_check(hwmgr); 262 return hwmgr_suspend(hwmgr);
260 if (ret == 0)
261 hwmgr_hw_suspend(hwmgr);
262 return 0;
263} 263}
264 264
265static int pp_resume(void *handle) 265static int pp_resume(void *handle)
266{ 266{
267 struct amdgpu_device *adev = handle; 267 struct amdgpu_device *adev = handle;
268 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 268 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
269 int ret;
270
271 ret = pp_check(hwmgr);
272
273 if (ret < 0)
274 return ret;
275
276 if (hwmgr->smumgr_funcs->start_smu == NULL)
277 return -EINVAL;
278
279 if (hwmgr->smumgr_funcs->start_smu(hwmgr)) {
280 pr_err("smc start failed\n");
281 hwmgr->smumgr_funcs->smu_fini(hwmgr);
282 return -EINVAL;
283 }
284
285 if (ret == PP_DPM_DISABLED)
286 return 0;
287 269
288 return hwmgr_hw_resume(hwmgr); 270 return hwmgr_resume(hwmgr);
289} 271}
290 272
291static int pp_set_clockgating_state(void *handle, 273static int pp_set_clockgating_state(void *handle,
@@ -334,12 +316,9 @@ static int pp_dpm_fw_loading_complete(void *handle)
334static int pp_set_clockgating_by_smu(void *handle, uint32_t msg_id) 316static int pp_set_clockgating_by_smu(void *handle, uint32_t msg_id)
335{ 317{
336 struct pp_hwmgr *hwmgr = handle; 318 struct pp_hwmgr *hwmgr = handle;
337 int ret = 0;
338
339 ret = pp_check(hwmgr);
340 319
341 if (ret) 320 if (!hwmgr || !hwmgr->pm_en)
342 return ret; 321 return -EINVAL;
343 322
344 if (hwmgr->hwmgr_func->update_clock_gatings == NULL) { 323 if (hwmgr->hwmgr_func->update_clock_gatings == NULL) {
345 pr_info("%s was not implemented.\n", __func__); 324 pr_info("%s was not implemented.\n", __func__);
@@ -362,10 +341,10 @@ static void pp_dpm_en_umd_pstate(struct pp_hwmgr *hwmgr,
362 if (*level & profile_mode_mask) { 341 if (*level & profile_mode_mask) {
363 hwmgr->saved_dpm_level = hwmgr->dpm_level; 342 hwmgr->saved_dpm_level = hwmgr->dpm_level;
364 hwmgr->en_umd_pstate = true; 343 hwmgr->en_umd_pstate = true;
365 cgs_set_clockgating_state(hwmgr->device, 344 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
366 AMD_IP_BLOCK_TYPE_GFX, 345 AMD_IP_BLOCK_TYPE_GFX,
367 AMD_CG_STATE_UNGATE); 346 AMD_CG_STATE_UNGATE);
368 cgs_set_powergating_state(hwmgr->device, 347 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
369 AMD_IP_BLOCK_TYPE_GFX, 348 AMD_IP_BLOCK_TYPE_GFX,
370 AMD_PG_STATE_UNGATE); 349 AMD_PG_STATE_UNGATE);
371 } 350 }
@@ -375,10 +354,10 @@ static void pp_dpm_en_umd_pstate(struct pp_hwmgr *hwmgr,
375 if (*level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT) 354 if (*level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)
376 *level = hwmgr->saved_dpm_level; 355 *level = hwmgr->saved_dpm_level;
377 hwmgr->en_umd_pstate = false; 356 hwmgr->en_umd_pstate = false;
378 cgs_set_clockgating_state(hwmgr->device, 357 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
379 AMD_IP_BLOCK_TYPE_GFX, 358 AMD_IP_BLOCK_TYPE_GFX,
380 AMD_CG_STATE_GATE); 359 AMD_CG_STATE_GATE);
381 cgs_set_powergating_state(hwmgr->device, 360 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
382 AMD_IP_BLOCK_TYPE_GFX, 361 AMD_IP_BLOCK_TYPE_GFX,
383 AMD_PG_STATE_GATE); 362 AMD_PG_STATE_GATE);
384 } 363 }
@@ -389,12 +368,9 @@ static int pp_dpm_force_performance_level(void *handle,
389 enum amd_dpm_forced_level level) 368 enum amd_dpm_forced_level level)
390{ 369{
391 struct pp_hwmgr *hwmgr = handle; 370 struct pp_hwmgr *hwmgr = handle;
392 int ret = 0;
393 371
394 ret = pp_check(hwmgr); 372 if (!hwmgr || !hwmgr->pm_en)
395 373 return -EINVAL;
396 if (ret)
397 return ret;
398 374
399 if (level == hwmgr->dpm_level) 375 if (level == hwmgr->dpm_level)
400 return 0; 376 return 0;
@@ -412,13 +388,10 @@ static enum amd_dpm_forced_level pp_dpm_get_performance_level(
412 void *handle) 388 void *handle)
413{ 389{
414 struct pp_hwmgr *hwmgr = handle; 390 struct pp_hwmgr *hwmgr = handle;
415 int ret = 0;
416 enum amd_dpm_forced_level level; 391 enum amd_dpm_forced_level level;
417 392
418 ret = pp_check(hwmgr); 393 if (!hwmgr || !hwmgr->pm_en)
419 394 return -EINVAL;
420 if (ret)
421 return ret;
422 395
423 mutex_lock(&hwmgr->smu_lock); 396 mutex_lock(&hwmgr->smu_lock);
424 level = hwmgr->dpm_level; 397 level = hwmgr->dpm_level;
@@ -429,13 +402,10 @@ static enum amd_dpm_forced_level pp_dpm_get_performance_level(
429static uint32_t pp_dpm_get_sclk(void *handle, bool low) 402static uint32_t pp_dpm_get_sclk(void *handle, bool low)
430{ 403{
431 struct pp_hwmgr *hwmgr = handle; 404 struct pp_hwmgr *hwmgr = handle;
432 int ret = 0;
433 uint32_t clk = 0; 405 uint32_t clk = 0;
434 406
435 ret = pp_check(hwmgr); 407 if (!hwmgr || !hwmgr->pm_en)
436 408 return 0;
437 if (ret)
438 return ret;
439 409
440 if (hwmgr->hwmgr_func->get_sclk == NULL) { 410 if (hwmgr->hwmgr_func->get_sclk == NULL) {
441 pr_info("%s was not implemented.\n", __func__); 411 pr_info("%s was not implemented.\n", __func__);
@@ -450,13 +420,10 @@ static uint32_t pp_dpm_get_sclk(void *handle, bool low)
450static uint32_t pp_dpm_get_mclk(void *handle, bool low) 420static uint32_t pp_dpm_get_mclk(void *handle, bool low)
451{ 421{
452 struct pp_hwmgr *hwmgr = handle; 422 struct pp_hwmgr *hwmgr = handle;
453 int ret = 0;
454 uint32_t clk = 0; 423 uint32_t clk = 0;
455 424
456 ret = pp_check(hwmgr); 425 if (!hwmgr || !hwmgr->pm_en)
457 426 return 0;
458 if (ret)
459 return ret;
460 427
461 if (hwmgr->hwmgr_func->get_mclk == NULL) { 428 if (hwmgr->hwmgr_func->get_mclk == NULL) {
462 pr_info("%s was not implemented.\n", __func__); 429 pr_info("%s was not implemented.\n", __func__);
@@ -471,11 +438,8 @@ static uint32_t pp_dpm_get_mclk(void *handle, bool low)
471static void pp_dpm_powergate_vce(void *handle, bool gate) 438static void pp_dpm_powergate_vce(void *handle, bool gate)
472{ 439{
473 struct pp_hwmgr *hwmgr = handle; 440 struct pp_hwmgr *hwmgr = handle;
474 int ret = 0;
475 441
476 ret = pp_check(hwmgr); 442 if (!hwmgr || !hwmgr->pm_en)
477
478 if (ret)
479 return; 443 return;
480 444
481 if (hwmgr->hwmgr_func->powergate_vce == NULL) { 445 if (hwmgr->hwmgr_func->powergate_vce == NULL) {
@@ -490,11 +454,8 @@ static void pp_dpm_powergate_vce(void *handle, bool gate)
490static void pp_dpm_powergate_uvd(void *handle, bool gate) 454static void pp_dpm_powergate_uvd(void *handle, bool gate)
491{ 455{
492 struct pp_hwmgr *hwmgr = handle; 456 struct pp_hwmgr *hwmgr = handle;
493 int ret = 0;
494
495 ret = pp_check(hwmgr);
496 457
497 if (ret) 458 if (!hwmgr || !hwmgr->pm_en)
498 return; 459 return;
499 460
500 if (hwmgr->hwmgr_func->powergate_uvd == NULL) { 461 if (hwmgr->hwmgr_func->powergate_uvd == NULL) {
@@ -512,10 +473,8 @@ static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id,
512 int ret = 0; 473 int ret = 0;
513 struct pp_hwmgr *hwmgr = handle; 474 struct pp_hwmgr *hwmgr = handle;
514 475
515 ret = pp_check(hwmgr); 476 if (!hwmgr || !hwmgr->pm_en)
516 477 return -EINVAL;
517 if (ret)
518 return ret;
519 478
520 mutex_lock(&hwmgr->smu_lock); 479 mutex_lock(&hwmgr->smu_lock);
521 ret = hwmgr_handle_task(hwmgr, task_id, user_state); 480 ret = hwmgr_handle_task(hwmgr, task_id, user_state);
@@ -528,15 +487,9 @@ static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle)
528{ 487{
529 struct pp_hwmgr *hwmgr = handle; 488 struct pp_hwmgr *hwmgr = handle;
530 struct pp_power_state *state; 489 struct pp_power_state *state;
531 int ret = 0;
532 enum amd_pm_state_type pm_type; 490 enum amd_pm_state_type pm_type;
533 491
534 ret = pp_check(hwmgr); 492 if (!hwmgr || !hwmgr->pm_en || !hwmgr->current_ps)
535
536 if (ret)
537 return ret;
538
539 if (hwmgr->current_ps == NULL)
540 return -EINVAL; 493 return -EINVAL;
541 494
542 mutex_lock(&hwmgr->smu_lock); 495 mutex_lock(&hwmgr->smu_lock);
@@ -568,11 +521,8 @@ static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle)
568static void pp_dpm_set_fan_control_mode(void *handle, uint32_t mode) 521static void pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
569{ 522{
570 struct pp_hwmgr *hwmgr = handle; 523 struct pp_hwmgr *hwmgr = handle;
571 int ret = 0;
572
573 ret = pp_check(hwmgr);
574 524
575 if (ret) 525 if (!hwmgr || !hwmgr->pm_en)
576 return; 526 return;
577 527
578 if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) { 528 if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) {
@@ -587,13 +537,10 @@ static void pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
587static uint32_t pp_dpm_get_fan_control_mode(void *handle) 537static uint32_t pp_dpm_get_fan_control_mode(void *handle)
588{ 538{
589 struct pp_hwmgr *hwmgr = handle; 539 struct pp_hwmgr *hwmgr = handle;
590 int ret = 0;
591 uint32_t mode = 0; 540 uint32_t mode = 0;
592 541
593 ret = pp_check(hwmgr); 542 if (!hwmgr || !hwmgr->pm_en)
594 543 return 0;
595 if (ret)
596 return ret;
597 544
598 if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) { 545 if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) {
599 pr_info("%s was not implemented.\n", __func__); 546 pr_info("%s was not implemented.\n", __func__);
@@ -610,10 +557,8 @@ static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent)
610 struct pp_hwmgr *hwmgr = handle; 557 struct pp_hwmgr *hwmgr = handle;
611 int ret = 0; 558 int ret = 0;
612 559
613 ret = pp_check(hwmgr); 560 if (!hwmgr || !hwmgr->pm_en)
614 561 return -EINVAL;
615 if (ret)
616 return ret;
617 562
618 if (hwmgr->hwmgr_func->set_fan_speed_percent == NULL) { 563 if (hwmgr->hwmgr_func->set_fan_speed_percent == NULL) {
619 pr_info("%s was not implemented.\n", __func__); 564 pr_info("%s was not implemented.\n", __func__);
@@ -630,10 +575,8 @@ static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed)
630 struct pp_hwmgr *hwmgr = handle; 575 struct pp_hwmgr *hwmgr = handle;
631 int ret = 0; 576 int ret = 0;
632 577
633 ret = pp_check(hwmgr); 578 if (!hwmgr || !hwmgr->pm_en)
634 579 return -EINVAL;
635 if (ret)
636 return ret;
637 580
638 if (hwmgr->hwmgr_func->get_fan_speed_percent == NULL) { 581 if (hwmgr->hwmgr_func->get_fan_speed_percent == NULL) {
639 pr_info("%s was not implemented.\n", __func__); 582 pr_info("%s was not implemented.\n", __func__);
@@ -651,10 +594,8 @@ static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm)
651 struct pp_hwmgr *hwmgr = handle; 594 struct pp_hwmgr *hwmgr = handle;
652 int ret = 0; 595 int ret = 0;
653 596
654 ret = pp_check(hwmgr); 597 if (!hwmgr || !hwmgr->pm_en)
655 598 return -EINVAL;
656 if (ret)
657 return ret;
658 599
659 if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL) 600 if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL)
660 return -EINVAL; 601 return -EINVAL;
@@ -670,16 +611,10 @@ static int pp_dpm_get_pp_num_states(void *handle,
670{ 611{
671 struct pp_hwmgr *hwmgr = handle; 612 struct pp_hwmgr *hwmgr = handle;
672 int i; 613 int i;
673 int ret = 0;
674 614
675 memset(data, 0, sizeof(*data)); 615 memset(data, 0, sizeof(*data));
676 616
677 ret = pp_check(hwmgr); 617 if (!hwmgr || !hwmgr->pm_en ||!hwmgr->ps)
678
679 if (ret)
680 return ret;
681
682 if (hwmgr->ps == NULL)
683 return -EINVAL; 618 return -EINVAL;
684 619
685 mutex_lock(&hwmgr->smu_lock); 620 mutex_lock(&hwmgr->smu_lock);
@@ -713,15 +648,9 @@ static int pp_dpm_get_pp_num_states(void *handle,
713static int pp_dpm_get_pp_table(void *handle, char **table) 648static int pp_dpm_get_pp_table(void *handle, char **table)
714{ 649{
715 struct pp_hwmgr *hwmgr = handle; 650 struct pp_hwmgr *hwmgr = handle;
716 int ret = 0;
717 int size = 0; 651 int size = 0;
718 652
719 ret = pp_check(hwmgr); 653 if (!hwmgr || !hwmgr->pm_en ||!hwmgr->soft_pp_table)
720
721 if (ret)
722 return ret;
723
724 if (!hwmgr->soft_pp_table)
725 return -EINVAL; 654 return -EINVAL;
726 655
727 mutex_lock(&hwmgr->smu_lock); 656 mutex_lock(&hwmgr->smu_lock);
@@ -736,10 +665,6 @@ static int amd_powerplay_reset(void *handle)
736 struct pp_hwmgr *hwmgr = handle; 665 struct pp_hwmgr *hwmgr = handle;
737 int ret; 666 int ret;
738 667
739 ret = pp_check(hwmgr);
740 if (ret)
741 return ret;
742
743 ret = hwmgr_hw_fini(hwmgr); 668 ret = hwmgr_hw_fini(hwmgr);
744 if (ret) 669 if (ret)
745 return ret; 670 return ret;
@@ -754,40 +679,38 @@ static int amd_powerplay_reset(void *handle)
754static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) 679static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)
755{ 680{
756 struct pp_hwmgr *hwmgr = handle; 681 struct pp_hwmgr *hwmgr = handle;
757 int ret = 0; 682 int ret = -ENOMEM;
758 683
759 ret = pp_check(hwmgr); 684 if (!hwmgr || !hwmgr->pm_en)
760 685 return -EINVAL;
761 if (ret)
762 return ret;
763 686
764 mutex_lock(&hwmgr->smu_lock); 687 mutex_lock(&hwmgr->smu_lock);
765 if (!hwmgr->hardcode_pp_table) { 688 if (!hwmgr->hardcode_pp_table) {
766 hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table, 689 hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table,
767 hwmgr->soft_pp_table_size, 690 hwmgr->soft_pp_table_size,
768 GFP_KERNEL); 691 GFP_KERNEL);
769 if (!hwmgr->hardcode_pp_table) { 692 if (!hwmgr->hardcode_pp_table)
770 mutex_unlock(&hwmgr->smu_lock); 693 goto err;
771 return -ENOMEM;
772 }
773 } 694 }
774 695
775 memcpy(hwmgr->hardcode_pp_table, buf, size); 696 memcpy(hwmgr->hardcode_pp_table, buf, size);
776 697
777 hwmgr->soft_pp_table = hwmgr->hardcode_pp_table; 698 hwmgr->soft_pp_table = hwmgr->hardcode_pp_table;
778 mutex_unlock(&hwmgr->smu_lock);
779 699
780 ret = amd_powerplay_reset(handle); 700 ret = amd_powerplay_reset(handle);
781 if (ret) 701 if (ret)
782 return ret; 702 goto err;
783 703
784 if (hwmgr->hwmgr_func->avfs_control) { 704 if (hwmgr->hwmgr_func->avfs_control) {
785 ret = hwmgr->hwmgr_func->avfs_control(hwmgr, false); 705 ret = hwmgr->hwmgr_func->avfs_control(hwmgr, false);
786 if (ret) 706 if (ret)
787 return ret; 707 goto err;
788 } 708 }
789 709 mutex_unlock(&hwmgr->smu_lock);
790 return 0; 710 return 0;
711err:
712 mutex_unlock(&hwmgr->smu_lock);
713 return ret;
791} 714}
792 715
793static int pp_dpm_force_clock_level(void *handle, 716static int pp_dpm_force_clock_level(void *handle,
@@ -796,10 +719,8 @@ static int pp_dpm_force_clock_level(void *handle,
796 struct pp_hwmgr *hwmgr = handle; 719 struct pp_hwmgr *hwmgr = handle;
797 int ret = 0; 720 int ret = 0;
798 721
799 ret = pp_check(hwmgr); 722 if (!hwmgr || !hwmgr->pm_en)
800 723 return -EINVAL;
801 if (ret)
802 return ret;
803 724
804 if (hwmgr->hwmgr_func->force_clock_level == NULL) { 725 if (hwmgr->hwmgr_func->force_clock_level == NULL) {
805 pr_info("%s was not implemented.\n", __func__); 726 pr_info("%s was not implemented.\n", __func__);
@@ -820,10 +741,8 @@ static int pp_dpm_print_clock_levels(void *handle,
820 struct pp_hwmgr *hwmgr = handle; 741 struct pp_hwmgr *hwmgr = handle;
821 int ret = 0; 742 int ret = 0;
822 743
823 ret = pp_check(hwmgr); 744 if (!hwmgr || !hwmgr->pm_en)
824 745 return -EINVAL;
825 if (ret)
826 return ret;
827 746
828 if (hwmgr->hwmgr_func->print_clock_levels == NULL) { 747 if (hwmgr->hwmgr_func->print_clock_levels == NULL) {
829 pr_info("%s was not implemented.\n", __func__); 748 pr_info("%s was not implemented.\n", __func__);
@@ -840,10 +759,8 @@ static int pp_dpm_get_sclk_od(void *handle)
840 struct pp_hwmgr *hwmgr = handle; 759 struct pp_hwmgr *hwmgr = handle;
841 int ret = 0; 760 int ret = 0;
842 761
843 ret = pp_check(hwmgr); 762 if (!hwmgr || !hwmgr->pm_en)
844 763 return -EINVAL;
845 if (ret)
846 return ret;
847 764
848 if (hwmgr->hwmgr_func->get_sclk_od == NULL) { 765 if (hwmgr->hwmgr_func->get_sclk_od == NULL) {
849 pr_info("%s was not implemented.\n", __func__); 766 pr_info("%s was not implemented.\n", __func__);
@@ -860,10 +777,8 @@ static int pp_dpm_set_sclk_od(void *handle, uint32_t value)
860 struct pp_hwmgr *hwmgr = handle; 777 struct pp_hwmgr *hwmgr = handle;
861 int ret = 0; 778 int ret = 0;
862 779
863 ret = pp_check(hwmgr); 780 if (!hwmgr || !hwmgr->pm_en)
864 781 return -EINVAL;
865 if (ret)
866 return ret;
867 782
868 if (hwmgr->hwmgr_func->set_sclk_od == NULL) { 783 if (hwmgr->hwmgr_func->set_sclk_od == NULL) {
869 pr_info("%s was not implemented.\n", __func__); 784 pr_info("%s was not implemented.\n", __func__);
@@ -881,10 +796,8 @@ static int pp_dpm_get_mclk_od(void *handle)
881 struct pp_hwmgr *hwmgr = handle; 796 struct pp_hwmgr *hwmgr = handle;
882 int ret = 0; 797 int ret = 0;
883 798
884 ret = pp_check(hwmgr); 799 if (!hwmgr || !hwmgr->pm_en)
885 800 return -EINVAL;
886 if (ret)
887 return ret;
888 801
889 if (hwmgr->hwmgr_func->get_mclk_od == NULL) { 802 if (hwmgr->hwmgr_func->get_mclk_od == NULL) {
890 pr_info("%s was not implemented.\n", __func__); 803 pr_info("%s was not implemented.\n", __func__);
@@ -901,10 +814,8 @@ static int pp_dpm_set_mclk_od(void *handle, uint32_t value)
901 struct pp_hwmgr *hwmgr = handle; 814 struct pp_hwmgr *hwmgr = handle;
902 int ret = 0; 815 int ret = 0;
903 816
904 ret = pp_check(hwmgr); 817 if (!hwmgr || !hwmgr->pm_en)
905 818 return -EINVAL;
906 if (ret)
907 return ret;
908 819
909 if (hwmgr->hwmgr_func->set_mclk_od == NULL) { 820 if (hwmgr->hwmgr_func->set_mclk_od == NULL) {
910 pr_info("%s was not implemented.\n", __func__); 821 pr_info("%s was not implemented.\n", __func__);
@@ -922,11 +833,7 @@ static int pp_dpm_read_sensor(void *handle, int idx,
922 struct pp_hwmgr *hwmgr = handle; 833 struct pp_hwmgr *hwmgr = handle;
923 int ret = 0; 834 int ret = 0;
924 835
925 ret = pp_check(hwmgr); 836 if (!hwmgr || !hwmgr->pm_en || !value)
926 if (ret)
927 return ret;
928
929 if (value == NULL)
930 return -EINVAL; 837 return -EINVAL;
931 838
932 switch (idx) { 839 switch (idx) {
@@ -948,14 +855,11 @@ static struct amd_vce_state*
948pp_dpm_get_vce_clock_state(void *handle, unsigned idx) 855pp_dpm_get_vce_clock_state(void *handle, unsigned idx)
949{ 856{
950 struct pp_hwmgr *hwmgr = handle; 857 struct pp_hwmgr *hwmgr = handle;
951 int ret = 0;
952
953 ret = pp_check(hwmgr);
954 858
955 if (ret) 859 if (!hwmgr || !hwmgr->pm_en)
956 return NULL; 860 return NULL;
957 861
958 if (hwmgr && idx < hwmgr->num_vce_state_tables) 862 if (idx < hwmgr->num_vce_state_tables)
959 return &hwmgr->vce_states[idx]; 863 return &hwmgr->vce_states[idx];
960 return NULL; 864 return NULL;
961} 865}
@@ -964,7 +868,7 @@ static int pp_get_power_profile_mode(void *handle, char *buf)
964{ 868{
965 struct pp_hwmgr *hwmgr = handle; 869 struct pp_hwmgr *hwmgr = handle;
966 870
967 if (!buf || pp_check(hwmgr)) 871 if (!hwmgr || !hwmgr->pm_en || !buf)
968 return -EINVAL; 872 return -EINVAL;
969 873
970 if (hwmgr->hwmgr_func->get_power_profile_mode == NULL) { 874 if (hwmgr->hwmgr_func->get_power_profile_mode == NULL) {
@@ -980,12 +884,12 @@ static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size)
980 struct pp_hwmgr *hwmgr = handle; 884 struct pp_hwmgr *hwmgr = handle;
981 int ret = -EINVAL; 885 int ret = -EINVAL;
982 886
983 if (pp_check(hwmgr)) 887 if (!hwmgr || !hwmgr->pm_en)
984 return -EINVAL; 888 return ret;
985 889
986 if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) { 890 if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) {
987 pr_info("%s was not implemented.\n", __func__); 891 pr_info("%s was not implemented.\n", __func__);
988 return -EINVAL; 892 return ret;
989 } 893 }
990 mutex_lock(&hwmgr->smu_lock); 894 mutex_lock(&hwmgr->smu_lock);
991 if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) 895 if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL)
@@ -998,7 +902,7 @@ static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint3
998{ 902{
999 struct pp_hwmgr *hwmgr = handle; 903 struct pp_hwmgr *hwmgr = handle;
1000 904
1001 if (pp_check(hwmgr)) 905 if (!hwmgr || !hwmgr->pm_en)
1002 return -EINVAL; 906 return -EINVAL;
1003 907
1004 if (hwmgr->hwmgr_func->odn_edit_dpm_table == NULL) { 908 if (hwmgr->hwmgr_func->odn_edit_dpm_table == NULL) {
@@ -1016,7 +920,7 @@ static int pp_dpm_switch_power_profile(void *handle,
1016 long workload; 920 long workload;
1017 uint32_t index; 921 uint32_t index;
1018 922
1019 if (pp_check(hwmgr)) 923 if (!hwmgr || !hwmgr->pm_en)
1020 return -EINVAL; 924 return -EINVAL;
1021 925
1022 if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) { 926 if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) {
@@ -1048,46 +952,12 @@ static int pp_dpm_switch_power_profile(void *handle,
1048 return 0; 952 return 0;
1049} 953}
1050 954
1051static int pp_dpm_notify_smu_memory_info(void *handle,
1052 uint32_t virtual_addr_low,
1053 uint32_t virtual_addr_hi,
1054 uint32_t mc_addr_low,
1055 uint32_t mc_addr_hi,
1056 uint32_t size)
1057{
1058 struct pp_hwmgr *hwmgr = handle;
1059 int ret = 0;
1060
1061 ret = pp_check(hwmgr);
1062
1063 if (ret)
1064 return ret;
1065
1066 if (hwmgr->hwmgr_func->notify_cac_buffer_info == NULL) {
1067 pr_info("%s was not implemented.\n", __func__);
1068 return -EINVAL;
1069 }
1070
1071 mutex_lock(&hwmgr->smu_lock);
1072
1073 ret = hwmgr->hwmgr_func->notify_cac_buffer_info(hwmgr, virtual_addr_low,
1074 virtual_addr_hi, mc_addr_low, mc_addr_hi,
1075 size);
1076
1077 mutex_unlock(&hwmgr->smu_lock);
1078
1079 return ret;
1080}
1081
1082static int pp_set_power_limit(void *handle, uint32_t limit) 955static int pp_set_power_limit(void *handle, uint32_t limit)
1083{ 956{
1084 struct pp_hwmgr *hwmgr = handle; 957 struct pp_hwmgr *hwmgr = handle;
1085 int ret = 0;
1086 958
1087 ret = pp_check(hwmgr); 959 if (!hwmgr || !hwmgr->pm_en)
1088 960 return -EINVAL;
1089 if (ret)
1090 return ret;
1091 961
1092 if (hwmgr->hwmgr_func->set_power_limit == NULL) { 962 if (hwmgr->hwmgr_func->set_power_limit == NULL) {
1093 pr_info("%s was not implemented.\n", __func__); 963 pr_info("%s was not implemented.\n", __func__);
@@ -1104,20 +974,14 @@ static int pp_set_power_limit(void *handle, uint32_t limit)
1104 hwmgr->hwmgr_func->set_power_limit(hwmgr, limit); 974 hwmgr->hwmgr_func->set_power_limit(hwmgr, limit);
1105 hwmgr->power_limit = limit; 975 hwmgr->power_limit = limit;
1106 mutex_unlock(&hwmgr->smu_lock); 976 mutex_unlock(&hwmgr->smu_lock);
1107 return ret; 977 return 0;
1108} 978}
1109 979
1110static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit) 980static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
1111{ 981{
1112 struct pp_hwmgr *hwmgr = handle; 982 struct pp_hwmgr *hwmgr = handle;
1113 int ret = 0;
1114
1115 ret = pp_check(hwmgr);
1116 983
1117 if (ret) 984 if (!hwmgr || !hwmgr->pm_en ||!limit)
1118 return ret;
1119
1120 if (limit == NULL)
1121 return -EINVAL; 985 return -EINVAL;
1122 986
1123 mutex_lock(&hwmgr->smu_lock); 987 mutex_lock(&hwmgr->smu_lock);
@@ -1129,19 +993,16 @@ static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
1129 993
1130 mutex_unlock(&hwmgr->smu_lock); 994 mutex_unlock(&hwmgr->smu_lock);
1131 995
1132 return ret; 996 return 0;
1133} 997}
1134 998
1135static int pp_display_configuration_change(void *handle, 999static int pp_display_configuration_change(void *handle,
1136 const struct amd_pp_display_configuration *display_config) 1000 const struct amd_pp_display_configuration *display_config)
1137{ 1001{
1138 struct pp_hwmgr *hwmgr = handle; 1002 struct pp_hwmgr *hwmgr = handle;
1139 int ret = 0;
1140 1003
1141 ret = pp_check(hwmgr); 1004 if (!hwmgr || !hwmgr->pm_en)
1142 1005 return -EINVAL;
1143 if (ret)
1144 return ret;
1145 1006
1146 mutex_lock(&hwmgr->smu_lock); 1007 mutex_lock(&hwmgr->smu_lock);
1147 phm_store_dal_configuration_data(hwmgr, display_config); 1008 phm_store_dal_configuration_data(hwmgr, display_config);
@@ -1155,12 +1016,7 @@ static int pp_get_display_power_level(void *handle,
1155 struct pp_hwmgr *hwmgr = handle; 1016 struct pp_hwmgr *hwmgr = handle;
1156 int ret = 0; 1017 int ret = 0;
1157 1018
1158 ret = pp_check(hwmgr); 1019 if (!hwmgr || !hwmgr->pm_en ||!output)
1159
1160 if (ret)
1161 return ret;
1162
1163 if (output == NULL)
1164 return -EINVAL; 1020 return -EINVAL;
1165 1021
1166 mutex_lock(&hwmgr->smu_lock); 1022 mutex_lock(&hwmgr->smu_lock);
@@ -1177,10 +1033,8 @@ static int pp_get_current_clocks(void *handle,
1177 struct pp_hwmgr *hwmgr = handle; 1033 struct pp_hwmgr *hwmgr = handle;
1178 int ret = 0; 1034 int ret = 0;
1179 1035
1180 ret = pp_check(hwmgr); 1036 if (!hwmgr || !hwmgr->pm_en)
1181 1037 return -EINVAL;
1182 if (ret)
1183 return ret;
1184 1038
1185 mutex_lock(&hwmgr->smu_lock); 1039 mutex_lock(&hwmgr->smu_lock);
1186 1040
@@ -1225,10 +1079,8 @@ static int pp_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struc
1225 struct pp_hwmgr *hwmgr = handle; 1079 struct pp_hwmgr *hwmgr = handle;
1226 int ret = 0; 1080 int ret = 0;
1227 1081
1228 ret = pp_check(hwmgr); 1082 if (!hwmgr || !hwmgr->pm_en)
1229 1083 return -EINVAL;
1230 if (ret)
1231 return ret;
1232 1084
1233 if (clocks == NULL) 1085 if (clocks == NULL)
1234 return -EINVAL; 1086 return -EINVAL;
@@ -1246,11 +1098,7 @@ static int pp_get_clock_by_type_with_latency(void *handle,
1246 struct pp_hwmgr *hwmgr = handle; 1098 struct pp_hwmgr *hwmgr = handle;
1247 int ret = 0; 1099 int ret = 0;
1248 1100
1249 ret = pp_check(hwmgr); 1101 if (!hwmgr || !hwmgr->pm_en ||!clocks)
1250 if (ret)
1251 return ret;
1252
1253 if (!clocks)
1254 return -EINVAL; 1102 return -EINVAL;
1255 1103
1256 mutex_lock(&hwmgr->smu_lock); 1104 mutex_lock(&hwmgr->smu_lock);
@@ -1266,11 +1114,7 @@ static int pp_get_clock_by_type_with_voltage(void *handle,
1266 struct pp_hwmgr *hwmgr = handle; 1114 struct pp_hwmgr *hwmgr = handle;
1267 int ret = 0; 1115 int ret = 0;
1268 1116
1269 ret = pp_check(hwmgr); 1117 if (!hwmgr || !hwmgr->pm_en ||!clocks)
1270 if (ret)
1271 return ret;
1272
1273 if (!clocks)
1274 return -EINVAL; 1118 return -EINVAL;
1275 1119
1276 mutex_lock(&hwmgr->smu_lock); 1120 mutex_lock(&hwmgr->smu_lock);
@@ -1287,11 +1131,7 @@ static int pp_set_watermarks_for_clocks_ranges(void *handle,
1287 struct pp_hwmgr *hwmgr = handle; 1131 struct pp_hwmgr *hwmgr = handle;
1288 int ret = 0; 1132 int ret = 0;
1289 1133
1290 ret = pp_check(hwmgr); 1134 if (!hwmgr || !hwmgr->pm_en ||!wm_with_clock_ranges)
1291 if (ret)
1292 return ret;
1293
1294 if (!wm_with_clock_ranges)
1295 return -EINVAL; 1135 return -EINVAL;
1296 1136
1297 mutex_lock(&hwmgr->smu_lock); 1137 mutex_lock(&hwmgr->smu_lock);
@@ -1308,11 +1148,7 @@ static int pp_display_clock_voltage_request(void *handle,
1308 struct pp_hwmgr *hwmgr = handle; 1148 struct pp_hwmgr *hwmgr = handle;
1309 int ret = 0; 1149 int ret = 0;
1310 1150
1311 ret = pp_check(hwmgr); 1151 if (!hwmgr || !hwmgr->pm_en ||!clock)
1312 if (ret)
1313 return ret;
1314
1315 if (!clock)
1316 return -EINVAL; 1152 return -EINVAL;
1317 1153
1318 mutex_lock(&hwmgr->smu_lock); 1154 mutex_lock(&hwmgr->smu_lock);
@@ -1328,12 +1164,7 @@ static int pp_get_display_mode_validation_clocks(void *handle,
1328 struct pp_hwmgr *hwmgr = handle; 1164 struct pp_hwmgr *hwmgr = handle;
1329 int ret = 0; 1165 int ret = 0;
1330 1166
1331 ret = pp_check(hwmgr); 1167 if (!hwmgr || !hwmgr->pm_en ||!clocks)
1332
1333 if (ret)
1334 return ret;
1335
1336 if (clocks == NULL)
1337 return -EINVAL; 1168 return -EINVAL;
1338 1169
1339 mutex_lock(&hwmgr->smu_lock); 1170 mutex_lock(&hwmgr->smu_lock);
@@ -1348,12 +1179,9 @@ static int pp_get_display_mode_validation_clocks(void *handle,
1348static int pp_set_mmhub_powergating_by_smu(void *handle) 1179static int pp_set_mmhub_powergating_by_smu(void *handle)
1349{ 1180{
1350 struct pp_hwmgr *hwmgr = handle; 1181 struct pp_hwmgr *hwmgr = handle;
1351 int ret = 0;
1352 1182
1353 ret = pp_check(hwmgr); 1183 if (!hwmgr || !hwmgr->pm_en)
1354 1184 return -EINVAL;
1355 if (ret)
1356 return ret;
1357 1185
1358 if (hwmgr->hwmgr_func->set_mmhub_powergating_by_smu == NULL) { 1186 if (hwmgr->hwmgr_func->set_mmhub_powergating_by_smu == NULL) {
1359 pr_info("%s was not implemented.\n", __func__); 1187 pr_info("%s was not implemented.\n", __func__);
@@ -1390,7 +1218,6 @@ static const struct amd_pm_funcs pp_dpm_funcs = {
1390 .get_vce_clock_state = pp_dpm_get_vce_clock_state, 1218 .get_vce_clock_state = pp_dpm_get_vce_clock_state,
1391 .switch_power_profile = pp_dpm_switch_power_profile, 1219 .switch_power_profile = pp_dpm_switch_power_profile,
1392 .set_clockgating_by_smu = pp_set_clockgating_by_smu, 1220 .set_clockgating_by_smu = pp_set_clockgating_by_smu,
1393 .notify_smu_memory_info = pp_dpm_notify_smu_memory_info,
1394 .get_power_profile_mode = pp_get_power_profile_mode, 1221 .get_power_profile_mode = pp_get_power_profile_mode,
1395 .set_power_profile_mode = pp_set_power_profile_mode, 1222 .set_power_profile_mode = pp_set_power_profile_mode,
1396 .odn_edit_dpm_table = pp_odn_edit_dpm_table, 1223 .odn_edit_dpm_table = pp_odn_edit_dpm_table,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
index ae2e9339dd6b..a0bb921fac22 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
@@ -75,8 +75,7 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr,
75 75
76int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr) 76int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
77{ 77{
78 int ret = 1; 78 int ret = -EINVAL;;
79 bool enabled;
80 PHM_FUNC_CHECK(hwmgr); 79 PHM_FUNC_CHECK(hwmgr);
81 80
82 if (smum_is_dpm_running(hwmgr)) { 81 if (smum_is_dpm_running(hwmgr)) {
@@ -87,17 +86,12 @@ int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
87 if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable) 86 if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable)
88 ret = hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr); 87 ret = hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr);
89 88
90 enabled = ret == 0;
91
92 cgs_notify_dpm_enabled(hwmgr->device, enabled);
93
94 return ret; 89 return ret;
95} 90}
96 91
97int phm_disable_dynamic_state_management(struct pp_hwmgr *hwmgr) 92int phm_disable_dynamic_state_management(struct pp_hwmgr *hwmgr)
98{ 93{
99 int ret = -1; 94 int ret = -EINVAL;
100 bool enabled;
101 95
102 PHM_FUNC_CHECK(hwmgr); 96 PHM_FUNC_CHECK(hwmgr);
103 97
@@ -109,10 +103,6 @@ int phm_disable_dynamic_state_management(struct pp_hwmgr *hwmgr)
109 if (hwmgr->hwmgr_func->dynamic_state_management_disable) 103 if (hwmgr->hwmgr_func->dynamic_state_management_disable)
110 ret = hwmgr->hwmgr_func->dynamic_state_management_disable(hwmgr); 104 ret = hwmgr->hwmgr_func->dynamic_state_management_disable(hwmgr);
111 105
112 enabled = ret == 0 ? false : true;
113
114 cgs_notify_dpm_enabled(hwmgr->device, enabled);
115
116 return ret; 106 return ret;
117} 107}
118 108
@@ -142,6 +132,15 @@ int phm_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
142 return 0; 132 return 0;
143} 133}
144 134
135int phm_apply_clock_adjust_rules(struct pp_hwmgr *hwmgr)
136{
137 PHM_FUNC_CHECK(hwmgr);
138
139 if (hwmgr->hwmgr_func->apply_clocks_adjust_rules != NULL)
140 return hwmgr->hwmgr_func->apply_clocks_adjust_rules(hwmgr);
141 return 0;
142}
143
145int phm_powerdown_uvd(struct pp_hwmgr *hwmgr) 144int phm_powerdown_uvd(struct pp_hwmgr *hwmgr)
146{ 145{
147 PHM_FUNC_CHECK(hwmgr); 146 PHM_FUNC_CHECK(hwmgr);
@@ -171,6 +170,16 @@ int phm_disable_clock_power_gatings(struct pp_hwmgr *hwmgr)
171 return 0; 170 return 0;
172} 171}
173 172
173int phm_pre_display_configuration_changed(struct pp_hwmgr *hwmgr)
174{
175 PHM_FUNC_CHECK(hwmgr);
176
177 if (NULL != hwmgr->hwmgr_func->pre_display_config_changed)
178 hwmgr->hwmgr_func->pre_display_config_changed(hwmgr);
179
180 return 0;
181
182}
174 183
175int phm_display_configuration_changed(struct pp_hwmgr *hwmgr) 184int phm_display_configuration_changed(struct pp_hwmgr *hwmgr)
176{ 185{
@@ -275,13 +284,11 @@ int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr,
275 if (display_config == NULL) 284 if (display_config == NULL)
276 return -EINVAL; 285 return -EINVAL;
277 286
278 hwmgr->display_config = *display_config;
279
280 if (NULL != hwmgr->hwmgr_func->set_deep_sleep_dcefclk) 287 if (NULL != hwmgr->hwmgr_func->set_deep_sleep_dcefclk)
281 hwmgr->hwmgr_func->set_deep_sleep_dcefclk(hwmgr, hwmgr->display_config.min_dcef_deep_sleep_set_clk); 288 hwmgr->hwmgr_func->set_deep_sleep_dcefclk(hwmgr, display_config->min_dcef_deep_sleep_set_clk);
282 289
283 for (index = 0; index < hwmgr->display_config.num_path_including_non_display; index++) { 290 for (index = 0; index < display_config->num_path_including_non_display; index++) {
284 if (hwmgr->display_config.displays[index].controller_id != 0) 291 if (display_config->displays[index].controller_id != 0)
285 number_of_active_display++; 292 number_of_active_display++;
286 } 293 }
287 294
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
index 42982055b161..e63bc47dc715 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
@@ -40,6 +40,7 @@ extern const struct pp_smumgr_func iceland_smu_funcs;
40extern const struct pp_smumgr_func tonga_smu_funcs; 40extern const struct pp_smumgr_func tonga_smu_funcs;
41extern const struct pp_smumgr_func fiji_smu_funcs; 41extern const struct pp_smumgr_func fiji_smu_funcs;
42extern const struct pp_smumgr_func polaris10_smu_funcs; 42extern const struct pp_smumgr_func polaris10_smu_funcs;
43extern const struct pp_smumgr_func vegam_smu_funcs;
43extern const struct pp_smumgr_func vega10_smu_funcs; 44extern const struct pp_smumgr_func vega10_smu_funcs;
44extern const struct pp_smumgr_func vega12_smu_funcs; 45extern const struct pp_smumgr_func vega12_smu_funcs;
45extern const struct pp_smumgr_func smu10_smu_funcs; 46extern const struct pp_smumgr_func smu10_smu_funcs;
@@ -76,7 +77,7 @@ static void hwmgr_init_workload_prority(struct pp_hwmgr *hwmgr)
76 77
77int hwmgr_early_init(struct pp_hwmgr *hwmgr) 78int hwmgr_early_init(struct pp_hwmgr *hwmgr)
78{ 79{
79 if (hwmgr == NULL) 80 if (!hwmgr)
80 return -EINVAL; 81 return -EINVAL;
81 82
82 hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; 83 hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
@@ -95,7 +96,8 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr)
95 hwmgr->smumgr_funcs = &ci_smu_funcs; 96 hwmgr->smumgr_funcs = &ci_smu_funcs;
96 ci_set_asic_special_caps(hwmgr); 97 ci_set_asic_special_caps(hwmgr);
97 hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK | 98 hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |
98 PP_ENABLE_GFX_CG_THRU_SMU); 99 PP_ENABLE_GFX_CG_THRU_SMU |
100 PP_GFXOFF_MASK);
99 hwmgr->pp_table_version = PP_TABLE_V0; 101 hwmgr->pp_table_version = PP_TABLE_V0;
100 hwmgr->od_enabled = false; 102 hwmgr->od_enabled = false;
101 smu7_init_function_pointers(hwmgr); 103 smu7_init_function_pointers(hwmgr);
@@ -103,9 +105,11 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr)
103 case AMDGPU_FAMILY_CZ: 105 case AMDGPU_FAMILY_CZ:
104 hwmgr->od_enabled = false; 106 hwmgr->od_enabled = false;
105 hwmgr->smumgr_funcs = &smu8_smu_funcs; 107 hwmgr->smumgr_funcs = &smu8_smu_funcs;
108 hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
106 smu8_init_function_pointers(hwmgr); 109 smu8_init_function_pointers(hwmgr);
107 break; 110 break;
108 case AMDGPU_FAMILY_VI: 111 case AMDGPU_FAMILY_VI:
112 hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
109 switch (hwmgr->chip_id) { 113 switch (hwmgr->chip_id) {
110 case CHIP_TOPAZ: 114 case CHIP_TOPAZ:
111 hwmgr->smumgr_funcs = &iceland_smu_funcs; 115 hwmgr->smumgr_funcs = &iceland_smu_funcs;
@@ -133,14 +137,21 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr)
133 polaris_set_asic_special_caps(hwmgr); 137 polaris_set_asic_special_caps(hwmgr);
134 hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK); 138 hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
135 break; 139 break;
140 case CHIP_VEGAM:
141 hwmgr->smumgr_funcs = &vegam_smu_funcs;
142 polaris_set_asic_special_caps(hwmgr);
143 hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
144 break;
136 default: 145 default:
137 return -EINVAL; 146 return -EINVAL;
138 } 147 }
139 smu7_init_function_pointers(hwmgr); 148 smu7_init_function_pointers(hwmgr);
140 break; 149 break;
141 case AMDGPU_FAMILY_AI: 150 case AMDGPU_FAMILY_AI:
151 hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
142 switch (hwmgr->chip_id) { 152 switch (hwmgr->chip_id) {
143 case CHIP_VEGA10: 153 case CHIP_VEGA10:
154 case CHIP_VEGA20:
144 hwmgr->smumgr_funcs = &vega10_smu_funcs; 155 hwmgr->smumgr_funcs = &vega10_smu_funcs;
145 vega10_hwmgr_init(hwmgr); 156 vega10_hwmgr_init(hwmgr);
146 break; 157 break;
@@ -170,22 +181,58 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr)
170 return 0; 181 return 0;
171} 182}
172 183
184int hwmgr_sw_init(struct pp_hwmgr *hwmgr)
185{
186 if (!hwmgr|| !hwmgr->smumgr_funcs || !hwmgr->smumgr_funcs->smu_init)
187 return -EINVAL;
188
189 phm_register_irq_handlers(hwmgr);
190
191 return hwmgr->smumgr_funcs->smu_init(hwmgr);
192}
193
194
195int hwmgr_sw_fini(struct pp_hwmgr *hwmgr)
196{
197 if (hwmgr && hwmgr->smumgr_funcs && hwmgr->smumgr_funcs->smu_fini)
198 hwmgr->smumgr_funcs->smu_fini(hwmgr);
199
200 return 0;
201}
202
173int hwmgr_hw_init(struct pp_hwmgr *hwmgr) 203int hwmgr_hw_init(struct pp_hwmgr *hwmgr)
174{ 204{
175 int ret = 0; 205 int ret = 0;
176 206
177 if (hwmgr == NULL) 207 if (!hwmgr || !hwmgr->smumgr_funcs)
178 return -EINVAL; 208 return -EINVAL;
179 209
180 if (hwmgr->pptable_func == NULL || 210 if (hwmgr->smumgr_funcs->start_smu) {
181 hwmgr->pptable_func->pptable_init == NULL || 211 ret = hwmgr->smumgr_funcs->start_smu(hwmgr);
182 hwmgr->hwmgr_func->backend_init == NULL) 212 if (ret) {
183 return -EINVAL; 213 pr_err("smc start failed\n");
214 return -EINVAL;
215 }
216 }
217
218 if (!hwmgr->pm_en)
219 return 0;
220
221 if (!hwmgr->pptable_func ||
222 !hwmgr->pptable_func->pptable_init ||
223 !hwmgr->hwmgr_func->backend_init) {
224 hwmgr->pm_en = false;
225 pr_info("dpm not supported \n");
226 return 0;
227 }
184 228
185 ret = hwmgr->pptable_func->pptable_init(hwmgr); 229 ret = hwmgr->pptable_func->pptable_init(hwmgr);
186 if (ret) 230 if (ret)
187 goto err; 231 goto err;
188 232
233 ((struct amdgpu_device *)hwmgr->adev)->pm.no_fan =
234 hwmgr->thermal_controller.fanInfo.bNoFan;
235
189 ret = hwmgr->hwmgr_func->backend_init(hwmgr); 236 ret = hwmgr->hwmgr_func->backend_init(hwmgr);
190 if (ret) 237 if (ret)
191 goto err1; 238 goto err1;
@@ -206,6 +253,8 @@ int hwmgr_hw_init(struct pp_hwmgr *hwmgr)
206 if (ret) 253 if (ret)
207 goto err2; 254 goto err2;
208 255
256 ((struct amdgpu_device *)hwmgr->adev)->pm.dpm_enabled = true;
257
209 return 0; 258 return 0;
210err2: 259err2:
211 if (hwmgr->hwmgr_func->backend_fini) 260 if (hwmgr->hwmgr_func->backend_fini)
@@ -214,14 +263,13 @@ err1:
214 if (hwmgr->pptable_func->pptable_fini) 263 if (hwmgr->pptable_func->pptable_fini)
215 hwmgr->pptable_func->pptable_fini(hwmgr); 264 hwmgr->pptable_func->pptable_fini(hwmgr);
216err: 265err:
217 pr_err("amdgpu: powerplay initialization failed\n");
218 return ret; 266 return ret;
219} 267}
220 268
221int hwmgr_hw_fini(struct pp_hwmgr *hwmgr) 269int hwmgr_hw_fini(struct pp_hwmgr *hwmgr)
222{ 270{
223 if (hwmgr == NULL) 271 if (!hwmgr || !hwmgr->pm_en)
224 return -EINVAL; 272 return 0;
225 273
226 phm_stop_thermal_controller(hwmgr); 274 phm_stop_thermal_controller(hwmgr);
227 psm_set_boot_states(hwmgr); 275 psm_set_boot_states(hwmgr);
@@ -236,12 +284,12 @@ int hwmgr_hw_fini(struct pp_hwmgr *hwmgr)
236 return psm_fini_power_state_table(hwmgr); 284 return psm_fini_power_state_table(hwmgr);
237} 285}
238 286
239int hwmgr_hw_suspend(struct pp_hwmgr *hwmgr) 287int hwmgr_suspend(struct pp_hwmgr *hwmgr)
240{ 288{
241 int ret = 0; 289 int ret = 0;
242 290
243 if (hwmgr == NULL) 291 if (!hwmgr || !hwmgr->pm_en)
244 return -EINVAL; 292 return 0;
245 293
246 phm_disable_smc_firmware_ctf(hwmgr); 294 phm_disable_smc_firmware_ctf(hwmgr);
247 ret = psm_set_boot_states(hwmgr); 295 ret = psm_set_boot_states(hwmgr);
@@ -255,13 +303,23 @@ int hwmgr_hw_suspend(struct pp_hwmgr *hwmgr)
255 return ret; 303 return ret;
256} 304}
257 305
258int hwmgr_hw_resume(struct pp_hwmgr *hwmgr) 306int hwmgr_resume(struct pp_hwmgr *hwmgr)
259{ 307{
260 int ret = 0; 308 int ret = 0;
261 309
262 if (hwmgr == NULL) 310 if (!hwmgr)
263 return -EINVAL; 311 return -EINVAL;
264 312
313 if (hwmgr->smumgr_funcs && hwmgr->smumgr_funcs->start_smu) {
314 if (hwmgr->smumgr_funcs->start_smu(hwmgr)) {
315 pr_err("smc start failed\n");
316 return -EINVAL;
317 }
318 }
319
320 if (!hwmgr->pm_en)
321 return 0;
322
265 ret = phm_setup_asic(hwmgr); 323 ret = phm_setup_asic(hwmgr);
266 if (ret) 324 if (ret)
267 return ret; 325 return ret;
@@ -270,9 +328,6 @@ int hwmgr_hw_resume(struct pp_hwmgr *hwmgr)
270 if (ret) 328 if (ret)
271 return ret; 329 return ret;
272 ret = phm_start_thermal_controller(hwmgr); 330 ret = phm_start_thermal_controller(hwmgr);
273 if (ret)
274 return ret;
275
276 ret |= psm_set_performance_states(hwmgr); 331 ret |= psm_set_performance_states(hwmgr);
277 if (ret) 332 if (ret)
278 return ret; 333 return ret;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c
index 0f2851b5b368..0af13c154328 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c
@@ -46,7 +46,7 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr)
46 sizeof(struct pp_power_state); 46 sizeof(struct pp_power_state);
47 47
48 if (table_entries == 0 || size == 0) { 48 if (table_entries == 0 || size == 0) {
49 pr_warn("Please check whether power state management is suppported on this asic\n"); 49 pr_warn("Please check whether power state management is supported on this asic\n");
50 return 0; 50 return 0;
51 } 51 }
52 52
@@ -265,6 +265,15 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip,
265 if (skip) 265 if (skip)
266 return 0; 266 return 0;
267 267
268 if (!hwmgr->ps)
269 /*
270 * for vega12/vega20 which does not support power state manager
271 * DAL clock limits should also be honoured
272 */
273 phm_apply_clock_adjust_rules(hwmgr);
274
275 phm_pre_display_configuration_changed(hwmgr);
276
268 phm_display_configuration_changed(hwmgr); 277 phm_display_configuration_changed(hwmgr);
269 278
270 if (hwmgr->ps) 279 if (hwmgr->ps)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
index c6febbf0bf69..7047e29755c3 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
@@ -23,7 +23,8 @@
23#include "pp_debug.h" 23#include "pp_debug.h"
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26 26#include <linux/delay.h>
27#include "atom.h"
27#include "ppatomctrl.h" 28#include "ppatomctrl.h"
28#include "atombios.h" 29#include "atombios.h"
29#include "cgs_common.h" 30#include "cgs_common.h"
@@ -128,7 +129,6 @@ static int atomctrl_set_mc_reg_address_table(
128 return 0; 129 return 0;
129} 130}
130 131
131
132int atomctrl_initialize_mc_reg_table( 132int atomctrl_initialize_mc_reg_table(
133 struct pp_hwmgr *hwmgr, 133 struct pp_hwmgr *hwmgr,
134 uint8_t module_index, 134 uint8_t module_index,
@@ -141,7 +141,7 @@ int atomctrl_initialize_mc_reg_table(
141 u16 size; 141 u16 size;
142 142
143 vram_info = (ATOM_VRAM_INFO_HEADER_V2_1 *) 143 vram_info = (ATOM_VRAM_INFO_HEADER_V2_1 *)
144 cgs_atom_get_data_table(hwmgr->device, 144 smu_atom_get_data_table(hwmgr->adev,
145 GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev); 145 GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev);
146 146
147 if (module_index >= vram_info->ucNumOfVRAMModule) { 147 if (module_index >= vram_info->ucNumOfVRAMModule) {
@@ -174,6 +174,8 @@ int atomctrl_set_engine_dram_timings_rv770(
174 uint32_t engine_clock, 174 uint32_t engine_clock,
175 uint32_t memory_clock) 175 uint32_t memory_clock)
176{ 176{
177 struct amdgpu_device *adev = hwmgr->adev;
178
177 SET_ENGINE_CLOCK_PS_ALLOCATION engine_clock_parameters; 179 SET_ENGINE_CLOCK_PS_ALLOCATION engine_clock_parameters;
178 180
179 /* They are both in 10KHz Units. */ 181 /* They are both in 10KHz Units. */
@@ -184,9 +186,10 @@ int atomctrl_set_engine_dram_timings_rv770(
184 /* in 10 khz units.*/ 186 /* in 10 khz units.*/
185 engine_clock_parameters.sReserved.ulClock = 187 engine_clock_parameters.sReserved.ulClock =
186 cpu_to_le32(memory_clock & SET_CLOCK_FREQ_MASK); 188 cpu_to_le32(memory_clock & SET_CLOCK_FREQ_MASK);
187 return cgs_atom_exec_cmd_table(hwmgr->device, 189
190 return amdgpu_atom_execute_table(adev->mode_info.atom_context,
188 GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings), 191 GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings),
189 &engine_clock_parameters); 192 (uint32_t *)&engine_clock_parameters);
190} 193}
191 194
192/** 195/**
@@ -203,7 +206,7 @@ static ATOM_VOLTAGE_OBJECT_INFO *get_voltage_info_table(void *device)
203 union voltage_object_info *voltage_info; 206 union voltage_object_info *voltage_info;
204 207
205 voltage_info = (union voltage_object_info *) 208 voltage_info = (union voltage_object_info *)
206 cgs_atom_get_data_table(device, index, 209 smu_atom_get_data_table(device, index,
207 &size, &frev, &crev); 210 &size, &frev, &crev);
208 211
209 if (voltage_info != NULL) 212 if (voltage_info != NULL)
@@ -247,16 +250,16 @@ int atomctrl_get_memory_pll_dividers_si(
247 pp_atomctrl_memory_clock_param *mpll_param, 250 pp_atomctrl_memory_clock_param *mpll_param,
248 bool strobe_mode) 251 bool strobe_mode)
249{ 252{
253 struct amdgpu_device *adev = hwmgr->adev;
250 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 mpll_parameters; 254 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 mpll_parameters;
251 int result; 255 int result;
252 256
253 mpll_parameters.ulClock = cpu_to_le32(clock_value); 257 mpll_parameters.ulClock = cpu_to_le32(clock_value);
254 mpll_parameters.ucInputFlag = (uint8_t)((strobe_mode) ? 1 : 0); 258 mpll_parameters.ucInputFlag = (uint8_t)((strobe_mode) ? 1 : 0);
255 259
256 result = cgs_atom_exec_cmd_table 260 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
257 (hwmgr->device,
258 GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam), 261 GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam),
259 &mpll_parameters); 262 (uint32_t *)&mpll_parameters);
260 263
261 if (0 == result) { 264 if (0 == result) {
262 mpll_param->mpll_fb_divider.clk_frac = 265 mpll_param->mpll_fb_divider.clk_frac =
@@ -295,14 +298,15 @@ int atomctrl_get_memory_pll_dividers_si(
295int atomctrl_get_memory_pll_dividers_vi(struct pp_hwmgr *hwmgr, 298int atomctrl_get_memory_pll_dividers_vi(struct pp_hwmgr *hwmgr,
296 uint32_t clock_value, pp_atomctrl_memory_clock_param *mpll_param) 299 uint32_t clock_value, pp_atomctrl_memory_clock_param *mpll_param)
297{ 300{
301 struct amdgpu_device *adev = hwmgr->adev;
298 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_2 mpll_parameters; 302 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_2 mpll_parameters;
299 int result; 303 int result;
300 304
301 mpll_parameters.ulClock.ulClock = cpu_to_le32(clock_value); 305 mpll_parameters.ulClock.ulClock = cpu_to_le32(clock_value);
302 306
303 result = cgs_atom_exec_cmd_table(hwmgr->device, 307 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
304 GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam), 308 GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam),
305 &mpll_parameters); 309 (uint32_t *)&mpll_parameters);
306 310
307 if (!result) 311 if (!result)
308 mpll_param->mpll_post_divider = 312 mpll_param->mpll_post_divider =
@@ -311,19 +315,49 @@ int atomctrl_get_memory_pll_dividers_vi(struct pp_hwmgr *hwmgr,
311 return result; 315 return result;
312} 316}
313 317
318int atomctrl_get_memory_pll_dividers_ai(struct pp_hwmgr *hwmgr,
319 uint32_t clock_value,
320 pp_atomctrl_memory_clock_param_ai *mpll_param)
321{
322 struct amdgpu_device *adev = hwmgr->adev;
323 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_3 mpll_parameters = {{0}, 0, 0};
324 int result;
325
326 mpll_parameters.ulClock.ulClock = cpu_to_le32(clock_value);
327
328 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
329 GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam),
330 (uint32_t *)&mpll_parameters);
331
332 /* VEGAM's mpll takes sometime to finish computing */
333 udelay(10);
334
335 if (!result) {
336 mpll_param->ulMclk_fcw_int =
337 le16_to_cpu(mpll_parameters.usMclk_fcw_int);
338 mpll_param->ulMclk_fcw_frac =
339 le16_to_cpu(mpll_parameters.usMclk_fcw_frac);
340 mpll_param->ulClock =
341 le32_to_cpu(mpll_parameters.ulClock.ulClock);
342 mpll_param->ulPostDiv = mpll_parameters.ulClock.ucPostDiv;
343 }
344
345 return result;
346}
347
314int atomctrl_get_engine_pll_dividers_kong(struct pp_hwmgr *hwmgr, 348int atomctrl_get_engine_pll_dividers_kong(struct pp_hwmgr *hwmgr,
315 uint32_t clock_value, 349 uint32_t clock_value,
316 pp_atomctrl_clock_dividers_kong *dividers) 350 pp_atomctrl_clock_dividers_kong *dividers)
317{ 351{
352 struct amdgpu_device *adev = hwmgr->adev;
318 COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 pll_parameters; 353 COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 pll_parameters;
319 int result; 354 int result;
320 355
321 pll_parameters.ulClock = cpu_to_le32(clock_value); 356 pll_parameters.ulClock = cpu_to_le32(clock_value);
322 357
323 result = cgs_atom_exec_cmd_table 358 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
324 (hwmgr->device,
325 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL), 359 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
326 &pll_parameters); 360 (uint32_t *)&pll_parameters);
327 361
328 if (0 == result) { 362 if (0 == result) {
329 dividers->pll_post_divider = pll_parameters.ucPostDiv; 363 dividers->pll_post_divider = pll_parameters.ucPostDiv;
@@ -338,16 +372,16 @@ int atomctrl_get_engine_pll_dividers_vi(
338 uint32_t clock_value, 372 uint32_t clock_value,
339 pp_atomctrl_clock_dividers_vi *dividers) 373 pp_atomctrl_clock_dividers_vi *dividers)
340{ 374{
375 struct amdgpu_device *adev = hwmgr->adev;
341 COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 pll_patameters; 376 COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 pll_patameters;
342 int result; 377 int result;
343 378
344 pll_patameters.ulClock.ulClock = cpu_to_le32(clock_value); 379 pll_patameters.ulClock.ulClock = cpu_to_le32(clock_value);
345 pll_patameters.ulClock.ucPostDiv = COMPUTE_GPUCLK_INPUT_FLAG_SCLK; 380 pll_patameters.ulClock.ucPostDiv = COMPUTE_GPUCLK_INPUT_FLAG_SCLK;
346 381
347 result = cgs_atom_exec_cmd_table 382 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
348 (hwmgr->device,
349 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL), 383 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
350 &pll_patameters); 384 (uint32_t *)&pll_patameters);
351 385
352 if (0 == result) { 386 if (0 == result) {
353 dividers->pll_post_divider = 387 dividers->pll_post_divider =
@@ -375,16 +409,16 @@ int atomctrl_get_engine_pll_dividers_ai(struct pp_hwmgr *hwmgr,
375 uint32_t clock_value, 409 uint32_t clock_value,
376 pp_atomctrl_clock_dividers_ai *dividers) 410 pp_atomctrl_clock_dividers_ai *dividers)
377{ 411{
412 struct amdgpu_device *adev = hwmgr->adev;
378 COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_7 pll_patameters; 413 COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_7 pll_patameters;
379 int result; 414 int result;
380 415
381 pll_patameters.ulClock.ulClock = cpu_to_le32(clock_value); 416 pll_patameters.ulClock.ulClock = cpu_to_le32(clock_value);
382 pll_patameters.ulClock.ucPostDiv = COMPUTE_GPUCLK_INPUT_FLAG_SCLK; 417 pll_patameters.ulClock.ucPostDiv = COMPUTE_GPUCLK_INPUT_FLAG_SCLK;
383 418
384 result = cgs_atom_exec_cmd_table 419 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
385 (hwmgr->device,
386 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL), 420 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
387 &pll_patameters); 421 (uint32_t *)&pll_patameters);
388 422
389 if (0 == result) { 423 if (0 == result) {
390 dividers->usSclk_fcw_frac = le16_to_cpu(pll_patameters.usSclk_fcw_frac); 424 dividers->usSclk_fcw_frac = le16_to_cpu(pll_patameters.usSclk_fcw_frac);
@@ -407,6 +441,7 @@ int atomctrl_get_dfs_pll_dividers_vi(
407 uint32_t clock_value, 441 uint32_t clock_value,
408 pp_atomctrl_clock_dividers_vi *dividers) 442 pp_atomctrl_clock_dividers_vi *dividers)
409{ 443{
444 struct amdgpu_device *adev = hwmgr->adev;
410 COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 pll_patameters; 445 COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 pll_patameters;
411 int result; 446 int result;
412 447
@@ -414,10 +449,9 @@ int atomctrl_get_dfs_pll_dividers_vi(
414 pll_patameters.ulClock.ucPostDiv = 449 pll_patameters.ulClock.ucPostDiv =
415 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK; 450 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK;
416 451
417 result = cgs_atom_exec_cmd_table 452 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
418 (hwmgr->device,
419 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL), 453 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
420 &pll_patameters); 454 (uint32_t *)&pll_patameters);
421 455
422 if (0 == result) { 456 if (0 == result) {
423 dividers->pll_post_divider = 457 dividers->pll_post_divider =
@@ -452,7 +486,7 @@ uint32_t atomctrl_get_reference_clock(struct pp_hwmgr *hwmgr)
452 uint32_t clock; 486 uint32_t clock;
453 487
454 fw_info = (ATOM_FIRMWARE_INFO *) 488 fw_info = (ATOM_FIRMWARE_INFO *)
455 cgs_atom_get_data_table(hwmgr->device, 489 smu_atom_get_data_table(hwmgr->adev,
456 GetIndexIntoMasterTable(DATA, FirmwareInfo), 490 GetIndexIntoMasterTable(DATA, FirmwareInfo),
457 &size, &frev, &crev); 491 &size, &frev, &crev);
458 492
@@ -476,7 +510,7 @@ bool atomctrl_is_voltage_controlled_by_gpio_v3(
476 uint8_t voltage_mode) 510 uint8_t voltage_mode)
477{ 511{
478 ATOM_VOLTAGE_OBJECT_INFO_V3_1 *voltage_info = 512 ATOM_VOLTAGE_OBJECT_INFO_V3_1 *voltage_info =
479 (ATOM_VOLTAGE_OBJECT_INFO_V3_1 *)get_voltage_info_table(hwmgr->device); 513 (ATOM_VOLTAGE_OBJECT_INFO_V3_1 *)get_voltage_info_table(hwmgr->adev);
480 bool ret; 514 bool ret;
481 515
482 PP_ASSERT_WITH_CODE((NULL != voltage_info), 516 PP_ASSERT_WITH_CODE((NULL != voltage_info),
@@ -495,7 +529,7 @@ int atomctrl_get_voltage_table_v3(
495 pp_atomctrl_voltage_table *voltage_table) 529 pp_atomctrl_voltage_table *voltage_table)
496{ 530{
497 ATOM_VOLTAGE_OBJECT_INFO_V3_1 *voltage_info = 531 ATOM_VOLTAGE_OBJECT_INFO_V3_1 *voltage_info =
498 (ATOM_VOLTAGE_OBJECT_INFO_V3_1 *)get_voltage_info_table(hwmgr->device); 532 (ATOM_VOLTAGE_OBJECT_INFO_V3_1 *)get_voltage_info_table(hwmgr->adev);
499 const ATOM_VOLTAGE_OBJECT_V3 *voltage_object; 533 const ATOM_VOLTAGE_OBJECT_V3 *voltage_object;
500 unsigned int i; 534 unsigned int i;
501 535
@@ -572,7 +606,7 @@ static ATOM_GPIO_PIN_LUT *get_gpio_lookup_table(void *device)
572 void *table_address; 606 void *table_address;
573 607
574 table_address = (ATOM_GPIO_PIN_LUT *) 608 table_address = (ATOM_GPIO_PIN_LUT *)
575 cgs_atom_get_data_table(device, 609 smu_atom_get_data_table(device,
576 GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT), 610 GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT),
577 &size, &frev, &crev); 611 &size, &frev, &crev);
578 612
@@ -592,7 +626,7 @@ bool atomctrl_get_pp_assign_pin(
592{ 626{
593 bool bRet = false; 627 bool bRet = false;
594 ATOM_GPIO_PIN_LUT *gpio_lookup_table = 628 ATOM_GPIO_PIN_LUT *gpio_lookup_table =
595 get_gpio_lookup_table(hwmgr->device); 629 get_gpio_lookup_table(hwmgr->adev);
596 630
597 PP_ASSERT_WITH_CODE((NULL != gpio_lookup_table), 631 PP_ASSERT_WITH_CODE((NULL != gpio_lookup_table),
598 "Could not find GPIO lookup Table in BIOS.", return false); 632 "Could not find GPIO lookup Table in BIOS.", return false);
@@ -613,7 +647,7 @@ int atomctrl_calculate_voltage_evv_on_sclk(
613 bool debug) 647 bool debug)
614{ 648{
615 ATOM_ASIC_PROFILING_INFO_V3_4 *getASICProfilingInfo; 649 ATOM_ASIC_PROFILING_INFO_V3_4 *getASICProfilingInfo;
616 650 struct amdgpu_device *adev = hwmgr->adev;
617 EFUSE_LINEAR_FUNC_PARAM sRO_fuse; 651 EFUSE_LINEAR_FUNC_PARAM sRO_fuse;
618 EFUSE_LINEAR_FUNC_PARAM sCACm_fuse; 652 EFUSE_LINEAR_FUNC_PARAM sCACm_fuse;
619 EFUSE_LINEAR_FUNC_PARAM sCACb_fuse; 653 EFUSE_LINEAR_FUNC_PARAM sCACb_fuse;
@@ -640,7 +674,7 @@ int atomctrl_calculate_voltage_evv_on_sclk(
640 int result; 674 int result;
641 675
642 getASICProfilingInfo = (ATOM_ASIC_PROFILING_INFO_V3_4 *) 676 getASICProfilingInfo = (ATOM_ASIC_PROFILING_INFO_V3_4 *)
643 cgs_atom_get_data_table(hwmgr->device, 677 smu_atom_get_data_table(hwmgr->adev,
644 GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo), 678 GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo),
645 NULL, NULL, NULL); 679 NULL, NULL, NULL);
646 680
@@ -706,9 +740,9 @@ int atomctrl_calculate_voltage_evv_on_sclk(
706 740
707 sOutput_FuseValues.sEfuse = sInput_FuseValues; 741 sOutput_FuseValues.sEfuse = sInput_FuseValues;
708 742
709 result = cgs_atom_exec_cmd_table(hwmgr->device, 743 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
710 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue), 744 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
711 &sOutput_FuseValues); 745 (uint32_t *)&sOutput_FuseValues);
712 746
713 if (result) 747 if (result)
714 return result; 748 return result;
@@ -727,9 +761,9 @@ int atomctrl_calculate_voltage_evv_on_sclk(
727 761
728 sOutput_FuseValues.sEfuse = sInput_FuseValues; 762 sOutput_FuseValues.sEfuse = sInput_FuseValues;
729 763
730 result = cgs_atom_exec_cmd_table(hwmgr->device, 764 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
731 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue), 765 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
732 &sOutput_FuseValues); 766 (uint32_t *)&sOutput_FuseValues);
733 767
734 if (result) 768 if (result)
735 return result; 769 return result;
@@ -747,9 +781,9 @@ int atomctrl_calculate_voltage_evv_on_sclk(
747 sInput_FuseValues.ucBitLength = sCACb_fuse.ucEfuseLength; 781 sInput_FuseValues.ucBitLength = sCACb_fuse.ucEfuseLength;
748 sOutput_FuseValues.sEfuse = sInput_FuseValues; 782 sOutput_FuseValues.sEfuse = sInput_FuseValues;
749 783
750 result = cgs_atom_exec_cmd_table(hwmgr->device, 784 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
751 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue), 785 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
752 &sOutput_FuseValues); 786 (uint32_t *)&sOutput_FuseValues);
753 787
754 if (result) 788 if (result)
755 return result; 789 return result;
@@ -768,9 +802,9 @@ int atomctrl_calculate_voltage_evv_on_sclk(
768 802
769 sOutput_FuseValues.sEfuse = sInput_FuseValues; 803 sOutput_FuseValues.sEfuse = sInput_FuseValues;
770 804
771 result = cgs_atom_exec_cmd_table(hwmgr->device, 805 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
772 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue), 806 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
773 &sOutput_FuseValues); 807 (uint32_t *)&sOutput_FuseValues);
774 808
775 if (result) 809 if (result)
776 return result; 810 return result;
@@ -790,9 +824,9 @@ int atomctrl_calculate_voltage_evv_on_sclk(
790 824
791 sOutput_FuseValues.sEfuse = sInput_FuseValues; 825 sOutput_FuseValues.sEfuse = sInput_FuseValues;
792 826
793 result = cgs_atom_exec_cmd_table(hwmgr->device, 827 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
794 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue), 828 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
795 &sOutput_FuseValues); 829 (uint32_t *)&sOutput_FuseValues);
796 if (result) 830 if (result)
797 return result; 831 return result;
798 832
@@ -811,9 +845,9 @@ int atomctrl_calculate_voltage_evv_on_sclk(
811 sInput_FuseValues.ucBitLength = sKv_b_fuse.ucEfuseLength; 845 sInput_FuseValues.ucBitLength = sKv_b_fuse.ucEfuseLength;
812 sOutput_FuseValues.sEfuse = sInput_FuseValues; 846 sOutput_FuseValues.sEfuse = sInput_FuseValues;
813 847
814 result = cgs_atom_exec_cmd_table(hwmgr->device, 848 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
815 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue), 849 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
816 &sOutput_FuseValues); 850 (uint32_t *)&sOutput_FuseValues);
817 851
818 if (result) 852 if (result)
819 return result; 853 return result;
@@ -842,9 +876,9 @@ int atomctrl_calculate_voltage_evv_on_sclk(
842 876
843 sOutput_FuseValues.sEfuse = sInput_FuseValues; 877 sOutput_FuseValues.sEfuse = sInput_FuseValues;
844 878
845 result = cgs_atom_exec_cmd_table(hwmgr->device, 879 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
846 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue), 880 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
847 &sOutput_FuseValues); 881 (uint32_t *)&sOutput_FuseValues);
848 882
849 if (result) 883 if (result)
850 return result; 884 return result;
@@ -1053,8 +1087,9 @@ int atomctrl_get_voltage_evv_on_sclk(
1053 uint32_t sclk, uint16_t virtual_voltage_Id, 1087 uint32_t sclk, uint16_t virtual_voltage_Id,
1054 uint16_t *voltage) 1088 uint16_t *voltage)
1055{ 1089{
1056 int result; 1090 struct amdgpu_device *adev = hwmgr->adev;
1057 GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 get_voltage_info_param_space; 1091 GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 get_voltage_info_param_space;
1092 int result;
1058 1093
1059 get_voltage_info_param_space.ucVoltageType = 1094 get_voltage_info_param_space.ucVoltageType =
1060 voltage_type; 1095 voltage_type;
@@ -1065,14 +1100,12 @@ int atomctrl_get_voltage_evv_on_sclk(
1065 get_voltage_info_param_space.ulSCLKFreq = 1100 get_voltage_info_param_space.ulSCLKFreq =
1066 cpu_to_le32(sclk); 1101 cpu_to_le32(sclk);
1067 1102
1068 result = cgs_atom_exec_cmd_table(hwmgr->device, 1103 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
1069 GetIndexIntoMasterTable(COMMAND, GetVoltageInfo), 1104 GetIndexIntoMasterTable(COMMAND, GetVoltageInfo),
1070 &get_voltage_info_param_space); 1105 (uint32_t *)&get_voltage_info_param_space);
1071
1072 if (0 != result)
1073 return result;
1074 1106
1075 *voltage = le16_to_cpu(((GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 *) 1107 *voltage = result ? 0 :
1108 le16_to_cpu(((GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 *)
1076 (&get_voltage_info_param_space))->usVoltageLevel); 1109 (&get_voltage_info_param_space))->usVoltageLevel);
1077 1110
1078 return result; 1111 return result;
@@ -1088,9 +1121,10 @@ int atomctrl_get_voltage_evv(struct pp_hwmgr *hwmgr,
1088 uint16_t virtual_voltage_id, 1121 uint16_t virtual_voltage_id,
1089 uint16_t *voltage) 1122 uint16_t *voltage)
1090{ 1123{
1124 struct amdgpu_device *adev = hwmgr->adev;
1125 GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 get_voltage_info_param_space;
1091 int result; 1126 int result;
1092 int entry_id; 1127 int entry_id;
1093 GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 get_voltage_info_param_space;
1094 1128
1095 /* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */ 1129 /* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */
1096 for (entry_id = 0; entry_id < hwmgr->dyn_state.vddc_dependency_on_sclk->count; entry_id++) { 1130 for (entry_id = 0; entry_id < hwmgr->dyn_state.vddc_dependency_on_sclk->count; entry_id++) {
@@ -1111,9 +1145,9 @@ int atomctrl_get_voltage_evv(struct pp_hwmgr *hwmgr,
1111 get_voltage_info_param_space.ulSCLKFreq = 1145 get_voltage_info_param_space.ulSCLKFreq =
1112 cpu_to_le32(hwmgr->dyn_state.vddc_dependency_on_sclk->entries[entry_id].clk); 1146 cpu_to_le32(hwmgr->dyn_state.vddc_dependency_on_sclk->entries[entry_id].clk);
1113 1147
1114 result = cgs_atom_exec_cmd_table(hwmgr->device, 1148 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
1115 GetIndexIntoMasterTable(COMMAND, GetVoltageInfo), 1149 GetIndexIntoMasterTable(COMMAND, GetVoltageInfo),
1116 &get_voltage_info_param_space); 1150 (uint32_t *)&get_voltage_info_param_space);
1117 1151
1118 if (0 != result) 1152 if (0 != result)
1119 return result; 1153 return result;
@@ -1135,7 +1169,7 @@ uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr)
1135 u16 size; 1169 u16 size;
1136 1170
1137 fw_info = (ATOM_COMMON_TABLE_HEADER *) 1171 fw_info = (ATOM_COMMON_TABLE_HEADER *)
1138 cgs_atom_get_data_table(hwmgr->device, 1172 smu_atom_get_data_table(hwmgr->adev,
1139 GetIndexIntoMasterTable(DATA, FirmwareInfo), 1173 GetIndexIntoMasterTable(DATA, FirmwareInfo),
1140 &size, &frev, &crev); 1174 &size, &frev, &crev);
1141 1175
@@ -1167,7 +1201,7 @@ static ATOM_ASIC_INTERNAL_SS_INFO *asic_internal_ss_get_ss_table(void *device)
1167 u16 size; 1201 u16 size;
1168 1202
1169 table = (ATOM_ASIC_INTERNAL_SS_INFO *) 1203 table = (ATOM_ASIC_INTERNAL_SS_INFO *)
1170 cgs_atom_get_data_table(device, 1204 smu_atom_get_data_table(device,
1171 GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info), 1205 GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info),
1172 &size, &frev, &crev); 1206 &size, &frev, &crev);
1173 1207
@@ -1188,7 +1222,7 @@ static int asic_internal_ss_get_ss_asignment(struct pp_hwmgr *hwmgr,
1188 1222
1189 memset(ssEntry, 0x00, sizeof(pp_atomctrl_internal_ss_info)); 1223 memset(ssEntry, 0x00, sizeof(pp_atomctrl_internal_ss_info));
1190 1224
1191 table = asic_internal_ss_get_ss_table(hwmgr->device); 1225 table = asic_internal_ss_get_ss_table(hwmgr->adev);
1192 1226
1193 if (NULL == table) 1227 if (NULL == table)
1194 return -1; 1228 return -1;
@@ -1260,9 +1294,10 @@ int atomctrl_get_engine_clock_spread_spectrum(
1260 ASIC_INTERNAL_ENGINE_SS, engine_clock, ssInfo); 1294 ASIC_INTERNAL_ENGINE_SS, engine_clock, ssInfo);
1261} 1295}
1262 1296
1263int atomctrl_read_efuse(void *device, uint16_t start_index, 1297int atomctrl_read_efuse(struct pp_hwmgr *hwmgr, uint16_t start_index,
1264 uint16_t end_index, uint32_t mask, uint32_t *efuse) 1298 uint16_t end_index, uint32_t mask, uint32_t *efuse)
1265{ 1299{
1300 struct amdgpu_device *adev = hwmgr->adev;
1266 int result; 1301 int result;
1267 READ_EFUSE_VALUE_PARAMETER efuse_param; 1302 READ_EFUSE_VALUE_PARAMETER efuse_param;
1268 1303
@@ -1272,11 +1307,10 @@ int atomctrl_read_efuse(void *device, uint16_t start_index,
1272 efuse_param.sEfuse.ucBitLength = (uint8_t) 1307 efuse_param.sEfuse.ucBitLength = (uint8_t)
1273 ((end_index - start_index) + 1); 1308 ((end_index - start_index) + 1);
1274 1309
1275 result = cgs_atom_exec_cmd_table(device, 1310 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
1276 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue), 1311 GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
1277 &efuse_param); 1312 (uint32_t *)&efuse_param);
1278 if (!result) 1313 *efuse = result ? 0 : le32_to_cpu(efuse_param.ulEfuseValue) & mask;
1279 *efuse = le32_to_cpu(efuse_param.ulEfuseValue) & mask;
1280 1314
1281 return result; 1315 return result;
1282} 1316}
@@ -1284,6 +1318,7 @@ int atomctrl_read_efuse(void *device, uint16_t start_index,
1284int atomctrl_set_ac_timing_ai(struct pp_hwmgr *hwmgr, uint32_t memory_clock, 1318int atomctrl_set_ac_timing_ai(struct pp_hwmgr *hwmgr, uint32_t memory_clock,
1285 uint8_t level) 1319 uint8_t level)
1286{ 1320{
1321 struct amdgpu_device *adev = hwmgr->adev;
1287 DYNAMICE_MEMORY_SETTINGS_PARAMETER_V2_1 memory_clock_parameters; 1322 DYNAMICE_MEMORY_SETTINGS_PARAMETER_V2_1 memory_clock_parameters;
1288 int result; 1323 int result;
1289 1324
@@ -1293,10 +1328,9 @@ int atomctrl_set_ac_timing_ai(struct pp_hwmgr *hwmgr, uint32_t memory_clock,
1293 ADJUST_MC_SETTING_PARAM; 1328 ADJUST_MC_SETTING_PARAM;
1294 memory_clock_parameters.asDPMMCReg.ucMclkDPMState = level; 1329 memory_clock_parameters.asDPMMCReg.ucMclkDPMState = level;
1295 1330
1296 result = cgs_atom_exec_cmd_table 1331 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
1297 (hwmgr->device,
1298 GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings), 1332 GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings),
1299 &memory_clock_parameters); 1333 (uint32_t *)&memory_clock_parameters);
1300 1334
1301 return result; 1335 return result;
1302} 1336}
@@ -1304,7 +1338,7 @@ int atomctrl_set_ac_timing_ai(struct pp_hwmgr *hwmgr, uint32_t memory_clock,
1304int atomctrl_get_voltage_evv_on_sclk_ai(struct pp_hwmgr *hwmgr, uint8_t voltage_type, 1338int atomctrl_get_voltage_evv_on_sclk_ai(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
1305 uint32_t sclk, uint16_t virtual_voltage_Id, uint32_t *voltage) 1339 uint32_t sclk, uint16_t virtual_voltage_Id, uint32_t *voltage)
1306{ 1340{
1307 1341 struct amdgpu_device *adev = hwmgr->adev;
1308 int result; 1342 int result;
1309 GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_3 get_voltage_info_param_space; 1343 GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_3 get_voltage_info_param_space;
1310 1344
@@ -1313,15 +1347,12 @@ int atomctrl_get_voltage_evv_on_sclk_ai(struct pp_hwmgr *hwmgr, uint8_t voltage_
1313 get_voltage_info_param_space.usVoltageLevel = cpu_to_le16(virtual_voltage_Id); 1347 get_voltage_info_param_space.usVoltageLevel = cpu_to_le16(virtual_voltage_Id);
1314 get_voltage_info_param_space.ulSCLKFreq = cpu_to_le32(sclk); 1348 get_voltage_info_param_space.ulSCLKFreq = cpu_to_le32(sclk);
1315 1349
1316 result = cgs_atom_exec_cmd_table(hwmgr->device, 1350 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
1317 GetIndexIntoMasterTable(COMMAND, GetVoltageInfo), 1351 GetIndexIntoMasterTable(COMMAND, GetVoltageInfo),
1318 &get_voltage_info_param_space); 1352 (uint32_t *)&get_voltage_info_param_space);
1319 1353
1320 if (0 != result) 1354 *voltage = result ? 0 :
1321 return result; 1355 le32_to_cpu(((GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_3 *)(&get_voltage_info_param_space))->ulVoltageLevel);
1322
1323 *voltage = le32_to_cpu(((GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_3 *)
1324 (&get_voltage_info_param_space))->ulVoltageLevel);
1325 1356
1326 return result; 1357 return result;
1327} 1358}
@@ -1334,7 +1365,7 @@ int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctr
1334 u16 size; 1365 u16 size;
1335 1366
1336 ATOM_SMU_INFO_V2_1 *psmu_info = 1367 ATOM_SMU_INFO_V2_1 *psmu_info =
1337 (ATOM_SMU_INFO_V2_1 *)cgs_atom_get_data_table(hwmgr->device, 1368 (ATOM_SMU_INFO_V2_1 *)smu_atom_get_data_table(hwmgr->adev,
1338 GetIndexIntoMasterTable(DATA, SMU_Info), 1369 GetIndexIntoMasterTable(DATA, SMU_Info),
1339 &size, &frev, &crev); 1370 &size, &frev, &crev);
1340 1371
@@ -1362,7 +1393,7 @@ int atomctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
1362 return -EINVAL; 1393 return -EINVAL;
1363 1394
1364 profile = (ATOM_ASIC_PROFILING_INFO_V3_6 *) 1395 profile = (ATOM_ASIC_PROFILING_INFO_V3_6 *)
1365 cgs_atom_get_data_table(hwmgr->device, 1396 smu_atom_get_data_table(hwmgr->adev,
1366 GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo), 1397 GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo),
1367 NULL, NULL, NULL); 1398 NULL, NULL, NULL);
1368 if (!profile) 1399 if (!profile)
@@ -1402,7 +1433,7 @@ int atomctrl_get_svi2_info(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
1402 uint16_t *load_line) 1433 uint16_t *load_line)
1403{ 1434{
1404 ATOM_VOLTAGE_OBJECT_INFO_V3_1 *voltage_info = 1435 ATOM_VOLTAGE_OBJECT_INFO_V3_1 *voltage_info =
1405 (ATOM_VOLTAGE_OBJECT_INFO_V3_1 *)get_voltage_info_table(hwmgr->device); 1436 (ATOM_VOLTAGE_OBJECT_INFO_V3_1 *)get_voltage_info_table(hwmgr->adev);
1406 1437
1407 const ATOM_VOLTAGE_OBJECT_V3 *voltage_object; 1438 const ATOM_VOLTAGE_OBJECT_V3 *voltage_object;
1408 1439
@@ -1421,16 +1452,17 @@ int atomctrl_get_svi2_info(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
1421 1452
1422int atomctrl_get_leakage_id_from_efuse(struct pp_hwmgr *hwmgr, uint16_t *virtual_voltage_id) 1453int atomctrl_get_leakage_id_from_efuse(struct pp_hwmgr *hwmgr, uint16_t *virtual_voltage_id)
1423{ 1454{
1424 int result; 1455 struct amdgpu_device *adev = hwmgr->adev;
1425 SET_VOLTAGE_PS_ALLOCATION allocation; 1456 SET_VOLTAGE_PS_ALLOCATION allocation;
1426 SET_VOLTAGE_PARAMETERS_V1_3 *voltage_parameters = 1457 SET_VOLTAGE_PARAMETERS_V1_3 *voltage_parameters =
1427 (SET_VOLTAGE_PARAMETERS_V1_3 *)&allocation.sASICSetVoltage; 1458 (SET_VOLTAGE_PARAMETERS_V1_3 *)&allocation.sASICSetVoltage;
1459 int result;
1428 1460
1429 voltage_parameters->ucVoltageMode = ATOM_GET_LEAKAGE_ID; 1461 voltage_parameters->ucVoltageMode = ATOM_GET_LEAKAGE_ID;
1430 1462
1431 result = cgs_atom_exec_cmd_table(hwmgr->device, 1463 result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
1432 GetIndexIntoMasterTable(COMMAND, SetVoltage), 1464 GetIndexIntoMasterTable(COMMAND, SetVoltage),
1433 voltage_parameters); 1465 (uint32_t *)voltage_parameters);
1434 1466
1435 *virtual_voltage_id = voltage_parameters->usVoltageLevel; 1467 *virtual_voltage_id = voltage_parameters->usVoltageLevel;
1436 1468
@@ -1453,7 +1485,7 @@ int atomctrl_get_leakage_vddc_base_on_leakage(struct pp_hwmgr *hwmgr,
1453 ix = GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo); 1485 ix = GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo);
1454 1486
1455 profile = (ATOM_ASIC_PROFILING_INFO_V2_1 *) 1487 profile = (ATOM_ASIC_PROFILING_INFO_V2_1 *)
1456 cgs_atom_get_data_table(hwmgr->device, 1488 smu_atom_get_data_table(hwmgr->adev,
1457 ix, 1489 ix,
1458 NULL, NULL, NULL); 1490 NULL, NULL, NULL);
1459 if (!profile) 1491 if (!profile)
@@ -1498,3 +1530,33 @@ int atomctrl_get_leakage_vddc_base_on_leakage(struct pp_hwmgr *hwmgr,
1498 1530
1499 return 0; 1531 return 0;
1500} 1532}
1533
1534void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t *max_vddc,
1535 uint32_t *min_vddc)
1536{
1537 void *profile;
1538
1539 profile = smu_atom_get_data_table(hwmgr->adev,
1540 GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo),
1541 NULL, NULL, NULL);
1542
1543 if (profile) {
1544 switch (hwmgr->chip_id) {
1545 case CHIP_TONGA:
1546 case CHIP_FIJI:
1547 *max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMaxVddc/4);
1548 *min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMinVddc/4);
1549 return;
1550 case CHIP_POLARIS11:
1551 case CHIP_POLARIS10:
1552 case CHIP_POLARIS12:
1553 *max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMaxVddc/100);
1554 *min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMinVddc/100);
1555 return;
1556 default:
1557 break;
1558 }
1559 }
1560 *max_vddc = 0;
1561 *min_vddc = 0;
1562}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
index c44a92064cf1..3ee54f182943 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
@@ -146,6 +146,14 @@ struct pp_atomctrl_memory_clock_param {
146}; 146};
147typedef struct pp_atomctrl_memory_clock_param pp_atomctrl_memory_clock_param; 147typedef struct pp_atomctrl_memory_clock_param pp_atomctrl_memory_clock_param;
148 148
149struct pp_atomctrl_memory_clock_param_ai {
150 uint32_t ulClock;
151 uint32_t ulPostDiv;
152 uint16_t ulMclk_fcw_frac;
153 uint16_t ulMclk_fcw_int;
154};
155typedef struct pp_atomctrl_memory_clock_param_ai pp_atomctrl_memory_clock_param_ai;
156
149struct pp_atomctrl_internal_ss_info { 157struct pp_atomctrl_internal_ss_info {
150 uint32_t speed_spectrum_percentage; /* in 1/100 percentage */ 158 uint32_t speed_spectrum_percentage; /* in 1/100 percentage */
151 uint32_t speed_spectrum_rate; /* in KHz */ 159 uint32_t speed_spectrum_rate; /* in KHz */
@@ -295,10 +303,12 @@ extern bool atomctrl_is_voltage_controlled_by_gpio_v3(struct pp_hwmgr *hwmgr, ui
295extern int atomctrl_get_voltage_table_v3(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint8_t voltage_mode, pp_atomctrl_voltage_table *voltage_table); 303extern int atomctrl_get_voltage_table_v3(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint8_t voltage_mode, pp_atomctrl_voltage_table *voltage_table);
296extern int atomctrl_get_memory_pll_dividers_vi(struct pp_hwmgr *hwmgr, 304extern int atomctrl_get_memory_pll_dividers_vi(struct pp_hwmgr *hwmgr,
297 uint32_t clock_value, pp_atomctrl_memory_clock_param *mpll_param); 305 uint32_t clock_value, pp_atomctrl_memory_clock_param *mpll_param);
306extern int atomctrl_get_memory_pll_dividers_ai(struct pp_hwmgr *hwmgr,
307 uint32_t clock_value, pp_atomctrl_memory_clock_param_ai *mpll_param);
298extern int atomctrl_get_engine_pll_dividers_kong(struct pp_hwmgr *hwmgr, 308extern int atomctrl_get_engine_pll_dividers_kong(struct pp_hwmgr *hwmgr,
299 uint32_t clock_value, 309 uint32_t clock_value,
300 pp_atomctrl_clock_dividers_kong *dividers); 310 pp_atomctrl_clock_dividers_kong *dividers);
301extern int atomctrl_read_efuse(void *device, uint16_t start_index, 311extern int atomctrl_read_efuse(struct pp_hwmgr *hwmgr, uint16_t start_index,
302 uint16_t end_index, uint32_t mask, uint32_t *efuse); 312 uint16_t end_index, uint32_t mask, uint32_t *efuse);
303extern int atomctrl_calculate_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, 313extern int atomctrl_calculate_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
304 uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage, uint16_t dpm_level, bool debug); 314 uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage, uint16_t dpm_level, bool debug);
@@ -320,5 +330,8 @@ extern int atomctrl_get_leakage_vddc_base_on_leakage(struct pp_hwmgr *hwmgr,
320 uint16_t virtual_voltage_id, 330 uint16_t virtual_voltage_id,
321 uint16_t efuse_voltage_id); 331 uint16_t efuse_voltage_id);
322extern int atomctrl_get_leakage_id_from_efuse(struct pp_hwmgr *hwmgr, uint16_t *virtual_voltage_id); 332extern int atomctrl_get_leakage_id_from_efuse(struct pp_hwmgr *hwmgr, uint16_t *virtual_voltage_id);
333
334extern void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t *max_vddc,
335 uint32_t *min_vddc);
323#endif 336#endif
324 337
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
index ad42caac033e..c97b0e5ba43b 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
@@ -23,9 +23,9 @@
23 23
24#include "ppatomfwctrl.h" 24#include "ppatomfwctrl.h"
25#include "atomfirmware.h" 25#include "atomfirmware.h"
26#include "atom.h"
26#include "pp_debug.h" 27#include "pp_debug.h"
27 28
28
29static const union atom_voltage_object_v4 *pp_atomfwctrl_lookup_voltage_type_v4( 29static const union atom_voltage_object_v4 *pp_atomfwctrl_lookup_voltage_type_v4(
30 const struct atom_voltage_objects_info_v4_1 *voltage_object_info_table, 30 const struct atom_voltage_objects_info_v4_1 *voltage_object_info_table,
31 uint8_t voltage_type, uint8_t voltage_mode) 31 uint8_t voltage_type, uint8_t voltage_mode)
@@ -38,35 +38,34 @@ static const union atom_voltage_object_v4 *pp_atomfwctrl_lookup_voltage_type_v4(
38 38
39 while (offset < size) { 39 while (offset < size) {
40 const union atom_voltage_object_v4 *voltage_object = 40 const union atom_voltage_object_v4 *voltage_object =
41 (const union atom_voltage_object_v4 *)(start + offset); 41 (const union atom_voltage_object_v4 *)(start + offset);
42 42
43 if (voltage_type == voltage_object->gpio_voltage_obj.header.voltage_type && 43 if (voltage_type == voltage_object->gpio_voltage_obj.header.voltage_type &&
44 voltage_mode == voltage_object->gpio_voltage_obj.header.voltage_mode) 44 voltage_mode == voltage_object->gpio_voltage_obj.header.voltage_mode)
45 return voltage_object; 45 return voltage_object;
46 46
47 offset += le16_to_cpu(voltage_object->gpio_voltage_obj.header.object_size); 47 offset += le16_to_cpu(voltage_object->gpio_voltage_obj.header.object_size);
48 48
49 } 49 }
50 50
51 return NULL; 51 return NULL;
52} 52}
53 53
54static struct atom_voltage_objects_info_v4_1 *pp_atomfwctrl_get_voltage_info_table( 54static struct atom_voltage_objects_info_v4_1 *pp_atomfwctrl_get_voltage_info_table(
55 struct pp_hwmgr *hwmgr) 55 struct pp_hwmgr *hwmgr)
56{ 56{
57 const void *table_address; 57 const void *table_address;
58 uint16_t idx; 58 uint16_t idx;
59 59
60 idx = GetIndexIntoMasterDataTable(voltageobject_info); 60 idx = GetIndexIntoMasterDataTable(voltageobject_info);
61 table_address = cgs_atom_get_data_table(hwmgr->device, 61 table_address = smu_atom_get_data_table(hwmgr->adev,
62 idx, NULL, NULL, NULL); 62 idx, NULL, NULL, NULL);
63 63
64 PP_ASSERT_WITH_CODE( 64 PP_ASSERT_WITH_CODE(table_address,
65 table_address, 65 "Error retrieving BIOS Table Address!",
66 "Error retrieving BIOS Table Address!", 66 return NULL);
67 return NULL);
68 67
69 return (struct atom_voltage_objects_info_v4_1 *)table_address; 68 return (struct atom_voltage_objects_info_v4_1 *)table_address;
70} 69}
71 70
72/** 71/**
@@ -167,7 +166,7 @@ static struct atom_gpio_pin_lut_v2_1 *pp_atomfwctrl_get_gpio_lookup_table(
167 uint16_t idx; 166 uint16_t idx;
168 167
169 idx = GetIndexIntoMasterDataTable(gpio_pin_lut); 168 idx = GetIndexIntoMasterDataTable(gpio_pin_lut);
170 table_address = cgs_atom_get_data_table(hwmgr->device, 169 table_address = smu_atom_get_data_table(hwmgr->adev,
171 idx, NULL, NULL, NULL); 170 idx, NULL, NULL, NULL);
172 PP_ASSERT_WITH_CODE(table_address, 171 PP_ASSERT_WITH_CODE(table_address,
173 "Error retrieving BIOS Table Address!", 172 "Error retrieving BIOS Table Address!",
@@ -248,28 +247,30 @@ int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr,
248 uint32_t clock_type, uint32_t clock_value, 247 uint32_t clock_type, uint32_t clock_value,
249 struct pp_atomfwctrl_clock_dividers_soc15 *dividers) 248 struct pp_atomfwctrl_clock_dividers_soc15 *dividers)
250{ 249{
250 struct amdgpu_device *adev = hwmgr->adev;
251 struct compute_gpu_clock_input_parameter_v1_8 pll_parameters; 251 struct compute_gpu_clock_input_parameter_v1_8 pll_parameters;
252 struct compute_gpu_clock_output_parameter_v1_8 *pll_output; 252 struct compute_gpu_clock_output_parameter_v1_8 *pll_output;
253 int result;
254 uint32_t idx; 253 uint32_t idx;
255 254
256 pll_parameters.gpuclock_10khz = (uint32_t)clock_value; 255 pll_parameters.gpuclock_10khz = (uint32_t)clock_value;
257 pll_parameters.gpu_clock_type = clock_type; 256 pll_parameters.gpu_clock_type = clock_type;
258 257
259 idx = GetIndexIntoMasterCmdTable(computegpuclockparam); 258 idx = GetIndexIntoMasterCmdTable(computegpuclockparam);
260 result = cgs_atom_exec_cmd_table(hwmgr->device, idx, &pll_parameters); 259
261 260 if (amdgpu_atom_execute_table(
262 if (!result) { 261 adev->mode_info.atom_context, idx, (uint32_t *)&pll_parameters))
263 pll_output = (struct compute_gpu_clock_output_parameter_v1_8 *) 262 return -EINVAL;
264 &pll_parameters; 263
265 dividers->ulClock = le32_to_cpu(pll_output->gpuclock_10khz); 264 pll_output = (struct compute_gpu_clock_output_parameter_v1_8 *)
266 dividers->ulDid = le32_to_cpu(pll_output->dfs_did); 265 &pll_parameters;
267 dividers->ulPll_fb_mult = le32_to_cpu(pll_output->pll_fb_mult); 266 dividers->ulClock = le32_to_cpu(pll_output->gpuclock_10khz);
268 dividers->ulPll_ss_fbsmult = le32_to_cpu(pll_output->pll_ss_fbsmult); 267 dividers->ulDid = le32_to_cpu(pll_output->dfs_did);
269 dividers->usPll_ss_slew_frac = le16_to_cpu(pll_output->pll_ss_slew_frac); 268 dividers->ulPll_fb_mult = le32_to_cpu(pll_output->pll_fb_mult);
270 dividers->ucPll_ss_enable = pll_output->pll_ss_enable; 269 dividers->ulPll_ss_fbsmult = le32_to_cpu(pll_output->pll_ss_fbsmult);
271 } 270 dividers->usPll_ss_slew_frac = le16_to_cpu(pll_output->pll_ss_slew_frac);
272 return result; 271 dividers->ucPll_ss_enable = pll_output->pll_ss_enable;
272
273 return 0;
273} 274}
274 275
275int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr, 276int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
@@ -283,7 +284,7 @@ int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
283 284
284 idx = GetIndexIntoMasterDataTable(asic_profiling_info); 285 idx = GetIndexIntoMasterDataTable(asic_profiling_info);
285 profile = (struct atom_asic_profiling_info_v4_1 *) 286 profile = (struct atom_asic_profiling_info_v4_1 *)
286 cgs_atom_get_data_table(hwmgr->device, 287 smu_atom_get_data_table(hwmgr->adev,
287 idx, NULL, NULL, NULL); 288 idx, NULL, NULL, NULL);
288 289
289 if (!profile) 290 if (!profile)
@@ -467,7 +468,7 @@ int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr,
467 468
468 idx = GetIndexIntoMasterDataTable(smu_info); 469 idx = GetIndexIntoMasterDataTable(smu_info);
469 info = (struct atom_smu_info_v3_1 *) 470 info = (struct atom_smu_info_v3_1 *)
470 cgs_atom_get_data_table(hwmgr->device, 471 smu_atom_get_data_table(hwmgr->adev,
471 idx, NULL, NULL, NULL); 472 idx, NULL, NULL, NULL);
472 473
473 if (!info) { 474 if (!info) {
@@ -487,8 +488,9 @@ int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr,
487 return 0; 488 return 0;
488} 489}
489 490
490int pp_atomfwctrl__get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, BIOS_CLKID id, uint32_t *frequency) 491int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, BIOS_CLKID id, uint32_t *frequency)
491{ 492{
493 struct amdgpu_device *adev = hwmgr->adev;
492 struct atom_get_smu_clock_info_parameters_v3_1 parameters; 494 struct atom_get_smu_clock_info_parameters_v3_1 parameters;
493 struct atom_get_smu_clock_info_output_parameters_v3_1 *output; 495 struct atom_get_smu_clock_info_output_parameters_v3_1 *output;
494 uint32_t ix; 496 uint32_t ix;
@@ -497,13 +499,13 @@ int pp_atomfwctrl__get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, BIOS_CLK
497 parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ; 499 parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ;
498 500
499 ix = GetIndexIntoMasterCmdTable(getsmuclockinfo); 501 ix = GetIndexIntoMasterCmdTable(getsmuclockinfo);
500 if (!cgs_atom_exec_cmd_table(hwmgr->device, ix, &parameters)) { 502
501 output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)&parameters; 503 if (amdgpu_atom_execute_table(
502 *frequency = output->atom_smu_outputclkfreq.smu_clock_freq_hz / 10000; 504 adev->mode_info.atom_context, ix, (uint32_t *)&parameters))
503 } else { 505 return -EINVAL;
504 pr_info("Error execute_table getsmuclockinfo!"); 506
505 return -1; 507 output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)&parameters;
506 } 508 *frequency = output->atom_smu_outputclkfreq.smu_clock_freq_hz / 10000;
507 509
508 return 0; 510 return 0;
509} 511}
@@ -513,11 +515,10 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
513{ 515{
514 struct atom_firmware_info_v3_1 *info = NULL; 516 struct atom_firmware_info_v3_1 *info = NULL;
515 uint16_t ix; 517 uint16_t ix;
516 uint32_t frequency = 0;
517 518
518 ix = GetIndexIntoMasterDataTable(firmwareinfo); 519 ix = GetIndexIntoMasterDataTable(firmwareinfo);
519 info = (struct atom_firmware_info_v3_1 *) 520 info = (struct atom_firmware_info_v3_1 *)
520 cgs_atom_get_data_table(hwmgr->device, 521 smu_atom_get_data_table(hwmgr->adev,
521 ix, NULL, NULL, NULL); 522 ix, NULL, NULL, NULL);
522 523
523 if (!info) { 524 if (!info) {
@@ -536,12 +537,6 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
536 boot_values->ulSocClk = 0; 537 boot_values->ulSocClk = 0;
537 boot_values->ulDCEFClk = 0; 538 boot_values->ulDCEFClk = 0;
538 539
539 if (!pp_atomfwctrl__get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, &frequency))
540 boot_values->ulSocClk = frequency;
541
542 if (!pp_atomfwctrl__get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, &frequency))
543 boot_values->ulDCEFClk = frequency;
544
545 return 0; 540 return 0;
546} 541}
547 542
@@ -553,7 +548,7 @@ int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,
553 548
554 ix = GetIndexIntoMasterDataTable(smc_dpm_info); 549 ix = GetIndexIntoMasterDataTable(smc_dpm_info);
555 info = (struct atom_smc_dpm_info_v4_1 *) 550 info = (struct atom_smc_dpm_info_v4_1 *)
556 cgs_atom_get_data_table(hwmgr->device, 551 smu_atom_get_data_table(hwmgr->adev,
557 ix, NULL, NULL, NULL); 552 ix, NULL, NULL, NULL);
558 if (!info) { 553 if (!info) {
559 pr_info("Error retrieving BIOS Table Address!"); 554 pr_info("Error retrieving BIOS Table Address!");
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
index 8df1e84f27c9..fe10aa4db5e6 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
@@ -230,6 +230,8 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
230 struct pp_atomfwctrl_bios_boot_up_values *boot_values); 230 struct pp_atomfwctrl_bios_boot_up_values *boot_values);
231int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr, 231int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,
232 struct pp_atomfwctrl_smc_dpm_parameters *param); 232 struct pp_atomfwctrl_smc_dpm_parameters *param);
233int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr,
234 BIOS_CLKID id, uint32_t *frequency);
233 235
234#endif 236#endif
235 237
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c b/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c
index c9eecce5683f..f0d48b183d22 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c
@@ -141,7 +141,7 @@ static const void *get_powerplay_table(struct pp_hwmgr *hwmgr)
141 141
142 if (!table_address) { 142 if (!table_address) {
143 table_address = (ATOM_Tonga_POWERPLAYTABLE *) 143 table_address = (ATOM_Tonga_POWERPLAYTABLE *)
144 cgs_atom_get_data_table(hwmgr->device, 144 smu_atom_get_data_table(hwmgr->adev,
145 index, &size, &frev, &crev); 145 index, &size, &frev, &crev);
146 hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/ 146 hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/
147 hwmgr->soft_pp_table_size = size; 147 hwmgr->soft_pp_table_size = size;
@@ -728,6 +728,32 @@ static int get_mm_clock_voltage_table(
728 return 0; 728 return 0;
729} 729}
730 730
731static int get_gpio_table(struct pp_hwmgr *hwmgr,
732 struct phm_ppt_v1_gpio_table **pp_tonga_gpio_table,
733 const ATOM_Tonga_GPIO_Table *atom_gpio_table)
734{
735 uint32_t table_size;
736 struct phm_ppt_v1_gpio_table *pp_gpio_table;
737 struct phm_ppt_v1_information *pp_table_information =
738 (struct phm_ppt_v1_information *)(hwmgr->pptable);
739
740 table_size = sizeof(struct phm_ppt_v1_gpio_table);
741 pp_gpio_table = kzalloc(table_size, GFP_KERNEL);
742 if (!pp_gpio_table)
743 return -ENOMEM;
744
745 if (pp_table_information->vdd_dep_on_sclk->count <
746 atom_gpio_table->ucVRHotTriggeredSclkDpmIndex)
747 PP_ASSERT_WITH_CODE(false,
748 "SCLK DPM index for VRHot cannot exceed the total sclk level count!",);
749 else
750 pp_gpio_table->vrhot_triggered_sclk_dpm_index =
751 atom_gpio_table->ucVRHotTriggeredSclkDpmIndex;
752
753 *pp_tonga_gpio_table = pp_gpio_table;
754
755 return 0;
756}
731/** 757/**
732 * Private Function used during initialization. 758 * Private Function used during initialization.
733 * Initialize clock voltage dependency 759 * Initialize clock voltage dependency
@@ -761,11 +787,15 @@ static int init_clock_voltage_dependency(
761 const PPTable_Generic_SubTable_Header *pcie_table = 787 const PPTable_Generic_SubTable_Header *pcie_table =
762 (const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) + 788 (const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) +
763 le16_to_cpu(powerplay_table->usPCIETableOffset)); 789 le16_to_cpu(powerplay_table->usPCIETableOffset));
790 const ATOM_Tonga_GPIO_Table *gpio_table =
791 (const ATOM_Tonga_GPIO_Table *)(((unsigned long) powerplay_table) +
792 le16_to_cpu(powerplay_table->usGPIOTableOffset));
764 793
765 pp_table_information->vdd_dep_on_sclk = NULL; 794 pp_table_information->vdd_dep_on_sclk = NULL;
766 pp_table_information->vdd_dep_on_mclk = NULL; 795 pp_table_information->vdd_dep_on_mclk = NULL;
767 pp_table_information->mm_dep_table = NULL; 796 pp_table_information->mm_dep_table = NULL;
768 pp_table_information->pcie_table = NULL; 797 pp_table_information->pcie_table = NULL;
798 pp_table_information->gpio_table = NULL;
769 799
770 if (powerplay_table->usMMDependencyTableOffset != 0) 800 if (powerplay_table->usMMDependencyTableOffset != 0)
771 result = get_mm_clock_voltage_table(hwmgr, 801 result = get_mm_clock_voltage_table(hwmgr,
@@ -810,6 +840,10 @@ static int init_clock_voltage_dependency(
810 result = get_valid_clk(hwmgr, &pp_table_information->valid_sclk_values, 840 result = get_valid_clk(hwmgr, &pp_table_information->valid_sclk_values,
811 pp_table_information->vdd_dep_on_sclk); 841 pp_table_information->vdd_dep_on_sclk);
812 842
843 if (!result && gpio_table)
844 result = get_gpio_table(hwmgr, &pp_table_information->gpio_table,
845 gpio_table);
846
813 return result; 847 return result;
814} 848}
815 849
@@ -1116,6 +1150,9 @@ static int pp_tables_v1_0_uninitialize(struct pp_hwmgr *hwmgr)
1116 kfree(pp_table_information->pcie_table); 1150 kfree(pp_table_information->pcie_table);
1117 pp_table_information->pcie_table = NULL; 1151 pp_table_information->pcie_table = NULL;
1118 1152
1153 kfree(pp_table_information->gpio_table);
1154 pp_table_information->gpio_table = NULL;
1155
1119 kfree(hwmgr->pptable); 1156 kfree(hwmgr->pptable);
1120 hwmgr->pptable = NULL; 1157 hwmgr->pptable = NULL;
1121 1158
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
index 36ca7c419c90..ce64dfabd34b 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
@@ -837,7 +837,7 @@ static const ATOM_PPLIB_POWERPLAYTABLE *get_powerplay_table(
837 hwmgr->soft_pp_table = &soft_dummy_pp_table[0]; 837 hwmgr->soft_pp_table = &soft_dummy_pp_table[0];
838 hwmgr->soft_pp_table_size = sizeof(soft_dummy_pp_table); 838 hwmgr->soft_pp_table_size = sizeof(soft_dummy_pp_table);
839 } else { 839 } else {
840 table_addr = cgs_atom_get_data_table(hwmgr->device, 840 table_addr = smu_atom_get_data_table(hwmgr->adev,
841 GetIndexIntoMasterTable(DATA, PowerPlayInfo), 841 GetIndexIntoMasterTable(DATA, PowerPlayInfo),
842 &size, &frev, &crev); 842 &size, &frev, &crev);
843 hwmgr->soft_pp_table = table_addr; 843 hwmgr->soft_pp_table = table_addr;
@@ -1058,7 +1058,7 @@ static int init_overdrive_limits(struct pp_hwmgr *hwmgr,
1058 return 0; 1058 return 0;
1059 1059
1060 /* We assume here that fw_info is unchanged if this call fails.*/ 1060 /* We assume here that fw_info is unchanged if this call fails.*/
1061 fw_info = cgs_atom_get_data_table(hwmgr->device, 1061 fw_info = smu_atom_get_data_table(hwmgr->adev,
1062 GetIndexIntoMasterTable(DATA, FirmwareInfo), 1062 GetIndexIntoMasterTable(DATA, FirmwareInfo),
1063 &size, &frev, &crev); 1063 &size, &frev, &crev);
1064 1064
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
index 10253b89b3d8..85f84f4d8be5 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
@@ -34,7 +34,7 @@
34#include "rv_ppsmc.h" 34#include "rv_ppsmc.h"
35#include "smu10_hwmgr.h" 35#include "smu10_hwmgr.h"
36#include "power_state.h" 36#include "power_state.h"
37#include "pp_soc15.h" 37#include "soc15_common.h"
38 38
39#define SMU10_MAX_DEEPSLEEP_DIVIDER_ID 5 39#define SMU10_MAX_DEEPSLEEP_DIVIDER_ID 5
40#define SMU10_MINIMUM_ENGINE_CLOCK 800 /* 8Mhz, the low boundary of engine clock allowed on this chip */ 40#define SMU10_MINIMUM_ENGINE_CLOCK 800 /* 8Mhz, the low boundary of engine clock allowed on this chip */
@@ -42,6 +42,13 @@
42#define SMU10_DISPCLK_BYPASS_THRESHOLD 10000 /* 100Mhz */ 42#define SMU10_DISPCLK_BYPASS_THRESHOLD 10000 /* 100Mhz */
43#define SMC_RAM_END 0x40000 43#define SMC_RAM_END 0x40000
44 44
45#define mmPWR_MISC_CNTL_STATUS 0x0183
46#define mmPWR_MISC_CNTL_STATUS_BASE_IDX 0
47#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT 0x0
48#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT 0x1
49#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK 0x00000001L
50#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK 0x00000006L
51
45static const unsigned long SMU10_Magic = (unsigned long) PHM_Rv_Magic; 52static const unsigned long SMU10_Magic = (unsigned long) PHM_Rv_Magic;
46 53
47 54
@@ -74,11 +81,15 @@ static int smu10_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
74 smu10_data->thermal_auto_throttling_treshold = 0; 81 smu10_data->thermal_auto_throttling_treshold = 0;
75 smu10_data->is_nb_dpm_enabled = 1; 82 smu10_data->is_nb_dpm_enabled = 1;
76 smu10_data->dpm_flags = 1; 83 smu10_data->dpm_flags = 1;
77 smu10_data->gfx_off_controled_by_driver = false;
78 smu10_data->need_min_deep_sleep_dcefclk = true; 84 smu10_data->need_min_deep_sleep_dcefclk = true;
79 smu10_data->num_active_display = 0; 85 smu10_data->num_active_display = 0;
80 smu10_data->deep_sleep_dcefclk = 0; 86 smu10_data->deep_sleep_dcefclk = 0;
81 87
88 if (hwmgr->feature_mask & PP_GFXOFF_MASK)
89 smu10_data->gfx_off_controled_by_driver = true;
90 else
91 smu10_data->gfx_off_controled_by_driver = false;
92
82 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 93 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
83 PHM_PlatformCaps_SclkDeepSleep); 94 PHM_PlatformCaps_SclkDeepSleep);
84 95
@@ -161,7 +172,7 @@ static int smu10_set_clock_limit(struct pp_hwmgr *hwmgr, const void *input)
161 struct PP_Clocks clocks = {0}; 172 struct PP_Clocks clocks = {0};
162 struct pp_display_clock_request clock_req; 173 struct pp_display_clock_request clock_req;
163 174
164 clocks.dcefClock = hwmgr->display_config.min_dcef_set_clk; 175 clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk;
165 clock_req.clock_type = amd_pp_dcf_clock; 176 clock_req.clock_type = amd_pp_dcf_clock;
166 clock_req.clock_freq_in_khz = clocks.dcefClock * 10; 177 clock_req.clock_freq_in_khz = clocks.dcefClock * 10;
167 178
@@ -206,12 +217,18 @@ static int smu10_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void *input
206static int smu10_init_power_gate_state(struct pp_hwmgr *hwmgr) 217static int smu10_init_power_gate_state(struct pp_hwmgr *hwmgr)
207{ 218{
208 struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); 219 struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
220 struct amdgpu_device *adev = hwmgr->adev;
209 221
210 smu10_data->vcn_power_gated = true; 222 smu10_data->vcn_power_gated = true;
211 smu10_data->isp_tileA_power_gated = true; 223 smu10_data->isp_tileA_power_gated = true;
212 smu10_data->isp_tileB_power_gated = true; 224 smu10_data->isp_tileB_power_gated = true;
213 225
214 return 0; 226 if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)
227 return smum_send_msg_to_smc_with_parameter(hwmgr,
228 PPSMC_MSG_SetGfxCGPG,
229 true);
230 else
231 return 0;
215} 232}
216 233
217 234
@@ -237,13 +254,31 @@ static int smu10_power_off_asic(struct pp_hwmgr *hwmgr)
237 return smu10_reset_cc6_data(hwmgr); 254 return smu10_reset_cc6_data(hwmgr);
238} 255}
239 256
257static bool smu10_is_gfx_on(struct pp_hwmgr *hwmgr)
258{
259 uint32_t reg;
260 struct amdgpu_device *adev = hwmgr->adev;
261
262 reg = RREG32_SOC15(PWR, 0, mmPWR_MISC_CNTL_STATUS);
263 if ((reg & PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK) ==
264 (0x2 << PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT))
265 return true;
266
267 return false;
268}
269
240static int smu10_disable_gfx_off(struct pp_hwmgr *hwmgr) 270static int smu10_disable_gfx_off(struct pp_hwmgr *hwmgr)
241{ 271{
242 struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); 272 struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
243 273
244 if (smu10_data->gfx_off_controled_by_driver) 274 if (smu10_data->gfx_off_controled_by_driver) {
245 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableGfxOff); 275 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableGfxOff);
246 276
277 /* confirm gfx is back to "on" state */
278 while (!smu10_is_gfx_on(hwmgr))
279 msleep(1);
280 }
281
247 return 0; 282 return 0;
248} 283}
249 284
@@ -267,6 +302,14 @@ static int smu10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
267 return smu10_enable_gfx_off(hwmgr); 302 return smu10_enable_gfx_off(hwmgr);
268} 303}
269 304
305static int smu10_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable)
306{
307 if (enable)
308 return smu10_enable_gfx_off(hwmgr);
309 else
310 return smu10_disable_gfx_off(hwmgr);
311}
312
270static int smu10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, 313static int smu10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
271 struct pp_power_state *prequest_ps, 314 struct pp_power_state *prequest_ps,
272 const struct pp_power_state *pcurrent_ps) 315 const struct pp_power_state *pcurrent_ps)
@@ -340,7 +383,7 @@ static int smu10_get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr,
340 383
341static int smu10_populate_clock_table(struct pp_hwmgr *hwmgr) 384static int smu10_populate_clock_table(struct pp_hwmgr *hwmgr)
342{ 385{
343 int result; 386 uint32_t result;
344 387
345 struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); 388 struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
346 DpmClocks_t *table = &(smu10_data->clock_table); 389 DpmClocks_t *table = &(smu10_data->clock_table);
@@ -386,11 +429,11 @@ static int smu10_populate_clock_table(struct pp_hwmgr *hwmgr)
386 429
387 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency); 430 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency);
388 result = smum_get_argument(hwmgr); 431 result = smum_get_argument(hwmgr);
389 smu10_data->gfx_min_freq_limit = result * 100; 432 smu10_data->gfx_min_freq_limit = result / 10 * 1000;
390 433
391 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency); 434 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency);
392 result = smum_get_argument(hwmgr); 435 result = smum_get_argument(hwmgr);
393 smu10_data->gfx_max_freq_limit = result * 100; 436 smu10_data->gfx_max_freq_limit = result / 10 * 1000;
394 437
395 return 0; 438 return 0;
396} 439}
@@ -436,8 +479,8 @@ static int smu10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
436 479
437 hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; 480 hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
438 481
439 hwmgr->pstate_sclk = SMU10_UMD_PSTATE_GFXCLK; 482 hwmgr->pstate_sclk = SMU10_UMD_PSTATE_GFXCLK * 100;
440 hwmgr->pstate_mclk = SMU10_UMD_PSTATE_FCLK; 483 hwmgr->pstate_mclk = SMU10_UMD_PSTATE_FCLK * 100;
441 484
442 return result; 485 return result;
443} 486}
@@ -472,6 +515,8 @@ static int smu10_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
472static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, 515static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
473 enum amd_dpm_forced_level level) 516 enum amd_dpm_forced_level level)
474{ 517{
518 struct smu10_hwmgr *data = hwmgr->backend;
519
475 if (hwmgr->smu_version < 0x1E3700) { 520 if (hwmgr->smu_version < 0x1E3700) {
476 pr_info("smu firmware version too old, can not set dpm level\n"); 521 pr_info("smu firmware version too old, can not set dpm level\n");
477 return 0; 522 return 0;
@@ -482,7 +527,7 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
482 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: 527 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
483 smum_send_msg_to_smc_with_parameter(hwmgr, 528 smum_send_msg_to_smc_with_parameter(hwmgr,
484 PPSMC_MSG_SetHardMinGfxClk, 529 PPSMC_MSG_SetHardMinGfxClk,
485 SMU10_UMD_PSTATE_PEAK_GFXCLK); 530 data->gfx_max_freq_limit/100);
486 smum_send_msg_to_smc_with_parameter(hwmgr, 531 smum_send_msg_to_smc_with_parameter(hwmgr,
487 PPSMC_MSG_SetHardMinFclkByFreq, 532 PPSMC_MSG_SetHardMinFclkByFreq,
488 SMU10_UMD_PSTATE_PEAK_FCLK); 533 SMU10_UMD_PSTATE_PEAK_FCLK);
@@ -495,7 +540,7 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
495 540
496 smum_send_msg_to_smc_with_parameter(hwmgr, 541 smum_send_msg_to_smc_with_parameter(hwmgr,
497 PPSMC_MSG_SetSoftMaxGfxClk, 542 PPSMC_MSG_SetSoftMaxGfxClk,
498 SMU10_UMD_PSTATE_PEAK_GFXCLK); 543 data->gfx_max_freq_limit/100);
499 smum_send_msg_to_smc_with_parameter(hwmgr, 544 smum_send_msg_to_smc_with_parameter(hwmgr,
500 PPSMC_MSG_SetSoftMaxFclkByFreq, 545 PPSMC_MSG_SetSoftMaxFclkByFreq,
501 SMU10_UMD_PSTATE_PEAK_FCLK); 546 SMU10_UMD_PSTATE_PEAK_FCLK);
@@ -509,10 +554,10 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
509 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: 554 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
510 smum_send_msg_to_smc_with_parameter(hwmgr, 555 smum_send_msg_to_smc_with_parameter(hwmgr,
511 PPSMC_MSG_SetHardMinGfxClk, 556 PPSMC_MSG_SetHardMinGfxClk,
512 SMU10_UMD_PSTATE_MIN_GFXCLK); 557 data->gfx_min_freq_limit/100);
513 smum_send_msg_to_smc_with_parameter(hwmgr, 558 smum_send_msg_to_smc_with_parameter(hwmgr,
514 PPSMC_MSG_SetSoftMaxGfxClk, 559 PPSMC_MSG_SetSoftMaxGfxClk,
515 SMU10_UMD_PSTATE_MIN_GFXCLK); 560 data->gfx_min_freq_limit/100);
516 break; 561 break;
517 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: 562 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
518 smum_send_msg_to_smc_with_parameter(hwmgr, 563 smum_send_msg_to_smc_with_parameter(hwmgr,
@@ -552,10 +597,13 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
552 case AMD_DPM_FORCED_LEVEL_AUTO: 597 case AMD_DPM_FORCED_LEVEL_AUTO:
553 smum_send_msg_to_smc_with_parameter(hwmgr, 598 smum_send_msg_to_smc_with_parameter(hwmgr,
554 PPSMC_MSG_SetHardMinGfxClk, 599 PPSMC_MSG_SetHardMinGfxClk,
555 SMU10_UMD_PSTATE_MIN_GFXCLK); 600 data->gfx_min_freq_limit/100);
556 smum_send_msg_to_smc_with_parameter(hwmgr, 601 smum_send_msg_to_smc_with_parameter(hwmgr,
557 PPSMC_MSG_SetHardMinFclkByFreq, 602 PPSMC_MSG_SetHardMinFclkByFreq,
603 hwmgr->display_config->num_display > 3 ?
604 SMU10_UMD_PSTATE_PEAK_FCLK :
558 SMU10_UMD_PSTATE_MIN_FCLK); 605 SMU10_UMD_PSTATE_MIN_FCLK);
606
559 smum_send_msg_to_smc_with_parameter(hwmgr, 607 smum_send_msg_to_smc_with_parameter(hwmgr,
560 PPSMC_MSG_SetHardMinSocclkByFreq, 608 PPSMC_MSG_SetHardMinSocclkByFreq,
561 SMU10_UMD_PSTATE_MIN_SOCCLK); 609 SMU10_UMD_PSTATE_MIN_SOCCLK);
@@ -565,7 +613,7 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
565 613
566 smum_send_msg_to_smc_with_parameter(hwmgr, 614 smum_send_msg_to_smc_with_parameter(hwmgr,
567 PPSMC_MSG_SetSoftMaxGfxClk, 615 PPSMC_MSG_SetSoftMaxGfxClk,
568 SMU10_UMD_PSTATE_PEAK_GFXCLK); 616 data->gfx_max_freq_limit/100);
569 smum_send_msg_to_smc_with_parameter(hwmgr, 617 smum_send_msg_to_smc_with_parameter(hwmgr,
570 PPSMC_MSG_SetSoftMaxFclkByFreq, 618 PPSMC_MSG_SetSoftMaxFclkByFreq,
571 SMU10_UMD_PSTATE_PEAK_FCLK); 619 SMU10_UMD_PSTATE_PEAK_FCLK);
@@ -579,10 +627,10 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
579 case AMD_DPM_FORCED_LEVEL_LOW: 627 case AMD_DPM_FORCED_LEVEL_LOW:
580 smum_send_msg_to_smc_with_parameter(hwmgr, 628 smum_send_msg_to_smc_with_parameter(hwmgr,
581 PPSMC_MSG_SetHardMinGfxClk, 629 PPSMC_MSG_SetHardMinGfxClk,
582 SMU10_UMD_PSTATE_MIN_GFXCLK); 630 data->gfx_min_freq_limit/100);
583 smum_send_msg_to_smc_with_parameter(hwmgr, 631 smum_send_msg_to_smc_with_parameter(hwmgr,
584 PPSMC_MSG_SetSoftMaxGfxClk, 632 PPSMC_MSG_SetSoftMaxGfxClk,
585 SMU10_UMD_PSTATE_MIN_GFXCLK); 633 data->gfx_min_freq_limit/100);
586 smum_send_msg_to_smc_with_parameter(hwmgr, 634 smum_send_msg_to_smc_with_parameter(hwmgr,
587 PPSMC_MSG_SetHardMinFclkByFreq, 635 PPSMC_MSG_SetHardMinFclkByFreq,
588 SMU10_UMD_PSTATE_MIN_FCLK); 636 SMU10_UMD_PSTATE_MIN_FCLK);
@@ -699,6 +747,16 @@ static int smu10_set_cpu_power_state(struct pp_hwmgr *hwmgr)
699static int smu10_store_cc6_data(struct pp_hwmgr *hwmgr, uint32_t separation_time, 747static int smu10_store_cc6_data(struct pp_hwmgr *hwmgr, uint32_t separation_time,
700 bool cc6_disable, bool pstate_disable, bool pstate_switch_disable) 748 bool cc6_disable, bool pstate_disable, bool pstate_switch_disable)
701{ 749{
750 struct smu10_hwmgr *data = (struct smu10_hwmgr *)(hwmgr->backend);
751
752 if (separation_time != data->separation_time ||
753 cc6_disable != data->cc6_disable ||
754 pstate_disable != data->pstate_disable) {
755 data->separation_time = separation_time;
756 data->cc6_disable = cc6_disable;
757 data->pstate_disable = pstate_disable;
758 data->cc6_setting_changed = true;
759 }
702 return 0; 760 return 0;
703} 761}
704 762
@@ -711,6 +769,51 @@ static int smu10_get_dal_power_level(struct pp_hwmgr *hwmgr,
711static int smu10_force_clock_level(struct pp_hwmgr *hwmgr, 769static int smu10_force_clock_level(struct pp_hwmgr *hwmgr,
712 enum pp_clock_type type, uint32_t mask) 770 enum pp_clock_type type, uint32_t mask)
713{ 771{
772 struct smu10_hwmgr *data = hwmgr->backend;
773 struct smu10_voltage_dependency_table *mclk_table =
774 data->clock_vol_info.vdd_dep_on_fclk;
775 uint32_t low, high;
776
777 low = mask ? (ffs(mask) - 1) : 0;
778 high = mask ? (fls(mask) - 1) : 0;
779
780 switch (type) {
781 case PP_SCLK:
782 if (low > 2 || high > 2) {
783 pr_info("Currently sclk only support 3 levels on RV\n");
784 return -EINVAL;
785 }
786
787 smum_send_msg_to_smc_with_parameter(hwmgr,
788 PPSMC_MSG_SetHardMinGfxClk,
789 low == 2 ? data->gfx_max_freq_limit/100 :
790 low == 1 ? SMU10_UMD_PSTATE_GFXCLK :
791 data->gfx_min_freq_limit/100);
792
793 smum_send_msg_to_smc_with_parameter(hwmgr,
794 PPSMC_MSG_SetSoftMaxGfxClk,
795 high == 0 ? data->gfx_min_freq_limit/100 :
796 high == 1 ? SMU10_UMD_PSTATE_GFXCLK :
797 data->gfx_max_freq_limit/100);
798 break;
799
800 case PP_MCLK:
801 if (low > mclk_table->count - 1 || high > mclk_table->count - 1)
802 return -EINVAL;
803
804 smum_send_msg_to_smc_with_parameter(hwmgr,
805 PPSMC_MSG_SetHardMinFclkByFreq,
806 mclk_table->entries[low].clk/100);
807
808 smum_send_msg_to_smc_with_parameter(hwmgr,
809 PPSMC_MSG_SetSoftMaxFclkByFreq,
810 mclk_table->entries[high].clk/100);
811 break;
812
813 case PP_PCIE:
814 default:
815 break;
816 }
714 return 0; 817 return 0;
715} 818}
716 819
@@ -720,21 +823,30 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
720 struct smu10_hwmgr *data = (struct smu10_hwmgr *)(hwmgr->backend); 823 struct smu10_hwmgr *data = (struct smu10_hwmgr *)(hwmgr->backend);
721 struct smu10_voltage_dependency_table *mclk_table = 824 struct smu10_voltage_dependency_table *mclk_table =
722 data->clock_vol_info.vdd_dep_on_fclk; 825 data->clock_vol_info.vdd_dep_on_fclk;
723 int i, now, size = 0; 826 uint32_t i, now, size = 0;
724 827
725 switch (type) { 828 switch (type) {
726 case PP_SCLK: 829 case PP_SCLK:
727 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency); 830 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency);
728 now = smum_get_argument(hwmgr); 831 now = smum_get_argument(hwmgr);
729 832
833 /* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
834 if (now == data->gfx_max_freq_limit/100)
835 i = 2;
836 else if (now == data->gfx_min_freq_limit/100)
837 i = 0;
838 else
839 i = 1;
840
730 size += sprintf(buf + size, "0: %uMhz %s\n", 841 size += sprintf(buf + size, "0: %uMhz %s\n",
731 data->gfx_min_freq_limit / 100, 842 data->gfx_min_freq_limit/100,
732 ((data->gfx_min_freq_limit / 100) 843 i == 0 ? "*" : "");
733 == now) ? "*" : "");
734 size += sprintf(buf + size, "1: %uMhz %s\n", 844 size += sprintf(buf + size, "1: %uMhz %s\n",
735 data->gfx_max_freq_limit / 100, 845 i == 1 ? now : SMU10_UMD_PSTATE_GFXCLK,
736 ((data->gfx_max_freq_limit / 100) 846 i == 1 ? "*" : "");
737 == now) ? "*" : ""); 847 size += sprintf(buf + size, "2: %uMhz %s\n",
848 data->gfx_max_freq_limit/100,
849 i == 2 ? "*" : "");
738 break; 850 break;
739 case PP_MCLK: 851 case PP_MCLK:
740 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency); 852 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency);
@@ -947,9 +1059,8 @@ static int smu10_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simpl
947 1059
948static int smu10_thermal_get_temperature(struct pp_hwmgr *hwmgr) 1060static int smu10_thermal_get_temperature(struct pp_hwmgr *hwmgr)
949{ 1061{
950 uint32_t reg_offset = soc15_get_register_offset(THM_HWID, 0, 1062 struct amdgpu_device *adev = hwmgr->adev;
951 mmTHM_TCON_CUR_TMP_BASE_IDX, mmTHM_TCON_CUR_TMP); 1063 uint32_t reg_value = RREG32_SOC15(THM, 0, mmTHM_TCON_CUR_TMP);
952 uint32_t reg_value = cgs_read_register(hwmgr->device, reg_offset);
953 int cur_temp = 1064 int cur_temp =
954 (reg_value & THM_TCON_CUR_TMP__CUR_TEMP_MASK) >> THM_TCON_CUR_TMP__CUR_TEMP__SHIFT; 1065 (reg_value & THM_TCON_CUR_TMP__CUR_TEMP_MASK) >> THM_TCON_CUR_TMP__CUR_TEMP__SHIFT;
955 1066
@@ -993,11 +1104,47 @@ static int smu10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
993 return ret; 1104 return ret;
994} 1105}
995 1106
1107static int smu10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr,
1108 struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges)
1109{
1110 struct smu10_hwmgr *data = hwmgr->backend;
1111 Watermarks_t *table = &(data->water_marks_table);
1112 int result = 0;
1113
1114 smu_set_watermarks_for_clocks_ranges(table,wm_with_clock_ranges);
1115 smum_smc_table_manager(hwmgr, (uint8_t *)table, (uint16_t)SMU10_WMTABLE, false);
1116 data->water_marks_exist = true;
1117 return result;
1118}
1119
1120static int smu10_smus_notify_pwe(struct pp_hwmgr *hwmgr)
1121{
1122
1123 return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SetRccPfcPmeRestoreRegister);
1124}
1125
996static int smu10_set_mmhub_powergating_by_smu(struct pp_hwmgr *hwmgr) 1126static int smu10_set_mmhub_powergating_by_smu(struct pp_hwmgr *hwmgr)
997{ 1127{
998 return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerGateMmHub); 1128 return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerGateMmHub);
999} 1129}
1000 1130
1131static void smu10_powergate_vcn(struct pp_hwmgr *hwmgr, bool bgate)
1132{
1133 if (bgate) {
1134 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
1135 AMD_IP_BLOCK_TYPE_VCN,
1136 AMD_PG_STATE_GATE);
1137 smum_send_msg_to_smc_with_parameter(hwmgr,
1138 PPSMC_MSG_PowerDownVcn, 0);
1139 } else {
1140 smum_send_msg_to_smc_with_parameter(hwmgr,
1141 PPSMC_MSG_PowerUpVcn, 0);
1142 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
1143 AMD_IP_BLOCK_TYPE_VCN,
1144 AMD_PG_STATE_UNGATE);
1145 }
1146}
1147
1001static const struct pp_hwmgr_func smu10_hwmgr_funcs = { 1148static const struct pp_hwmgr_func smu10_hwmgr_funcs = {
1002 .backend_init = smu10_hwmgr_backend_init, 1149 .backend_init = smu10_hwmgr_backend_init,
1003 .backend_fini = smu10_hwmgr_backend_fini, 1150 .backend_fini = smu10_hwmgr_backend_fini,
@@ -1006,7 +1153,7 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = {
1006 .force_dpm_level = smu10_dpm_force_dpm_level, 1153 .force_dpm_level = smu10_dpm_force_dpm_level,
1007 .get_power_state_size = smu10_get_power_state_size, 1154 .get_power_state_size = smu10_get_power_state_size,
1008 .powerdown_uvd = NULL, 1155 .powerdown_uvd = NULL,
1009 .powergate_uvd = NULL, 1156 .powergate_uvd = smu10_powergate_vcn,
1010 .powergate_vce = NULL, 1157 .powergate_vce = NULL,
1011 .get_mclk = smu10_dpm_get_mclk, 1158 .get_mclk = smu10_dpm_get_mclk,
1012 .get_sclk = smu10_dpm_get_sclk, 1159 .get_sclk = smu10_dpm_get_sclk,
@@ -1022,6 +1169,7 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = {
1022 .get_current_shallow_sleep_clocks = smu10_get_current_shallow_sleep_clocks, 1169 .get_current_shallow_sleep_clocks = smu10_get_current_shallow_sleep_clocks,
1023 .get_clock_by_type_with_latency = smu10_get_clock_by_type_with_latency, 1170 .get_clock_by_type_with_latency = smu10_get_clock_by_type_with_latency,
1024 .get_clock_by_type_with_voltage = smu10_get_clock_by_type_with_voltage, 1171 .get_clock_by_type_with_voltage = smu10_get_clock_by_type_with_voltage,
1172 .set_watermarks_for_clocks_ranges = smu10_set_watermarks_for_clocks_ranges,
1025 .get_max_high_clocks = smu10_get_max_high_clocks, 1173 .get_max_high_clocks = smu10_get_max_high_clocks,
1026 .read_sensor = smu10_read_sensor, 1174 .read_sensor = smu10_read_sensor,
1027 .set_active_display_count = smu10_set_active_display_count, 1175 .set_active_display_count = smu10_set_active_display_count,
@@ -1032,6 +1180,8 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = {
1032 .power_state_set = smu10_set_power_state_tasks, 1180 .power_state_set = smu10_set_power_state_tasks,
1033 .dynamic_state_management_disable = smu10_disable_dpm_tasks, 1181 .dynamic_state_management_disable = smu10_disable_dpm_tasks,
1034 .set_mmhub_powergating_by_smu = smu10_set_mmhub_powergating_by_smu, 1182 .set_mmhub_powergating_by_smu = smu10_set_mmhub_powergating_by_smu,
1183 .smus_notify_pwe = smu10_smus_notify_pwe,
1184 .gfx_off_control = smu10_gfx_off_control,
1035}; 1185};
1036 1186
1037int smu10_init_function_pointers(struct pp_hwmgr *hwmgr) 1187int smu10_init_function_pointers(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.h
index 175c3a592b6c..1fb296a996f3 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.h
@@ -290,6 +290,7 @@ struct smu10_hwmgr {
290 bool vcn_dpg_mode; 290 bool vcn_dpg_mode;
291 291
292 bool gfx_off_controled_by_driver; 292 bool gfx_off_controled_by_driver;
293 bool water_marks_exist;
293 Watermarks_t water_marks_table; 294 Watermarks_t water_marks_table;
294 struct smu10_clock_voltage_information clock_vol_info; 295 struct smu10_clock_voltage_information clock_vol_info;
295 DpmClocks_t clock_table; 296 DpmClocks_t clock_table;
@@ -310,11 +311,9 @@ int smu10_init_function_pointers(struct pp_hwmgr *hwmgr);
310#define SMU10_UMD_PSTATE_FCLK 933 311#define SMU10_UMD_PSTATE_FCLK 933
311#define SMU10_UMD_PSTATE_VCE 0x03C00320 312#define SMU10_UMD_PSTATE_VCE 0x03C00320
312 313
313#define SMU10_UMD_PSTATE_PEAK_GFXCLK 1100
314#define SMU10_UMD_PSTATE_PEAK_SOCCLK 757 314#define SMU10_UMD_PSTATE_PEAK_SOCCLK 757
315#define SMU10_UMD_PSTATE_PEAK_FCLK 1200 315#define SMU10_UMD_PSTATE_PEAK_FCLK 1200
316 316
317#define SMU10_UMD_PSTATE_MIN_GFXCLK 200
318#define SMU10_UMD_PSTATE_MIN_FCLK 400 317#define SMU10_UMD_PSTATE_MIN_FCLK 400
319#define SMU10_UMD_PSTATE_MIN_SOCCLK 200 318#define SMU10_UMD_PSTATE_MIN_SOCCLK 200
320#define SMU10_UMD_PSTATE_MIN_VCE 0x0190012C 319#define SMU10_UMD_PSTATE_MIN_VCE 0x0190012C
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c
index f4cbaee4e2ca..6d72a5600917 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c
@@ -147,20 +147,20 @@ void smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
147 data->uvd_power_gated = bgate; 147 data->uvd_power_gated = bgate;
148 148
149 if (bgate) { 149 if (bgate) {
150 cgs_set_powergating_state(hwmgr->device, 150 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
151 AMD_IP_BLOCK_TYPE_UVD, 151 AMD_IP_BLOCK_TYPE_UVD,
152 AMD_PG_STATE_GATE); 152 AMD_PG_STATE_GATE);
153 cgs_set_clockgating_state(hwmgr->device, 153 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
154 AMD_IP_BLOCK_TYPE_UVD, 154 AMD_IP_BLOCK_TYPE_UVD,
155 AMD_CG_STATE_GATE); 155 AMD_CG_STATE_GATE);
156 smu7_update_uvd_dpm(hwmgr, true); 156 smu7_update_uvd_dpm(hwmgr, true);
157 smu7_powerdown_uvd(hwmgr); 157 smu7_powerdown_uvd(hwmgr);
158 } else { 158 } else {
159 smu7_powerup_uvd(hwmgr); 159 smu7_powerup_uvd(hwmgr);
160 cgs_set_clockgating_state(hwmgr->device, 160 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
161 AMD_IP_BLOCK_TYPE_UVD, 161 AMD_IP_BLOCK_TYPE_UVD,
162 AMD_CG_STATE_UNGATE); 162 AMD_CG_STATE_UNGATE);
163 cgs_set_powergating_state(hwmgr->device, 163 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
164 AMD_IP_BLOCK_TYPE_UVD, 164 AMD_IP_BLOCK_TYPE_UVD,
165 AMD_PG_STATE_UNGATE); 165 AMD_PG_STATE_UNGATE);
166 smu7_update_uvd_dpm(hwmgr, false); 166 smu7_update_uvd_dpm(hwmgr, false);
@@ -175,20 +175,20 @@ void smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
175 data->vce_power_gated = bgate; 175 data->vce_power_gated = bgate;
176 176
177 if (bgate) { 177 if (bgate) {
178 cgs_set_powergating_state(hwmgr->device, 178 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
179 AMD_IP_BLOCK_TYPE_VCE, 179 AMD_IP_BLOCK_TYPE_VCE,
180 AMD_PG_STATE_GATE); 180 AMD_PG_STATE_GATE);
181 cgs_set_clockgating_state(hwmgr->device, 181 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
182 AMD_IP_BLOCK_TYPE_VCE, 182 AMD_IP_BLOCK_TYPE_VCE,
183 AMD_CG_STATE_GATE); 183 AMD_CG_STATE_GATE);
184 smu7_update_vce_dpm(hwmgr, true); 184 smu7_update_vce_dpm(hwmgr, true);
185 smu7_powerdown_vce(hwmgr); 185 smu7_powerdown_vce(hwmgr);
186 } else { 186 } else {
187 smu7_powerup_vce(hwmgr); 187 smu7_powerup_vce(hwmgr);
188 cgs_set_clockgating_state(hwmgr->device, 188 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
189 AMD_IP_BLOCK_TYPE_VCE, 189 AMD_IP_BLOCK_TYPE_VCE,
190 AMD_CG_STATE_UNGATE); 190 AMD_CG_STATE_UNGATE);
191 cgs_set_powergating_state(hwmgr->device, 191 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
192 AMD_IP_BLOCK_TYPE_VCE, 192 AMD_IP_BLOCK_TYPE_VCE,
193 AMD_PG_STATE_UNGATE); 193 AMD_PG_STATE_UNGATE);
194 smu7_update_vce_dpm(hwmgr, false); 194 smu7_update_vce_dpm(hwmgr, false);
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 18b5b2ff47fe..45e9b8cb169d 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -61,10 +61,6 @@
61#define SMC_CG_IND_START 0xc0030000 61#define SMC_CG_IND_START 0xc0030000
62#define SMC_CG_IND_END 0xc0040000 62#define SMC_CG_IND_END 0xc0040000
63 63
64#define VOLTAGE_SCALE 4
65#define VOLTAGE_VID_OFFSET_SCALE1 625
66#define VOLTAGE_VID_OFFSET_SCALE2 100
67
68#define MEM_FREQ_LOW_LATENCY 25000 64#define MEM_FREQ_LOW_LATENCY 25000
69#define MEM_FREQ_HIGH_LATENCY 80000 65#define MEM_FREQ_HIGH_LATENCY 80000
70 66
@@ -88,6 +84,14 @@ static const struct profile_mode_setting smu7_profiling[6] =
88 {0, 0, 0, 0, 0, 0, 0, 0}, 84 {0, 0, 0, 0, 0, 0, 0, 0},
89 }; 85 };
90 86
87#define PPSMC_MSG_SetVBITimeout_VEGAM ((uint16_t) 0x310)
88
89#define ixPWR_SVI2_PLANE1_LOAD 0xC0200280
90#define PWR_SVI2_PLANE1_LOAD__PSI1_MASK 0x00000020L
91#define PWR_SVI2_PLANE1_LOAD__PSI0_EN_MASK 0x00000040L
92#define PWR_SVI2_PLANE1_LOAD__PSI1__SHIFT 0x00000005
93#define PWR_SVI2_PLANE1_LOAD__PSI0_EN__SHIFT 0x00000006
94
91/** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */ 95/** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */
92enum DPM_EVENT_SRC { 96enum DPM_EVENT_SRC {
93 DPM_EVENT_SRC_ANALOG = 0, 97 DPM_EVENT_SRC_ANALOG = 0,
@@ -169,6 +173,13 @@ static int smu7_get_current_pcie_lane_number(struct pp_hwmgr *hwmgr)
169*/ 173*/
170static int smu7_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr) 174static int smu7_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr)
171{ 175{
176 if (hwmgr->chip_id == CHIP_VEGAM) {
177 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device,
178 CGS_IND_REG__SMC, PWR_SVI2_PLANE1_LOAD, PSI1, 0);
179 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device,
180 CGS_IND_REG__SMC, PWR_SVI2_PLANE1_LOAD, PSI0_EN, 0);
181 }
182
172 if (hwmgr->feature_mask & PP_SMC_VOLTAGE_CONTROL_MASK) 183 if (hwmgr->feature_mask & PP_SMC_VOLTAGE_CONTROL_MASK)
173 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Voltage_Cntl_Enable); 184 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Voltage_Cntl_Enable);
174 185
@@ -798,32 +809,6 @@ static int smu7_setup_dpm_tables_v1(struct pp_hwmgr *hwmgr)
798 return 0; 809 return 0;
799} 810}
800 811
801static int smu7_get_voltage_dependency_table(
802 const struct phm_ppt_v1_clock_voltage_dependency_table *allowed_dep_table,
803 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table)
804{
805 uint8_t i = 0;
806 PP_ASSERT_WITH_CODE((0 != allowed_dep_table->count),
807 "Voltage Lookup Table empty",
808 return -EINVAL);
809
810 dep_table->count = allowed_dep_table->count;
811 for (i=0; i<dep_table->count; i++) {
812 dep_table->entries[i].clk = allowed_dep_table->entries[i].clk;
813 dep_table->entries[i].vddInd = allowed_dep_table->entries[i].vddInd;
814 dep_table->entries[i].vdd_offset = allowed_dep_table->entries[i].vdd_offset;
815 dep_table->entries[i].vddc = allowed_dep_table->entries[i].vddc;
816 dep_table->entries[i].vddgfx = allowed_dep_table->entries[i].vddgfx;
817 dep_table->entries[i].vddci = allowed_dep_table->entries[i].vddci;
818 dep_table->entries[i].mvdd = allowed_dep_table->entries[i].mvdd;
819 dep_table->entries[i].phases = allowed_dep_table->entries[i].phases;
820 dep_table->entries[i].cks_enable = allowed_dep_table->entries[i].cks_enable;
821 dep_table->entries[i].cks_voffset = allowed_dep_table->entries[i].cks_voffset;
822 }
823
824 return 0;
825}
826
827static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr) 812static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
828{ 813{
829 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 814 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
@@ -851,7 +836,7 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
851 entries[i].vddc = dep_sclk_table->entries[i].vddc; 836 entries[i].vddc = dep_sclk_table->entries[i].vddc;
852 } 837 }
853 838
854 smu7_get_voltage_dependency_table(dep_sclk_table, 839 smu_get_voltage_dependency_table_ppt_v1(dep_sclk_table,
855 (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk)); 840 (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk));
856 841
857 odn_table->odn_memory_clock_dpm_levels.num_of_pl = 842 odn_table->odn_memory_clock_dpm_levels.num_of_pl =
@@ -863,12 +848,40 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
863 entries[i].vddc = dep_mclk_table->entries[i].vddc; 848 entries[i].vddc = dep_mclk_table->entries[i].vddc;
864 } 849 }
865 850
866 smu7_get_voltage_dependency_table(dep_mclk_table, 851 smu_get_voltage_dependency_table_ppt_v1(dep_mclk_table,
867 (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_mclk)); 852 (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_mclk));
868 853
869 return 0; 854 return 0;
870} 855}
871 856
857static void smu7_setup_voltage_range_from_vbios(struct pp_hwmgr *hwmgr)
858{
859 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
860 struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;
861 struct phm_ppt_v1_information *table_info =
862 (struct phm_ppt_v1_information *)(hwmgr->pptable);
863 uint32_t min_vddc = 0;
864 uint32_t max_vddc = 0;
865
866 if (!table_info)
867 return;
868
869 dep_sclk_table = table_info->vdd_dep_on_sclk;
870
871 atomctrl_get_voltage_range(hwmgr, &max_vddc, &min_vddc);
872
873 if (min_vddc == 0 || min_vddc > 2000
874 || min_vddc > dep_sclk_table->entries[0].vddc)
875 min_vddc = dep_sclk_table->entries[0].vddc;
876
877 if (max_vddc == 0 || max_vddc > 2000
878 || max_vddc < dep_sclk_table->entries[dep_sclk_table->count-1].vddc)
879 max_vddc = dep_sclk_table->entries[dep_sclk_table->count-1].vddc;
880
881 data->odn_dpm_table.min_vddc = min_vddc;
882 data->odn_dpm_table.max_vddc = max_vddc;
883}
884
872static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) 885static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
873{ 886{
874 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 887 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
@@ -887,8 +900,10 @@ static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
887 sizeof(struct smu7_dpm_table)); 900 sizeof(struct smu7_dpm_table));
888 901
889 /* initialize ODN table */ 902 /* initialize ODN table */
890 if (hwmgr->od_enabled) 903 if (hwmgr->od_enabled) {
904 smu7_setup_voltage_range_from_vbios(hwmgr);
891 smu7_odn_initial_default_setting(hwmgr); 905 smu7_odn_initial_default_setting(hwmgr);
906 }
892 907
893 return 0; 908 return 0;
894} 909}
@@ -966,6 +981,22 @@ static int smu7_disable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
966 return 0; 981 return 0;
967} 982}
968 983
984static int smu7_disable_sclk_vce_handshake(struct pp_hwmgr *hwmgr)
985{
986 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
987 uint32_t soft_register_value = 0;
988 uint32_t handshake_disables_offset = data->soft_regs_start
989 + smum_get_offsetof(hwmgr,
990 SMU_SoftRegisters, HandshakeDisables);
991
992 soft_register_value = cgs_read_ind_register(hwmgr->device,
993 CGS_IND_REG__SMC, handshake_disables_offset);
994 soft_register_value |= SMU7_VCE_SCLK_HANDSHAKE_DISABLE;
995 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
996 handshake_disables_offset, soft_register_value);
997 return 0;
998}
999
969static int smu7_disable_handshake_uvd(struct pp_hwmgr *hwmgr) 1000static int smu7_disable_handshake_uvd(struct pp_hwmgr *hwmgr)
970{ 1001{
971 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 1002 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
@@ -988,23 +1019,29 @@ static int smu7_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
988 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 1019 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
989 1020
990 /* enable SCLK dpm */ 1021 /* enable SCLK dpm */
991 if (!data->sclk_dpm_key_disabled) 1022 if (!data->sclk_dpm_key_disabled) {
1023 if (hwmgr->chip_id == CHIP_VEGAM)
1024 smu7_disable_sclk_vce_handshake(hwmgr);
1025
992 PP_ASSERT_WITH_CODE( 1026 PP_ASSERT_WITH_CODE(
993 (0 == smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DPM_Enable)), 1027 (0 == smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DPM_Enable)),
994 "Failed to enable SCLK DPM during DPM Start Function!", 1028 "Failed to enable SCLK DPM during DPM Start Function!",
995 return -EINVAL); 1029 return -EINVAL);
1030 }
996 1031
997 /* enable MCLK dpm */ 1032 /* enable MCLK dpm */
998 if (0 == data->mclk_dpm_key_disabled) { 1033 if (0 == data->mclk_dpm_key_disabled) {
999 if (!(hwmgr->feature_mask & PP_UVD_HANDSHAKE_MASK)) 1034 if (!(hwmgr->feature_mask & PP_UVD_HANDSHAKE_MASK))
1000 smu7_disable_handshake_uvd(hwmgr); 1035 smu7_disable_handshake_uvd(hwmgr);
1036
1001 PP_ASSERT_WITH_CODE( 1037 PP_ASSERT_WITH_CODE(
1002 (0 == smum_send_msg_to_smc(hwmgr, 1038 (0 == smum_send_msg_to_smc(hwmgr,
1003 PPSMC_MSG_MCLKDPM_Enable)), 1039 PPSMC_MSG_MCLKDPM_Enable)),
1004 "Failed to enable MCLK DPM during DPM Start Function!", 1040 "Failed to enable MCLK DPM during DPM Start Function!",
1005 return -EINVAL); 1041 return -EINVAL);
1006 1042
1007 PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1); 1043 if (hwmgr->chip_family != CHIP_VEGAM)
1044 PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1);
1008 1045
1009 1046
1010 if (hwmgr->chip_family == AMDGPU_FAMILY_CI) { 1047 if (hwmgr->chip_family == AMDGPU_FAMILY_CI) {
@@ -1020,8 +1057,13 @@ static int smu7_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
1020 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC1_CNTL, 0x5); 1057 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC1_CNTL, 0x5);
1021 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_CPL_CNTL, 0x100005); 1058 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_CPL_CNTL, 0x100005);
1022 udelay(10); 1059 udelay(10);
1023 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC0_CNTL, 0x400005); 1060 if (hwmgr->chip_id == CHIP_VEGAM) {
1024 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC1_CNTL, 0x400005); 1061 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC0_CNTL, 0x400009);
1062 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC1_CNTL, 0x400009);
1063 } else {
1064 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC0_CNTL, 0x400005);
1065 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC1_CNTL, 0x400005);
1066 }
1025 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_CPL_CNTL, 0x500005); 1067 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_CPL_CNTL, 0x500005);
1026 } 1068 }
1027 } 1069 }
@@ -1230,7 +1272,7 @@ static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
1230 1272
1231 tmp_result = smu7_construct_voltage_tables(hwmgr); 1273 tmp_result = smu7_construct_voltage_tables(hwmgr);
1232 PP_ASSERT_WITH_CODE((0 == tmp_result), 1274 PP_ASSERT_WITH_CODE((0 == tmp_result),
1233 "Failed to contruct voltage tables!", 1275 "Failed to construct voltage tables!",
1234 result = tmp_result); 1276 result = tmp_result);
1235 } 1277 }
1236 smum_initialize_mc_reg_table(hwmgr); 1278 smum_initialize_mc_reg_table(hwmgr);
@@ -1262,10 +1304,12 @@ static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
1262 PP_ASSERT_WITH_CODE((0 == tmp_result), 1304 PP_ASSERT_WITH_CODE((0 == tmp_result),
1263 "Failed to process firmware header!", result = tmp_result); 1305 "Failed to process firmware header!", result = tmp_result);
1264 1306
1265 tmp_result = smu7_initial_switch_from_arbf0_to_f1(hwmgr); 1307 if (hwmgr->chip_id != CHIP_VEGAM) {
1266 PP_ASSERT_WITH_CODE((0 == tmp_result), 1308 tmp_result = smu7_initial_switch_from_arbf0_to_f1(hwmgr);
1267 "Failed to initialize switch from ArbF0 to F1!", 1309 PP_ASSERT_WITH_CODE((0 == tmp_result),
1268 result = tmp_result); 1310 "Failed to initialize switch from ArbF0 to F1!",
1311 result = tmp_result);
1312 }
1269 1313
1270 result = smu7_setup_default_dpm_tables(hwmgr); 1314 result = smu7_setup_default_dpm_tables(hwmgr);
1271 PP_ASSERT_WITH_CODE(0 == result, 1315 PP_ASSERT_WITH_CODE(0 == result,
@@ -2755,6 +2799,9 @@ static int smu7_vblank_too_short(struct pp_hwmgr *hwmgr,
2755 case CHIP_POLARIS12: 2799 case CHIP_POLARIS12:
2756 switch_limit_us = data->is_memory_gddr5 ? 190 : 150; 2800 switch_limit_us = data->is_memory_gddr5 ? 190 : 150;
2757 break; 2801 break;
2802 case CHIP_VEGAM:
2803 switch_limit_us = 30;
2804 break;
2758 default: 2805 default:
2759 switch_limit_us = data->is_memory_gddr5 ? 450 : 150; 2806 switch_limit_us = data->is_memory_gddr5 ? 450 : 150;
2760 break; 2807 break;
@@ -2778,8 +2825,6 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
2778 struct PP_Clocks minimum_clocks = {0}; 2825 struct PP_Clocks minimum_clocks = {0};
2779 bool disable_mclk_switching; 2826 bool disable_mclk_switching;
2780 bool disable_mclk_switching_for_frame_lock; 2827 bool disable_mclk_switching_for_frame_lock;
2781 struct cgs_display_info info = {0};
2782 struct cgs_mode_info mode_info = {0};
2783 const struct phm_clock_and_voltage_limits *max_limits; 2828 const struct phm_clock_and_voltage_limits *max_limits;
2784 uint32_t i; 2829 uint32_t i;
2785 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 2830 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
@@ -2788,7 +2833,6 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
2788 int32_t count; 2833 int32_t count;
2789 int32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; 2834 int32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0;
2790 2835
2791 info.mode_info = &mode_info;
2792 data->battery_state = (PP_StateUILabel_Battery == 2836 data->battery_state = (PP_StateUILabel_Battery ==
2793 request_ps->classification.ui_label); 2837 request_ps->classification.ui_label);
2794 2838
@@ -2810,10 +2854,8 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
2810 } 2854 }
2811 } 2855 }
2812 2856
2813 cgs_get_active_displays_info(hwmgr->device, &info); 2857 minimum_clocks.engineClock = hwmgr->display_config->min_core_set_clock;
2814 2858 minimum_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock;
2815 minimum_clocks.engineClock = hwmgr->display_config.min_core_set_clock;
2816 minimum_clocks.memoryClock = hwmgr->display_config.min_mem_set_clock;
2817 2859
2818 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 2860 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2819 PHM_PlatformCaps_StablePState)) { 2861 PHM_PlatformCaps_StablePState)) {
@@ -2844,12 +2886,12 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
2844 PHM_PlatformCaps_DisableMclkSwitchingForFrameLock); 2886 PHM_PlatformCaps_DisableMclkSwitchingForFrameLock);
2845 2887
2846 2888
2847 if (info.display_count == 0) 2889 if (hwmgr->display_config->num_display == 0)
2848 disable_mclk_switching = false; 2890 disable_mclk_switching = false;
2849 else 2891 else
2850 disable_mclk_switching = ((1 < info.display_count) || 2892 disable_mclk_switching = ((1 < hwmgr->display_config->num_display) ||
2851 disable_mclk_switching_for_frame_lock || 2893 disable_mclk_switching_for_frame_lock ||
2852 smu7_vblank_too_short(hwmgr, mode_info.vblank_time_us)); 2894 smu7_vblank_too_short(hwmgr, hwmgr->display_config->min_vblank_time));
2853 2895
2854 sclk = smu7_ps->performance_levels[0].engine_clock; 2896 sclk = smu7_ps->performance_levels[0].engine_clock;
2855 mclk = smu7_ps->performance_levels[0].memory_clock; 2897 mclk = smu7_ps->performance_levels[0].memory_clock;
@@ -2958,8 +3000,7 @@ static int smu7_dpm_patch_boot_state(struct pp_hwmgr *hwmgr,
2958 /* First retrieve the Boot clocks and VDDC from the firmware info table. 3000 /* First retrieve the Boot clocks and VDDC from the firmware info table.
2959 * We assume here that fw_info is unchanged if this call fails. 3001 * We assume here that fw_info is unchanged if this call fails.
2960 */ 3002 */
2961 fw_info = (ATOM_FIRMWARE_INFO_V2_2 *)cgs_atom_get_data_table( 3003 fw_info = (ATOM_FIRMWARE_INFO_V2_2 *)smu_atom_get_data_table(hwmgr->adev, index,
2962 hwmgr->device, index,
2963 &size, &frev, &crev); 3004 &size, &frev, &crev);
2964 if (!fw_info) 3005 if (!fw_info)
2965 /* During a test, there is no firmware info table. */ 3006 /* During a test, there is no firmware info table. */
@@ -3367,34 +3408,35 @@ static int smu7_get_pp_table_entry(struct pp_hwmgr *hwmgr,
3367 return 0; 3408 return 0;
3368} 3409}
3369 3410
3370static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, 3411static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, u32 *query)
3371 struct pp_gpu_power *query)
3372{ 3412{
3373 PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr, 3413 int i;
3374 PPSMC_MSG_PmStatusLogStart), 3414 u32 tmp = 0;
3375 "Failed to start pm status log!", 3415
3376 return -1); 3416 if (!query)
3417 return -EINVAL;
3377 3418
3378 /* Sampling period from 50ms to 4sec */ 3419 smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetCurrPkgPwr, 0);
3379 msleep_interruptible(200); 3420 tmp = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
3421 *query = tmp;
3380 3422
3381 PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr, 3423 if (tmp != 0)
3382 PPSMC_MSG_PmStatusLogSample), 3424 return 0;
3383 "Failed to sample pm status log!",
3384 return -1);
3385 3425
3386 query->vddc_power = cgs_read_ind_register(hwmgr->device, 3426 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogStart);
3387 CGS_IND_REG__SMC, 3427 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
3388 ixSMU_PM_STATUS_40); 3428 ixSMU_PM_STATUS_94, 0);
3389 query->vddci_power = cgs_read_ind_register(hwmgr->device, 3429
3390 CGS_IND_REG__SMC, 3430 for (i = 0; i < 10; i++) {
3391 ixSMU_PM_STATUS_49); 3431 mdelay(1);
3392 query->max_gpu_power = cgs_read_ind_register(hwmgr->device, 3432 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogSample);
3393 CGS_IND_REG__SMC, 3433 tmp = cgs_read_ind_register(hwmgr->device,
3394 ixSMU_PM_STATUS_94); 3434 CGS_IND_REG__SMC,
3395 query->average_gpu_power = cgs_read_ind_register(hwmgr->device, 3435 ixSMU_PM_STATUS_94);
3396 CGS_IND_REG__SMC, 3436 if (tmp != 0)
3397 ixSMU_PM_STATUS_95); 3437 break;
3438 }
3439 *query = tmp;
3398 3440
3399 return 0; 3441 return 0;
3400} 3442}
@@ -3447,10 +3489,7 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx,
3447 *size = 4; 3489 *size = 4;
3448 return 0; 3490 return 0;
3449 case AMDGPU_PP_SENSOR_GPU_POWER: 3491 case AMDGPU_PP_SENSOR_GPU_POWER:
3450 if (*size < sizeof(struct pp_gpu_power)) 3492 return smu7_get_gpu_power(hwmgr, (uint32_t *)value);
3451 return -EINVAL;
3452 *size = sizeof(struct pp_gpu_power);
3453 return smu7_get_gpu_power(hwmgr, (struct pp_gpu_power *)value);
3454 case AMDGPU_PP_SENSOR_VDDGFX: 3493 case AMDGPU_PP_SENSOR_VDDGFX:
3455 if ((data->vr_config & 0xff) == 0x2) 3494 if ((data->vr_config & 0xff) == 0x2)
3456 val_vid = PHM_READ_INDIRECT_FIELD(hwmgr->device, 3495 val_vid = PHM_READ_INDIRECT_FIELD(hwmgr->device,
@@ -3481,7 +3520,6 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons
3481 [smu7_ps->performance_level_count - 1].memory_clock; 3520 [smu7_ps->performance_level_count - 1].memory_clock;
3482 struct PP_Clocks min_clocks = {0}; 3521 struct PP_Clocks min_clocks = {0};
3483 uint32_t i; 3522 uint32_t i;
3484 struct cgs_display_info info = {0};
3485 3523
3486 for (i = 0; i < sclk_table->count; i++) { 3524 for (i = 0; i < sclk_table->count; i++) {
3487 if (sclk == sclk_table->dpm_levels[i].value) 3525 if (sclk == sclk_table->dpm_levels[i].value)
@@ -3508,9 +3546,8 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons
3508 if (i >= mclk_table->count) 3546 if (i >= mclk_table->count)
3509 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; 3547 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
3510 3548
3511 cgs_get_active_displays_info(hwmgr->device, &info);
3512 3549
3513 if (data->display_timing.num_existing_displays != info.display_count) 3550 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
3514 data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK; 3551 data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK;
3515 3552
3516 return 0; 3553 return 0;
@@ -3813,9 +3850,14 @@ static int smu7_notify_smc_display(struct pp_hwmgr *hwmgr)
3813{ 3850{
3814 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 3851 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
3815 3852
3816 if (hwmgr->feature_mask & PP_VBI_TIME_SUPPORT_MASK) 3853 if (hwmgr->feature_mask & PP_VBI_TIME_SUPPORT_MASK) {
3817 smum_send_msg_to_smc_with_parameter(hwmgr, 3854 if (hwmgr->chip_id == CHIP_VEGAM)
3818 (PPSMC_Msg)PPSMC_MSG_SetVBITimeout, data->frame_time_x2); 3855 smum_send_msg_to_smc_with_parameter(hwmgr,
3856 (PPSMC_Msg)PPSMC_MSG_SetVBITimeout_VEGAM, data->frame_time_x2);
3857 else
3858 smum_send_msg_to_smc_with_parameter(hwmgr,
3859 (PPSMC_Msg)PPSMC_MSG_SetVBITimeout, data->frame_time_x2);
3860 }
3819 return (smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_HasDisplay) == 0) ? 0 : -EINVAL; 3861 return (smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_HasDisplay) == 0) ? 0 : -EINVAL;
3820} 3862}
3821 3863
@@ -3909,15 +3951,8 @@ smu7_notify_smc_display_change(struct pp_hwmgr *hwmgr, bool has_display)
3909static int 3951static int
3910smu7_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr) 3952smu7_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr)
3911{ 3953{
3912 uint32_t num_active_displays = 0; 3954 if (hwmgr->display_config->num_display > 1 &&
3913 struct cgs_display_info info = {0}; 3955 !hwmgr->display_config->multi_monitor_in_sync)
3914
3915 info.mode_info = NULL;
3916 cgs_get_active_displays_info(hwmgr->device, &info);
3917
3918 num_active_displays = info.display_count;
3919
3920 if (num_active_displays > 1 && hwmgr->display_config.multi_monitor_in_sync != true)
3921 smu7_notify_smc_display_change(hwmgr, false); 3956 smu7_notify_smc_display_change(hwmgr, false);
3922 3957
3923 return 0; 3958 return 0;
@@ -3932,33 +3967,24 @@ smu7_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr)
3932static int smu7_program_display_gap(struct pp_hwmgr *hwmgr) 3967static int smu7_program_display_gap(struct pp_hwmgr *hwmgr)
3933{ 3968{
3934 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 3969 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
3935 uint32_t num_active_displays = 0;
3936 uint32_t display_gap = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL); 3970 uint32_t display_gap = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL);
3937 uint32_t display_gap2; 3971 uint32_t display_gap2;
3938 uint32_t pre_vbi_time_in_us; 3972 uint32_t pre_vbi_time_in_us;
3939 uint32_t frame_time_in_us; 3973 uint32_t frame_time_in_us;
3940 uint32_t ref_clock; 3974 uint32_t ref_clock, refresh_rate;
3941 uint32_t refresh_rate = 0;
3942 struct cgs_display_info info = {0};
3943 struct cgs_mode_info mode_info = {0};
3944 3975
3945 info.mode_info = &mode_info; 3976 display_gap = PHM_SET_FIELD(display_gap, CG_DISPLAY_GAP_CNTL, DISP_GAP, (hwmgr->display_config->num_display > 0) ? DISPLAY_GAP_VBLANK_OR_WM : DISPLAY_GAP_IGNORE);
3946 cgs_get_active_displays_info(hwmgr->device, &info);
3947 num_active_displays = info.display_count;
3948
3949 display_gap = PHM_SET_FIELD(display_gap, CG_DISPLAY_GAP_CNTL, DISP_GAP, (num_active_displays > 0) ? DISPLAY_GAP_VBLANK_OR_WM : DISPLAY_GAP_IGNORE);
3950 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL, display_gap); 3977 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL, display_gap);
3951 3978
3952 ref_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev); 3979 ref_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
3953 3980 refresh_rate = hwmgr->display_config->vrefresh;
3954 refresh_rate = mode_info.refresh_rate;
3955 3981
3956 if (0 == refresh_rate) 3982 if (0 == refresh_rate)
3957 refresh_rate = 60; 3983 refresh_rate = 60;
3958 3984
3959 frame_time_in_us = 1000000 / refresh_rate; 3985 frame_time_in_us = 1000000 / refresh_rate;
3960 3986
3961 pre_vbi_time_in_us = frame_time_in_us - 200 - mode_info.vblank_time_us; 3987 pre_vbi_time_in_us = frame_time_in_us - 200 - hwmgr->display_config->min_vblank_time;
3962 3988
3963 data->frame_time_x2 = frame_time_in_us * 2 / 100; 3989 data->frame_time_x2 = frame_time_in_us * 2 / 100;
3964 3990
@@ -4038,17 +4064,14 @@ smu7_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
4038{ 4064{
4039 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 4065 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
4040 bool is_update_required = false; 4066 bool is_update_required = false;
4041 struct cgs_display_info info = {0, 0, NULL};
4042
4043 cgs_get_active_displays_info(hwmgr->device, &info);
4044 4067
4045 if (data->display_timing.num_existing_displays != info.display_count) 4068 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
4046 is_update_required = true; 4069 is_update_required = true;
4047 4070
4048 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) { 4071 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) {
4049 if (data->display_timing.min_clock_in_sr != hwmgr->display_config.min_core_set_clock_in_sr && 4072 if (data->display_timing.min_clock_in_sr != hwmgr->display_config->min_core_set_clock_in_sr &&
4050 (data->display_timing.min_clock_in_sr >= SMU7_MINIMUM_ENGINE_CLOCK || 4073 (data->display_timing.min_clock_in_sr >= SMU7_MINIMUM_ENGINE_CLOCK ||
4051 hwmgr->display_config.min_core_set_clock_in_sr >= SMU7_MINIMUM_ENGINE_CLOCK)) 4074 hwmgr->display_config->min_core_set_clock_in_sr >= SMU7_MINIMUM_ENGINE_CLOCK))
4052 is_update_required = true; 4075 is_update_required = true;
4053 } 4076 }
4054 return is_update_required; 4077 return is_update_required;
@@ -4103,7 +4126,7 @@ static int smu7_check_states_equal(struct pp_hwmgr *hwmgr,
4103 return 0; 4126 return 0;
4104} 4127}
4105 4128
4106static int smu7_upload_mc_firmware(struct pp_hwmgr *hwmgr) 4129static int smu7_check_mc_firmware(struct pp_hwmgr *hwmgr)
4107{ 4130{
4108 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 4131 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
4109 4132
@@ -4182,13 +4205,9 @@ static int smu7_read_clock_registers(struct pp_hwmgr *hwmgr)
4182static int smu7_get_memory_type(struct pp_hwmgr *hwmgr) 4205static int smu7_get_memory_type(struct pp_hwmgr *hwmgr)
4183{ 4206{
4184 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 4207 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
4185 uint32_t temp; 4208 struct amdgpu_device *adev = hwmgr->adev;
4186
4187 temp = cgs_read_register(hwmgr->device, mmMC_SEQ_MISC0);
4188 4209
4189 data->is_memory_gddr5 = (MC_SEQ_MISC0_GDDR5_VALUE == 4210 data->is_memory_gddr5 = (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5);
4190 ((temp & MC_SEQ_MISC0_GDDR5_MASK) >>
4191 MC_SEQ_MISC0_GDDR5_SHIFT));
4192 4211
4193 return 0; 4212 return 0;
4194} 4213}
@@ -4236,7 +4255,7 @@ static int smu7_setup_asic_task(struct pp_hwmgr *hwmgr)
4236{ 4255{
4237 int tmp_result, result = 0; 4256 int tmp_result, result = 0;
4238 4257
4239 smu7_upload_mc_firmware(hwmgr); 4258 smu7_check_mc_firmware(hwmgr);
4240 4259
4241 tmp_result = smu7_read_clock_registers(hwmgr); 4260 tmp_result = smu7_read_clock_registers(hwmgr);
4242 PP_ASSERT_WITH_CODE((0 == tmp_result), 4261 PP_ASSERT_WITH_CODE((0 == tmp_result),
@@ -4371,22 +4390,36 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
4371 break; 4390 break;
4372 case OD_SCLK: 4391 case OD_SCLK:
4373 if (hwmgr->od_enabled) { 4392 if (hwmgr->od_enabled) {
4374 size = sprintf(buf, "%s: \n", "OD_SCLK"); 4393 size = sprintf(buf, "%s:\n", "OD_SCLK");
4375 for (i = 0; i < odn_sclk_table->num_of_pl; i++) 4394 for (i = 0; i < odn_sclk_table->num_of_pl; i++)
4376 size += sprintf(buf + size, "%d: %10uMhz %10u mV\n", 4395 size += sprintf(buf + size, "%d: %10uMHz %10umV\n",
4377 i, odn_sclk_table->entries[i].clock / 100, 4396 i, odn_sclk_table->entries[i].clock/100,
4378 odn_sclk_table->entries[i].vddc); 4397 odn_sclk_table->entries[i].vddc);
4379 } 4398 }
4380 break; 4399 break;
4381 case OD_MCLK: 4400 case OD_MCLK:
4382 if (hwmgr->od_enabled) { 4401 if (hwmgr->od_enabled) {
4383 size = sprintf(buf, "%s: \n", "OD_MCLK"); 4402 size = sprintf(buf, "%s:\n", "OD_MCLK");
4384 for (i = 0; i < odn_mclk_table->num_of_pl; i++) 4403 for (i = 0; i < odn_mclk_table->num_of_pl; i++)
4385 size += sprintf(buf + size, "%d: %10uMhz %10u mV\n", 4404 size += sprintf(buf + size, "%d: %10uMHz %10umV\n",
4386 i, odn_mclk_table->entries[i].clock / 100, 4405 i, odn_mclk_table->entries[i].clock/100,
4387 odn_mclk_table->entries[i].vddc); 4406 odn_mclk_table->entries[i].vddc);
4388 } 4407 }
4389 break; 4408 break;
4409 case OD_RANGE:
4410 if (hwmgr->od_enabled) {
4411 size = sprintf(buf, "%s:\n", "OD_RANGE");
4412 size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
4413 data->golden_dpm_table.sclk_table.dpm_levels[0].value/100,
4414 hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
4415 size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n",
4416 data->golden_dpm_table.mclk_table.dpm_levels[0].value/100,
4417 hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
4418 size += sprintf(buf + size, "VDDC: %7umV %11umV\n",
4419 data->odn_dpm_table.min_vddc,
4420 data->odn_dpm_table.max_vddc);
4421 }
4422 break;
4390 default: 4423 default:
4391 break; 4424 break;
4392 } 4425 }
@@ -4670,36 +4703,27 @@ static bool smu7_check_clk_voltage_valid(struct pp_hwmgr *hwmgr,
4670{ 4703{
4671 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 4704 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
4672 4705
4673 struct phm_ppt_v1_information *table_info = 4706 if (voltage < data->odn_dpm_table.min_vddc || voltage > data->odn_dpm_table.max_vddc) {
4674 (struct phm_ppt_v1_information *)(hwmgr->pptable); 4707 pr_info("OD voltage is out of range [%d - %d] mV\n",
4675 uint32_t min_vddc; 4708 data->odn_dpm_table.min_vddc,
4676 struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table; 4709 data->odn_dpm_table.max_vddc);
4677
4678 if (table_info == NULL)
4679 return false;
4680
4681 dep_sclk_table = table_info->vdd_dep_on_sclk;
4682 min_vddc = dep_sclk_table->entries[0].vddc;
4683
4684 if (voltage < min_vddc || voltage > 2000) {
4685 pr_info("OD voltage is out of range [%d - 2000] mV\n", min_vddc);
4686 return false; 4710 return false;
4687 } 4711 }
4688 4712
4689 if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) { 4713 if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
4690 if (data->vbios_boot_state.sclk_bootup_value > clk || 4714 if (data->golden_dpm_table.sclk_table.dpm_levels[0].value > clk ||
4691 hwmgr->platform_descriptor.overdriveLimit.engineClock < clk) { 4715 hwmgr->platform_descriptor.overdriveLimit.engineClock < clk) {
4692 pr_info("OD engine clock is out of range [%d - %d] MHz\n", 4716 pr_info("OD engine clock is out of range [%d - %d] MHz\n",
4693 data->vbios_boot_state.sclk_bootup_value, 4717 data->golden_dpm_table.sclk_table.dpm_levels[0].value/100,
4694 hwmgr->platform_descriptor.overdriveLimit.engineClock / 100); 4718 hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
4695 return false; 4719 return false;
4696 } 4720 }
4697 } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) { 4721 } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
4698 if (data->vbios_boot_state.mclk_bootup_value > clk || 4722 if (data->golden_dpm_table.mclk_table.dpm_levels[0].value > clk ||
4699 hwmgr->platform_descriptor.overdriveLimit.memoryClock < clk) { 4723 hwmgr->platform_descriptor.overdriveLimit.memoryClock < clk) {
4700 pr_info("OD memory clock is out of range [%d - %d] MHz\n", 4724 pr_info("OD memory clock is out of range [%d - %d] MHz\n",
4701 data->vbios_boot_state.mclk_bootup_value/100, 4725 data->golden_dpm_table.mclk_table.dpm_levels[0].value/100,
4702 hwmgr->platform_descriptor.overdriveLimit.memoryClock / 100); 4726 hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
4703 return false; 4727 return false;
4704 } 4728 }
4705 } else { 4729 } else {
@@ -4748,10 +4772,6 @@ static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)
4748 return; 4772 return;
4749 } 4773 }
4750 } 4774 }
4751 if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
4752 data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
4753 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
4754 }
4755 4775
4756 dep_table = table_info->vdd_dep_on_sclk; 4776 dep_table = table_info->vdd_dep_on_sclk;
4757 odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk); 4777 odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk);
@@ -4761,9 +4781,9 @@ static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)
4761 return; 4781 return;
4762 } 4782 }
4763 } 4783 }
4764 if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) { 4784 if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
4765 data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC; 4785 data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
4766 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; 4786 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK;
4767 } 4787 }
4768} 4788}
4769 4789
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h
index b8d0bb378595..c91e75db6a8e 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h
@@ -184,6 +184,8 @@ struct smu7_odn_dpm_table {
184 struct smu7_odn_clock_voltage_dependency_table vdd_dependency_on_sclk; 184 struct smu7_odn_clock_voltage_dependency_table vdd_dependency_on_sclk;
185 struct smu7_odn_clock_voltage_dependency_table vdd_dependency_on_mclk; 185 struct smu7_odn_clock_voltage_dependency_table vdd_dependency_on_mclk;
186 uint32_t odn_mclk_min_limit; 186 uint32_t odn_mclk_min_limit;
187 uint32_t min_vddc;
188 uint32_t max_vddc;
187}; 189};
188 190
189struct profile_mode_setting { 191struct profile_mode_setting {
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
index d9e92e306535..c952845833d7 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
@@ -623,6 +623,190 @@ static const struct gpu_pt_config_reg DIDTConfig_Polaris11_Kicker[] =
623 { 0xFFFFFFFF } /* End of list */ 623 { 0xFFFFFFFF } /* End of list */
624}; 624};
625 625
626static const struct gpu_pt_config_reg GCCACConfig_VegaM[] =
627{
628// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
629// Offset Mask Shift Value Type
630// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
631 // DIDT_SQ
632 //
633 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x00060013, GPU_CONFIGREG_GC_CAC_IND },
634 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x00860013, GPU_CONFIGREG_GC_CAC_IND },
635 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x01060013, GPU_CONFIGREG_GC_CAC_IND },
636 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x01860013, GPU_CONFIGREG_GC_CAC_IND },
637 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x02060013, GPU_CONFIGREG_GC_CAC_IND },
638 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x02860013, GPU_CONFIGREG_GC_CAC_IND },
639 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x03060013, GPU_CONFIGREG_GC_CAC_IND },
640 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x03860013, GPU_CONFIGREG_GC_CAC_IND },
641 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x04060013, GPU_CONFIGREG_GC_CAC_IND },
642
643 // DIDT_TD
644 //
645 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x000E0013, GPU_CONFIGREG_GC_CAC_IND },
646 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x008E0013, GPU_CONFIGREG_GC_CAC_IND },
647 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x010E0013, GPU_CONFIGREG_GC_CAC_IND },
648 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x018E0013, GPU_CONFIGREG_GC_CAC_IND },
649 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x020E0013, GPU_CONFIGREG_GC_CAC_IND },
650
651 // DIDT_TCP
652 //
653 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x00100013, GPU_CONFIGREG_GC_CAC_IND },
654 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x00900013, GPU_CONFIGREG_GC_CAC_IND },
655 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x01100013, GPU_CONFIGREG_GC_CAC_IND },
656 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x01900013, GPU_CONFIGREG_GC_CAC_IND },
657 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x02100013, GPU_CONFIGREG_GC_CAC_IND },
658 { ixGC_CAC_CNTL, 0xFFFFFFFF, 0, 0x02900013, GPU_CONFIGREG_GC_CAC_IND },
659
660 { 0xFFFFFFFF } // End of list
661};
662
663static const struct gpu_pt_config_reg DIDTConfig_VegaM[] =
664{
665// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
666// Offset Mask Shift Value Type
667// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
668 // DIDT_SQ
669 //
670 { ixDIDT_SQ_WEIGHT0_3, DIDT_SQ_WEIGHT0_3__WEIGHT0_MASK, DIDT_SQ_WEIGHT0_3__WEIGHT0__SHIFT, 0x0073, GPU_CONFIGREG_DIDT_IND },
671 { ixDIDT_SQ_WEIGHT0_3, DIDT_SQ_WEIGHT0_3__WEIGHT1_MASK, DIDT_SQ_WEIGHT0_3__WEIGHT1__SHIFT, 0x00ab, GPU_CONFIGREG_DIDT_IND },
672 { ixDIDT_SQ_WEIGHT0_3, DIDT_SQ_WEIGHT0_3__WEIGHT2_MASK, DIDT_SQ_WEIGHT0_3__WEIGHT2__SHIFT, 0x0084, GPU_CONFIGREG_DIDT_IND },
673 { ixDIDT_SQ_WEIGHT0_3, DIDT_SQ_WEIGHT0_3__WEIGHT3_MASK, DIDT_SQ_WEIGHT0_3__WEIGHT3__SHIFT, 0x005a, GPU_CONFIGREG_DIDT_IND },
674
675 { ixDIDT_SQ_WEIGHT4_7, DIDT_SQ_WEIGHT4_7__WEIGHT4_MASK, DIDT_SQ_WEIGHT4_7__WEIGHT4__SHIFT, 0x0067, GPU_CONFIGREG_DIDT_IND },
676 { ixDIDT_SQ_WEIGHT4_7, DIDT_SQ_WEIGHT4_7__WEIGHT5_MASK, DIDT_SQ_WEIGHT4_7__WEIGHT5__SHIFT, 0x0084, GPU_CONFIGREG_DIDT_IND },
677 { ixDIDT_SQ_WEIGHT4_7, DIDT_SQ_WEIGHT4_7__WEIGHT6_MASK, DIDT_SQ_WEIGHT4_7__WEIGHT6__SHIFT, 0x0027, GPU_CONFIGREG_DIDT_IND },
678 { ixDIDT_SQ_WEIGHT4_7, DIDT_SQ_WEIGHT4_7__WEIGHT7_MASK, DIDT_SQ_WEIGHT4_7__WEIGHT7__SHIFT, 0x0046, GPU_CONFIGREG_DIDT_IND },
679
680 { ixDIDT_SQ_WEIGHT8_11, DIDT_SQ_WEIGHT8_11__WEIGHT8_MASK, DIDT_SQ_WEIGHT8_11__WEIGHT8__SHIFT, 0x00aa, GPU_CONFIGREG_DIDT_IND },
681 { ixDIDT_SQ_WEIGHT8_11, DIDT_SQ_WEIGHT8_11__WEIGHT9_MASK, DIDT_SQ_WEIGHT8_11__WEIGHT9__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
682 { ixDIDT_SQ_WEIGHT8_11, DIDT_SQ_WEIGHT8_11__WEIGHT10_MASK, DIDT_SQ_WEIGHT8_11__WEIGHT10__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
683 { ixDIDT_SQ_WEIGHT8_11, DIDT_SQ_WEIGHT8_11__WEIGHT11_MASK, DIDT_SQ_WEIGHT8_11__WEIGHT11__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
684
685 { ixDIDT_SQ_CTRL1, DIDT_SQ_CTRL1__MIN_POWER_MASK, DIDT_SQ_CTRL1__MIN_POWER__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
686 { ixDIDT_SQ_CTRL1, DIDT_SQ_CTRL1__MAX_POWER_MASK, DIDT_SQ_CTRL1__MAX_POWER__SHIFT, 0xffff, GPU_CONFIGREG_DIDT_IND },
687
688 { ixDIDT_SQ_CTRL_OCP, DIDT_SQ_CTRL_OCP__UNUSED_0_MASK, DIDT_SQ_CTRL_OCP__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
689 { ixDIDT_SQ_CTRL_OCP, DIDT_SQ_CTRL_OCP__OCP_MAX_POWER_MASK, DIDT_SQ_CTRL_OCP__OCP_MAX_POWER__SHIFT, 0xffff, GPU_CONFIGREG_DIDT_IND },
690
691 { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__MAX_POWER_DELTA_MASK, DIDT_SQ_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3853, GPU_CONFIGREG_DIDT_IND },
692 { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__UNUSED_0_MASK, DIDT_SQ_CTRL2__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
693 { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x005a, GPU_CONFIGREG_DIDT_IND },
694 { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__UNUSED_1_MASK, DIDT_SQ_CTRL2__UNUSED_1__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
695 { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
696 { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__UNUSED_2_MASK, DIDT_SQ_CTRL2__UNUSED_2__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
697
698 { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_STALL_CTRL_ENABLE_MASK, DIDT_SQ_STALL_CTRL__DIDT_STALL_CTRL_ENABLE__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
699 { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
700 { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
701 { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_SQ_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT, 0x0ebb, GPU_CONFIGREG_DIDT_IND },
702 { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__UNUSED_0_MASK, DIDT_SQ_STALL_CTRL__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
703
704 { ixDIDT_SQ_TUNING_CTRL, DIDT_SQ_TUNING_CTRL__DIDT_TUNING_ENABLE_MASK, DIDT_SQ_TUNING_CTRL__DIDT_TUNING_ENABLE__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
705 { ixDIDT_SQ_TUNING_CTRL, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x3853, GPU_CONFIGREG_DIDT_IND },
706 { ixDIDT_SQ_TUNING_CTRL, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x3153, GPU_CONFIGREG_DIDT_IND },
707 { ixDIDT_SQ_TUNING_CTRL, DIDT_SQ_TUNING_CTRL__UNUSED_0_MASK, DIDT_SQ_TUNING_CTRL__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
708
709 { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_CTRL_EN_MASK, DIDT_SQ_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
710 { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__USE_REF_CLOCK_MASK, DIDT_SQ_CTRL0__USE_REF_CLOCK__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
711 { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__PHASE_OFFSET_MASK, DIDT_SQ_CTRL0__PHASE_OFFSET__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
712 { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_CTRL_RST_MASK, DIDT_SQ_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
713 { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
714 { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x0010, GPU_CONFIGREG_DIDT_IND },
715 { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x0010, GPU_CONFIGREG_DIDT_IND },
716 { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__UNUSED_0_MASK, DIDT_SQ_CTRL0__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
717
718 // DIDT_TD
719 //
720 { ixDIDT_TD_WEIGHT0_3, DIDT_TD_WEIGHT0_3__WEIGHT0_MASK, DIDT_TD_WEIGHT0_3__WEIGHT0__SHIFT, 0x000a, GPU_CONFIGREG_DIDT_IND },
721 { ixDIDT_TD_WEIGHT0_3, DIDT_TD_WEIGHT0_3__WEIGHT1_MASK, DIDT_TD_WEIGHT0_3__WEIGHT1__SHIFT, 0x0010, GPU_CONFIGREG_DIDT_IND },
722 { ixDIDT_TD_WEIGHT0_3, DIDT_TD_WEIGHT0_3__WEIGHT2_MASK, DIDT_TD_WEIGHT0_3__WEIGHT2__SHIFT, 0x0017, GPU_CONFIGREG_DIDT_IND },
723 { ixDIDT_TD_WEIGHT0_3, DIDT_TD_WEIGHT0_3__WEIGHT3_MASK, DIDT_TD_WEIGHT0_3__WEIGHT3__SHIFT, 0x002f, GPU_CONFIGREG_DIDT_IND },
724
725 { ixDIDT_TD_WEIGHT4_7, DIDT_TD_WEIGHT4_7__WEIGHT4_MASK, DIDT_TD_WEIGHT4_7__WEIGHT4__SHIFT, 0x0046, GPU_CONFIGREG_DIDT_IND },
726 { ixDIDT_TD_WEIGHT4_7, DIDT_TD_WEIGHT4_7__WEIGHT5_MASK, DIDT_TD_WEIGHT4_7__WEIGHT5__SHIFT, 0x005d, GPU_CONFIGREG_DIDT_IND },
727 { ixDIDT_TD_WEIGHT4_7, DIDT_TD_WEIGHT4_7__WEIGHT6_MASK, DIDT_TD_WEIGHT4_7__WEIGHT6__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
728 { ixDIDT_TD_WEIGHT4_7, DIDT_TD_WEIGHT4_7__WEIGHT7_MASK, DIDT_TD_WEIGHT4_7__WEIGHT7__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
729
730 { ixDIDT_TD_CTRL1, DIDT_TD_CTRL1__MIN_POWER_MASK, DIDT_TD_CTRL1__MIN_POWER__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
731 { ixDIDT_TD_CTRL1, DIDT_TD_CTRL1__MAX_POWER_MASK, DIDT_TD_CTRL1__MAX_POWER__SHIFT, 0xffff, GPU_CONFIGREG_DIDT_IND },
732
733 { ixDIDT_TD_CTRL_OCP, DIDT_TD_CTRL_OCP__UNUSED_0_MASK, DIDT_TD_CTRL_OCP__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
734 { ixDIDT_TD_CTRL_OCP, DIDT_TD_CTRL_OCP__OCP_MAX_POWER_MASK, DIDT_TD_CTRL_OCP__OCP_MAX_POWER__SHIFT, 0x00ff, GPU_CONFIGREG_DIDT_IND },
735
736 { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__MAX_POWER_DELTA_MASK, DIDT_TD_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3fff, GPU_CONFIGREG_DIDT_IND },
737 { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__UNUSED_0_MASK, DIDT_TD_CTRL2__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
738 { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_TD_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x000f, GPU_CONFIGREG_DIDT_IND },
739 { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__UNUSED_1_MASK, DIDT_TD_CTRL2__UNUSED_1__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
740 { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_TD_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
741 { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__UNUSED_2_MASK, DIDT_TD_CTRL2__UNUSED_2__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
742
743 { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_STALL_CTRL_ENABLE_MASK, DIDT_TD_STALL_CTRL__DIDT_STALL_CTRL_ENABLE__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
744 { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
745 { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
746 { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TD_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT, 0x01aa, GPU_CONFIGREG_DIDT_IND },
747 { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__UNUSED_0_MASK, DIDT_TD_STALL_CTRL__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
748
749 { ixDIDT_TD_TUNING_CTRL, DIDT_TD_TUNING_CTRL__DIDT_TUNING_ENABLE_MASK, DIDT_TD_TUNING_CTRL__DIDT_TUNING_ENABLE__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
750 { ixDIDT_TD_TUNING_CTRL, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x0dde, GPU_CONFIGREG_DIDT_IND },
751 { ixDIDT_TD_TUNING_CTRL, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x0dde, GPU_CONFIGREG_DIDT_IND },
752 { ixDIDT_TD_TUNING_CTRL, DIDT_TD_TUNING_CTRL__UNUSED_0_MASK, DIDT_TD_TUNING_CTRL__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
753
754 { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_CTRL_EN_MASK, DIDT_TD_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
755 { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__USE_REF_CLOCK_MASK, DIDT_TD_CTRL0__USE_REF_CLOCK__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
756 { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__PHASE_OFFSET_MASK, DIDT_TD_CTRL0__PHASE_OFFSET__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
757 { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_CTRL_RST_MASK, DIDT_TD_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
758 { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
759 { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_TD_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x0009, GPU_CONFIGREG_DIDT_IND },
760 { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_TD_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x0009, GPU_CONFIGREG_DIDT_IND },
761 { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__UNUSED_0_MASK, DIDT_TD_CTRL0__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
762
763 // DIDT_TCP
764 //
765 { ixDIDT_TCP_WEIGHT0_3, DIDT_TCP_WEIGHT0_3__WEIGHT0_MASK, DIDT_TCP_WEIGHT0_3__WEIGHT0__SHIFT, 0x0004, GPU_CONFIGREG_DIDT_IND },
766 { ixDIDT_TCP_WEIGHT0_3, DIDT_TCP_WEIGHT0_3__WEIGHT1_MASK, DIDT_TCP_WEIGHT0_3__WEIGHT1__SHIFT, 0x0037, GPU_CONFIGREG_DIDT_IND },
767 { ixDIDT_TCP_WEIGHT0_3, DIDT_TCP_WEIGHT0_3__WEIGHT2_MASK, DIDT_TCP_WEIGHT0_3__WEIGHT2__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
768 { ixDIDT_TCP_WEIGHT0_3, DIDT_TCP_WEIGHT0_3__WEIGHT3_MASK, DIDT_TCP_WEIGHT0_3__WEIGHT3__SHIFT, 0x00ff, GPU_CONFIGREG_DIDT_IND },
769
770 { ixDIDT_TCP_WEIGHT4_7, DIDT_TCP_WEIGHT4_7__WEIGHT4_MASK, DIDT_TCP_WEIGHT4_7__WEIGHT4__SHIFT, 0x0054, GPU_CONFIGREG_DIDT_IND },
771 { ixDIDT_TCP_WEIGHT4_7, DIDT_TCP_WEIGHT4_7__WEIGHT5_MASK, DIDT_TCP_WEIGHT4_7__WEIGHT5__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
772 { ixDIDT_TCP_WEIGHT4_7, DIDT_TCP_WEIGHT4_7__WEIGHT6_MASK, DIDT_TCP_WEIGHT4_7__WEIGHT6__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
773 { ixDIDT_TCP_WEIGHT4_7, DIDT_TCP_WEIGHT4_7__WEIGHT7_MASK, DIDT_TCP_WEIGHT4_7__WEIGHT7__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
774
775 { ixDIDT_TCP_CTRL1, DIDT_TCP_CTRL1__MIN_POWER_MASK, DIDT_TCP_CTRL1__MIN_POWER__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
776 { ixDIDT_TCP_CTRL1, DIDT_TCP_CTRL1__MAX_POWER_MASK, DIDT_TCP_CTRL1__MAX_POWER__SHIFT, 0xffff, GPU_CONFIGREG_DIDT_IND },
777
778 { ixDIDT_TCP_CTRL_OCP, DIDT_TCP_CTRL_OCP__UNUSED_0_MASK, DIDT_TCP_CTRL_OCP__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
779 { ixDIDT_TCP_CTRL_OCP, DIDT_TCP_CTRL_OCP__OCP_MAX_POWER_MASK, DIDT_TCP_CTRL_OCP__OCP_MAX_POWER__SHIFT, 0xffff, GPU_CONFIGREG_DIDT_IND },
780
781 { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__MAX_POWER_DELTA_MASK, DIDT_TCP_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3dde, GPU_CONFIGREG_DIDT_IND },
782 { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__UNUSED_0_MASK, DIDT_TCP_CTRL2__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
783 { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_TCP_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x0032, GPU_CONFIGREG_DIDT_IND },
784 { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__UNUSED_1_MASK, DIDT_TCP_CTRL2__UNUSED_1__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
785 { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_TCP_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
786 { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__UNUSED_2_MASK, DIDT_TCP_CTRL2__UNUSED_2__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
787
788 { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_CTRL_ENABLE_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_CTRL_ENABLE__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
789 { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
790 { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
791 { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT,0x01aa, GPU_CONFIGREG_DIDT_IND },
792 { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__UNUSED_0_MASK, DIDT_TCP_STALL_CTRL__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
793
794 { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__DIDT_TUNING_ENABLE_MASK, DIDT_TCP_TUNING_CTRL__DIDT_TUNING_ENABLE__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
795 { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x3dde, GPU_CONFIGREG_DIDT_IND },
796 { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x3dde, GPU_CONFIGREG_DIDT_IND },
797 { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__UNUSED_0_MASK, DIDT_TCP_TUNING_CTRL__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
798
799 { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_CTRL_EN_MASK, DIDT_TCP_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND },
800 { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__USE_REF_CLOCK_MASK, DIDT_TCP_CTRL0__USE_REF_CLOCK__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
801 { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__PHASE_OFFSET_MASK, DIDT_TCP_CTRL0__PHASE_OFFSET__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
802 { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_CTRL_RST_MASK, DIDT_TCP_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
803 { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
804 { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_TCP_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x0010, GPU_CONFIGREG_DIDT_IND },
805 { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_TCP_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x0010, GPU_CONFIGREG_DIDT_IND },
806 { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__UNUSED_0_MASK, DIDT_TCP_CTRL0__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND },
807
808 { 0xFFFFFFFF } // End of list
809};
626static int smu7_enable_didt(struct pp_hwmgr *hwmgr, const bool enable) 810static int smu7_enable_didt(struct pp_hwmgr *hwmgr, const bool enable)
627{ 811{
628 uint32_t en = enable ? 1 : 0; 812 uint32_t en = enable ? 1 : 0;
@@ -740,8 +924,8 @@ int smu7_enable_didt_config(struct pp_hwmgr *hwmgr)
740 PP_CAP(PHM_PlatformCaps_TDRamping) || 924 PP_CAP(PHM_PlatformCaps_TDRamping) ||
741 PP_CAP(PHM_PlatformCaps_TCPRamping)) { 925 PP_CAP(PHM_PlatformCaps_TCPRamping)) {
742 926
743 cgs_enter_safe_mode(hwmgr->device, true); 927 adev->gfx.rlc.funcs->enter_safe_mode(adev);
744 cgs_lock_grbm_idx(hwmgr->device, true); 928 mutex_lock(&adev->grbm_idx_mutex);
745 value = 0; 929 value = 0;
746 value2 = cgs_read_register(hwmgr->device, mmGRBM_GFX_INDEX); 930 value2 = cgs_read_register(hwmgr->device, mmGRBM_GFX_INDEX);
747 for (count = 0; count < num_se; count++) { 931 for (count = 0; count < num_se; count++) {
@@ -752,67 +936,80 @@ int smu7_enable_didt_config(struct pp_hwmgr *hwmgr)
752 936
753 if (hwmgr->chip_id == CHIP_POLARIS10) { 937 if (hwmgr->chip_id == CHIP_POLARIS10) {
754 result = smu7_program_pt_config_registers(hwmgr, GCCACConfig_Polaris10); 938 result = smu7_program_pt_config_registers(hwmgr, GCCACConfig_Polaris10);
755 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", return result); 939 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", goto error);
756 result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris10); 940 result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris10);
757 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", return result); 941 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", goto error);
758 } else if (hwmgr->chip_id == CHIP_POLARIS11) { 942 } else if (hwmgr->chip_id == CHIP_POLARIS11) {
759 result = smu7_program_pt_config_registers(hwmgr, GCCACConfig_Polaris11); 943 result = smu7_program_pt_config_registers(hwmgr, GCCACConfig_Polaris11);
760 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", return result); 944 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", goto error);
761 if (hwmgr->is_kicker) 945 if (hwmgr->is_kicker)
762 result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris11_Kicker); 946 result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris11_Kicker);
763 else 947 else
764 result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris11); 948 result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris11);
765 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", return result); 949 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", goto error);
766 } else if (hwmgr->chip_id == CHIP_POLARIS12) { 950 } else if (hwmgr->chip_id == CHIP_POLARIS12) {
767 result = smu7_program_pt_config_registers(hwmgr, GCCACConfig_Polaris11); 951 result = smu7_program_pt_config_registers(hwmgr, GCCACConfig_Polaris11);
768 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", return result); 952 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", goto error);
769 result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris12); 953 result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris12);
770 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", return result); 954 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", goto error);
955 } else if (hwmgr->chip_id == CHIP_VEGAM) {
956 result = smu7_program_pt_config_registers(hwmgr, GCCACConfig_VegaM);
957 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", goto error);
958 result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_VegaM);
959 PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", goto error);
771 } 960 }
772 } 961 }
773 cgs_write_register(hwmgr->device, mmGRBM_GFX_INDEX, value2); 962 cgs_write_register(hwmgr->device, mmGRBM_GFX_INDEX, value2);
774 963
775 result = smu7_enable_didt(hwmgr, true); 964 result = smu7_enable_didt(hwmgr, true);
776 PP_ASSERT_WITH_CODE((result == 0), "EnableDiDt failed.", return result); 965 PP_ASSERT_WITH_CODE((result == 0), "EnableDiDt failed.", goto error);
777 966
778 if (hwmgr->chip_id == CHIP_POLARIS11) { 967 if (hwmgr->chip_id == CHIP_POLARIS11) {
779 result = smum_send_msg_to_smc(hwmgr, 968 result = smum_send_msg_to_smc(hwmgr,
780 (uint16_t)(PPSMC_MSG_EnableDpmDidt)); 969 (uint16_t)(PPSMC_MSG_EnableDpmDidt));
781 PP_ASSERT_WITH_CODE((0 == result), 970 PP_ASSERT_WITH_CODE((0 == result),
782 "Failed to enable DPM DIDT.", return result); 971 "Failed to enable DPM DIDT.", goto error);
783 } 972 }
784 cgs_lock_grbm_idx(hwmgr->device, false); 973 mutex_unlock(&adev->grbm_idx_mutex);
785 cgs_enter_safe_mode(hwmgr->device, false); 974 adev->gfx.rlc.funcs->exit_safe_mode(adev);
786 } 975 }
787 976
788 return 0; 977 return 0;
978error:
979 mutex_unlock(&adev->grbm_idx_mutex);
980 adev->gfx.rlc.funcs->exit_safe_mode(adev);
981 return result;
789} 982}
790 983
791int smu7_disable_didt_config(struct pp_hwmgr *hwmgr) 984int smu7_disable_didt_config(struct pp_hwmgr *hwmgr)
792{ 985{
793 int result; 986 int result;
987 struct amdgpu_device *adev = hwmgr->adev;
794 988
795 if (PP_CAP(PHM_PlatformCaps_SQRamping) || 989 if (PP_CAP(PHM_PlatformCaps_SQRamping) ||
796 PP_CAP(PHM_PlatformCaps_DBRamping) || 990 PP_CAP(PHM_PlatformCaps_DBRamping) ||
797 PP_CAP(PHM_PlatformCaps_TDRamping) || 991 PP_CAP(PHM_PlatformCaps_TDRamping) ||
798 PP_CAP(PHM_PlatformCaps_TCPRamping)) { 992 PP_CAP(PHM_PlatformCaps_TCPRamping)) {
799 993
800 cgs_enter_safe_mode(hwmgr->device, true); 994 adev->gfx.rlc.funcs->enter_safe_mode(adev);
801 995
802 result = smu7_enable_didt(hwmgr, false); 996 result = smu7_enable_didt(hwmgr, false);
803 PP_ASSERT_WITH_CODE((result == 0), 997 PP_ASSERT_WITH_CODE((result == 0),
804 "Post DIDT enable clock gating failed.", 998 "Post DIDT enable clock gating failed.",
805 return result); 999 goto error);
806 if (hwmgr->chip_id == CHIP_POLARIS11) { 1000 if (hwmgr->chip_id == CHIP_POLARIS11) {
807 result = smum_send_msg_to_smc(hwmgr, 1001 result = smum_send_msg_to_smc(hwmgr,
808 (uint16_t)(PPSMC_MSG_DisableDpmDidt)); 1002 (uint16_t)(PPSMC_MSG_DisableDpmDidt));
809 PP_ASSERT_WITH_CODE((0 == result), 1003 PP_ASSERT_WITH_CODE((0 == result),
810 "Failed to disable DPM DIDT.", return result); 1004 "Failed to disable DPM DIDT.", goto error);
811 } 1005 }
812 cgs_enter_safe_mode(hwmgr->device, false); 1006 adev->gfx.rlc.funcs->exit_safe_mode(adev);
813 } 1007 }
814 1008
815 return 0; 1009 return 0;
1010error:
1011 adev->gfx.rlc.funcs->exit_safe_mode(adev);
1012 return result;
816} 1013}
817 1014
818int smu7_enable_smc_cac(struct pp_hwmgr *hwmgr) 1015int smu7_enable_smc_cac(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c
index 7b26607c646a..50690c72b2ea 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c
@@ -314,8 +314,7 @@ static int smu8_get_system_info_data(struct pp_hwmgr *hwmgr)
314 uint8_t frev, crev; 314 uint8_t frev, crev;
315 uint16_t size; 315 uint16_t size;
316 316
317 info = (ATOM_INTEGRATED_SYSTEM_INFO_V1_9 *) cgs_atom_get_data_table( 317 info = (ATOM_INTEGRATED_SYSTEM_INFO_V1_9 *)smu_atom_get_data_table(hwmgr->adev,
318 hwmgr->device,
319 GetIndexIntoMasterTable(DATA, IntegratedSystemInfo), 318 GetIndexIntoMasterTable(DATA, IntegratedSystemInfo),
320 &size, &frev, &crev); 319 &size, &frev, &crev);
321 320
@@ -694,7 +693,7 @@ static int smu8_update_sclk_limit(struct pp_hwmgr *hwmgr)
694 else 693 else
695 data->sclk_dpm.soft_max_clk = table->entries[table->count - 1].clk; 694 data->sclk_dpm.soft_max_clk = table->entries[table->count - 1].clk;
696 695
697 clock = hwmgr->display_config.min_core_set_clock; 696 clock = hwmgr->display_config->min_core_set_clock;
698 if (clock == 0) 697 if (clock == 0)
699 pr_debug("min_core_set_clock not set\n"); 698 pr_debug("min_core_set_clock not set\n");
700 699
@@ -749,7 +748,7 @@ static int smu8_set_deep_sleep_sclk_threshold(struct pp_hwmgr *hwmgr)
749{ 748{
750 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 749 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
751 PHM_PlatformCaps_SclkDeepSleep)) { 750 PHM_PlatformCaps_SclkDeepSleep)) {
752 uint32_t clks = hwmgr->display_config.min_core_set_clock_in_sr; 751 uint32_t clks = hwmgr->display_config->min_core_set_clock_in_sr;
753 if (clks == 0) 752 if (clks == 0)
754 clks = SMU8_MIN_DEEP_SLEEP_SCLK; 753 clks = SMU8_MIN_DEEP_SLEEP_SCLK;
755 754
@@ -1041,25 +1040,21 @@ static int smu8_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
1041 struct smu8_hwmgr *data = hwmgr->backend; 1040 struct smu8_hwmgr *data = hwmgr->backend;
1042 struct PP_Clocks clocks = {0, 0, 0, 0}; 1041 struct PP_Clocks clocks = {0, 0, 0, 0};
1043 bool force_high; 1042 bool force_high;
1044 uint32_t num_of_active_displays = 0;
1045 struct cgs_display_info info = {0};
1046 1043
1047 smu8_ps->need_dfs_bypass = true; 1044 smu8_ps->need_dfs_bypass = true;
1048 1045
1049 data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label); 1046 data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label);
1050 1047
1051 clocks.memoryClock = hwmgr->display_config.min_mem_set_clock != 0 ? 1048 clocks.memoryClock = hwmgr->display_config->min_mem_set_clock != 0 ?
1052 hwmgr->display_config.min_mem_set_clock : 1049 hwmgr->display_config->min_mem_set_clock :
1053 data->sys_info.nbp_memory_clock[1]; 1050 data->sys_info.nbp_memory_clock[1];
1054 1051
1055 cgs_get_active_displays_info(hwmgr->device, &info);
1056 num_of_active_displays = info.display_count;
1057 1052
1058 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) 1053 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
1059 clocks.memoryClock = hwmgr->dyn_state.max_clock_voltage_on_ac.mclk; 1054 clocks.memoryClock = hwmgr->dyn_state.max_clock_voltage_on_ac.mclk;
1060 1055
1061 force_high = (clocks.memoryClock > data->sys_info.nbp_memory_clock[SMU8_NUM_NBPMEMORYCLOCK - 1]) 1056 force_high = (clocks.memoryClock > data->sys_info.nbp_memory_clock[SMU8_NUM_NBPMEMORYCLOCK - 1])
1062 || (num_of_active_displays >= 3); 1057 || (hwmgr->display_config->num_display >= 3);
1063 1058
1064 smu8_ps->action = smu8_current_ps->action; 1059 smu8_ps->action = smu8_current_ps->action;
1065 1060
@@ -1897,20 +1892,20 @@ static void smu8_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
1897 data->uvd_power_gated = bgate; 1892 data->uvd_power_gated = bgate;
1898 1893
1899 if (bgate) { 1894 if (bgate) {
1900 cgs_set_powergating_state(hwmgr->device, 1895 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
1901 AMD_IP_BLOCK_TYPE_UVD, 1896 AMD_IP_BLOCK_TYPE_UVD,
1902 AMD_PG_STATE_GATE); 1897 AMD_PG_STATE_GATE);
1903 cgs_set_clockgating_state(hwmgr->device, 1898 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
1904 AMD_IP_BLOCK_TYPE_UVD, 1899 AMD_IP_BLOCK_TYPE_UVD,
1905 AMD_CG_STATE_GATE); 1900 AMD_CG_STATE_GATE);
1906 smu8_dpm_update_uvd_dpm(hwmgr, true); 1901 smu8_dpm_update_uvd_dpm(hwmgr, true);
1907 smu8_dpm_powerdown_uvd(hwmgr); 1902 smu8_dpm_powerdown_uvd(hwmgr);
1908 } else { 1903 } else {
1909 smu8_dpm_powerup_uvd(hwmgr); 1904 smu8_dpm_powerup_uvd(hwmgr);
1910 cgs_set_clockgating_state(hwmgr->device, 1905 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
1911 AMD_IP_BLOCK_TYPE_UVD, 1906 AMD_IP_BLOCK_TYPE_UVD,
1912 AMD_CG_STATE_UNGATE); 1907 AMD_CG_STATE_UNGATE);
1913 cgs_set_powergating_state(hwmgr->device, 1908 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
1914 AMD_IP_BLOCK_TYPE_UVD, 1909 AMD_IP_BLOCK_TYPE_UVD,
1915 AMD_PG_STATE_UNGATE); 1910 AMD_PG_STATE_UNGATE);
1916 smu8_dpm_update_uvd_dpm(hwmgr, false); 1911 smu8_dpm_update_uvd_dpm(hwmgr, false);
@@ -1923,12 +1918,10 @@ static void smu8_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
1923 struct smu8_hwmgr *data = hwmgr->backend; 1918 struct smu8_hwmgr *data = hwmgr->backend;
1924 1919
1925 if (bgate) { 1920 if (bgate) {
1926 cgs_set_powergating_state( 1921 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
1927 hwmgr->device,
1928 AMD_IP_BLOCK_TYPE_VCE, 1922 AMD_IP_BLOCK_TYPE_VCE,
1929 AMD_PG_STATE_GATE); 1923 AMD_PG_STATE_GATE);
1930 cgs_set_clockgating_state( 1924 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
1931 hwmgr->device,
1932 AMD_IP_BLOCK_TYPE_VCE, 1925 AMD_IP_BLOCK_TYPE_VCE,
1933 AMD_CG_STATE_GATE); 1926 AMD_CG_STATE_GATE);
1934 smu8_enable_disable_vce_dpm(hwmgr, false); 1927 smu8_enable_disable_vce_dpm(hwmgr, false);
@@ -1937,12 +1930,10 @@ static void smu8_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
1937 } else { 1930 } else {
1938 smu8_dpm_powerup_vce(hwmgr); 1931 smu8_dpm_powerup_vce(hwmgr);
1939 data->vce_power_gated = false; 1932 data->vce_power_gated = false;
1940 cgs_set_clockgating_state( 1933 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
1941 hwmgr->device,
1942 AMD_IP_BLOCK_TYPE_VCE, 1934 AMD_IP_BLOCK_TYPE_VCE,
1943 AMD_CG_STATE_UNGATE); 1935 AMD_CG_STATE_UNGATE);
1944 cgs_set_powergating_state( 1936 amdgpu_device_ip_set_powergating_state(hwmgr->adev,
1945 hwmgr->device,
1946 AMD_IP_BLOCK_TYPE_VCE, 1937 AMD_IP_BLOCK_TYPE_VCE,
1947 AMD_PG_STATE_UNGATE); 1938 AMD_PG_STATE_UNGATE);
1948 smu8_dpm_update_vce_dpm(hwmgr); 1939 smu8_dpm_update_vce_dpm(hwmgr);
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
index 598122854ab5..93a3d022ba47 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
@@ -24,6 +24,7 @@
24#include "pp_debug.h" 24#include "pp_debug.h"
25#include "ppatomctrl.h" 25#include "ppatomctrl.h"
26#include "ppsmc.h" 26#include "ppsmc.h"
27#include "atom.h"
27 28
28uint8_t convert_to_vid(uint16_t vddc) 29uint8_t convert_to_vid(uint16_t vddc)
29{ 30{
@@ -608,3 +609,100 @@ int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr)
608 609
609 return 0; 610 return 0;
610} 611}
612
613void *smu_atom_get_data_table(void *dev, uint32_t table, uint16_t *size,
614 uint8_t *frev, uint8_t *crev)
615{
616 struct amdgpu_device *adev = dev;
617 uint16_t data_start;
618
619 if (amdgpu_atom_parse_data_header(
620 adev->mode_info.atom_context, table, size,
621 frev, crev, &data_start))
622 return (uint8_t *)adev->mode_info.atom_context->bios +
623 data_start;
624
625 return NULL;
626}
627
628int smu_get_voltage_dependency_table_ppt_v1(
629 const struct phm_ppt_v1_clock_voltage_dependency_table *allowed_dep_table,
630 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table)
631{
632 uint8_t i = 0;
633 PP_ASSERT_WITH_CODE((0 != allowed_dep_table->count),
634 "Voltage Lookup Table empty",
635 return -EINVAL);
636
637 dep_table->count = allowed_dep_table->count;
638 for (i=0; i<dep_table->count; i++) {
639 dep_table->entries[i].clk = allowed_dep_table->entries[i].clk;
640 dep_table->entries[i].vddInd = allowed_dep_table->entries[i].vddInd;
641 dep_table->entries[i].vdd_offset = allowed_dep_table->entries[i].vdd_offset;
642 dep_table->entries[i].vddc = allowed_dep_table->entries[i].vddc;
643 dep_table->entries[i].vddgfx = allowed_dep_table->entries[i].vddgfx;
644 dep_table->entries[i].vddci = allowed_dep_table->entries[i].vddci;
645 dep_table->entries[i].mvdd = allowed_dep_table->entries[i].mvdd;
646 dep_table->entries[i].phases = allowed_dep_table->entries[i].phases;
647 dep_table->entries[i].cks_enable = allowed_dep_table->entries[i].cks_enable;
648 dep_table->entries[i].cks_voffset = allowed_dep_table->entries[i].cks_voffset;
649 }
650
651 return 0;
652}
653
654int smu_set_watermarks_for_clocks_ranges(void *wt_table,
655 struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges)
656{
657 uint32_t i;
658 struct watermarks *table = wt_table;
659
660 if (!table || !wm_with_clock_ranges)
661 return -EINVAL;
662
663 if (wm_with_clock_ranges->num_wm_sets_dmif > 4 || wm_with_clock_ranges->num_wm_sets_mcif > 4)
664 return -EINVAL;
665
666 for (i = 0; i < wm_with_clock_ranges->num_wm_sets_dmif; i++) {
667 table->WatermarkRow[1][i].MinClock =
668 cpu_to_le16((uint16_t)
669 (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_dcefclk_in_khz) /
670 100);
671 table->WatermarkRow[1][i].MaxClock =
672 cpu_to_le16((uint16_t)
673 (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_dcefclk_in_khz) /
674 100);
675 table->WatermarkRow[1][i].MinUclk =
676 cpu_to_le16((uint16_t)
677 (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_memclk_in_khz) /
678 100);
679 table->WatermarkRow[1][i].MaxUclk =
680 cpu_to_le16((uint16_t)
681 (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_memclk_in_khz) /
682 100);
683 table->WatermarkRow[1][i].WmSetting = (uint8_t)
684 wm_with_clock_ranges->wm_sets_dmif[i].wm_set_id;
685 }
686
687 for (i = 0; i < wm_with_clock_ranges->num_wm_sets_mcif; i++) {
688 table->WatermarkRow[0][i].MinClock =
689 cpu_to_le16((uint16_t)
690 (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_socclk_in_khz) /
691 100);
692 table->WatermarkRow[0][i].MaxClock =
693 cpu_to_le16((uint16_t)
694 (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_socclk_in_khz) /
695 100);
696 table->WatermarkRow[0][i].MinUclk =
697 cpu_to_le16((uint16_t)
698 (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_memclk_in_khz) /
699 100);
700 table->WatermarkRow[0][i].MaxUclk =
701 cpu_to_le16((uint16_t)
702 (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_memclk_in_khz) /
703 100);
704 table->WatermarkRow[0][i].WmSetting = (uint8_t)
705 wm_with_clock_ranges->wm_sets_mcif[i].wm_set_id;
706 }
707 return 0;
708}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h
index d37d16e4b613..916cc01e7652 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h
@@ -26,10 +26,27 @@
26struct pp_atomctrl_voltage_table; 26struct pp_atomctrl_voltage_table;
27struct pp_hwmgr; 27struct pp_hwmgr;
28struct phm_ppt_v1_voltage_lookup_table; 28struct phm_ppt_v1_voltage_lookup_table;
29struct Watermarks_t;
30struct pp_wm_sets_with_clock_ranges_soc15;
29 31
30uint8_t convert_to_vid(uint16_t vddc); 32uint8_t convert_to_vid(uint16_t vddc);
31uint16_t convert_to_vddc(uint8_t vid); 33uint16_t convert_to_vddc(uint8_t vid);
32 34
35struct watermark_row_generic_t {
36 uint16_t MinClock;
37 uint16_t MaxClock;
38 uint16_t MinUclk;
39 uint16_t MaxUclk;
40
41 uint8_t WmSetting;
42 uint8_t Padding[3];
43};
44
45struct watermarks {
46 struct watermark_row_generic_t WatermarkRow[2][4];
47 uint32_t padding[7];
48};
49
33extern int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr, 50extern int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
34 uint32_t index, 51 uint32_t index,
35 uint32_t value, uint32_t mask); 52 uint32_t value, uint32_t mask);
@@ -82,6 +99,16 @@ int phm_irq_process(struct amdgpu_device *adev,
82 99
83int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr); 100int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr);
84 101
102void *smu_atom_get_data_table(void *dev, uint32_t table, uint16_t *size,
103 uint8_t *frev, uint8_t *crev);
104
105int smu_get_voltage_dependency_table_ppt_v1(
106 const struct phm_ppt_v1_clock_voltage_dependency_table *allowed_dep_table,
107 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table);
108
109int smu_set_watermarks_for_clocks_ranges(void *wt_table,
110 struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges);
111
85#define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT 112#define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
86#define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK 113#define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK
87 114
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
index 7cbb56ba6fab..d156b7bb92ae 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
@@ -36,7 +36,7 @@
36#include "smu9.h" 36#include "smu9.h"
37#include "smu9_driver_if.h" 37#include "smu9_driver_if.h"
38#include "vega10_inc.h" 38#include "vega10_inc.h"
39#include "pp_soc15.h" 39#include "soc15_common.h"
40#include "pppcielanes.h" 40#include "pppcielanes.h"
41#include "vega10_hwmgr.h" 41#include "vega10_hwmgr.h"
42#include "vega10_processpptables.h" 42#include "vega10_processpptables.h"
@@ -51,10 +51,6 @@
51#include "smuio/smuio_9_0_offset.h" 51#include "smuio/smuio_9_0_offset.h"
52#include "smuio/smuio_9_0_sh_mask.h" 52#include "smuio/smuio_9_0_sh_mask.h"
53 53
54#define VOLTAGE_SCALE 4
55#define VOLTAGE_VID_OFFSET_SCALE1 625
56#define VOLTAGE_VID_OFFSET_SCALE2 100
57
58#define HBM_MEMORY_CHANNEL_WIDTH 128 54#define HBM_MEMORY_CHANNEL_WIDTH 128
59 55
60static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2}; 56static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2};
@@ -79,8 +75,6 @@ static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2};
79#define DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK 0x000000F0L 75#define DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK 0x000000F0L
80#define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel_MASK 0x00000700L 76#define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel_MASK 0x00000700L
81#define DF_CS_AON0_DramBaseAddress0__DramBaseAddr_MASK 0xFFFFF000L 77#define DF_CS_AON0_DramBaseAddress0__DramBaseAddr_MASK 0xFFFFF000L
82static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
83 enum pp_clock_type type, uint32_t mask);
84 78
85static const ULONG PhwVega10_Magic = (ULONG)(PHM_VIslands_Magic); 79static const ULONG PhwVega10_Magic = (ULONG)(PHM_VIslands_Magic);
86 80
@@ -291,6 +285,48 @@ static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
291 return 0; 285 return 0;
292} 286}
293 287
288static int vega10_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
289{
290 struct vega10_hwmgr *data = hwmgr->backend;
291 struct phm_ppt_v2_information *table_info =
292 (struct phm_ppt_v2_information *)(hwmgr->pptable);
293 struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);
294 struct vega10_odn_vddc_lookup_table *od_lookup_table;
295 struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table;
296 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table[3];
297 struct phm_ppt_v1_clock_voltage_dependency_table *od_table[3];
298 uint32_t i;
299
300 od_lookup_table = &odn_table->vddc_lookup_table;
301 vddc_lookup_table = table_info->vddc_lookup_table;
302
303 for (i = 0; i < vddc_lookup_table->count; i++)
304 od_lookup_table->entries[i].us_vdd = vddc_lookup_table->entries[i].us_vdd;
305
306 od_lookup_table->count = vddc_lookup_table->count;
307
308 dep_table[0] = table_info->vdd_dep_on_sclk;
309 dep_table[1] = table_info->vdd_dep_on_mclk;
310 dep_table[2] = table_info->vdd_dep_on_socclk;
311 od_table[0] = (struct phm_ppt_v1_clock_voltage_dependency_table *)&odn_table->vdd_dep_on_sclk;
312 od_table[1] = (struct phm_ppt_v1_clock_voltage_dependency_table *)&odn_table->vdd_dep_on_mclk;
313 od_table[2] = (struct phm_ppt_v1_clock_voltage_dependency_table *)&odn_table->vdd_dep_on_socclk;
314
315 for (i = 0; i < 3; i++)
316 smu_get_voltage_dependency_table_ppt_v1(dep_table[i], od_table[i]);
317
318 if (odn_table->max_vddc == 0 || odn_table->max_vddc > 2000)
319 odn_table->max_vddc = dep_table[0]->entries[dep_table[0]->count - 1].vddc;
320 if (odn_table->min_vddc == 0 || odn_table->min_vddc > 2000)
321 odn_table->min_vddc = dep_table[0]->entries[0].vddc;
322
323 i = od_table[2]->count - 1;
324 od_table[2]->entries[i].clk = hwmgr->platform_descriptor.overdriveLimit.memoryClock;
325 od_table[2]->entries[i].vddc = odn_table->max_vddc;
326
327 return 0;
328}
329
294static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) 330static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
295{ 331{
296 struct vega10_hwmgr *data = hwmgr->backend; 332 struct vega10_hwmgr *data = hwmgr->backend;
@@ -427,7 +463,6 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
427 /* ACG firmware has major version 5 */ 463 /* ACG firmware has major version 5 */
428 if ((hwmgr->smu_version & 0xff000000) == 0x5000000) 464 if ((hwmgr->smu_version & 0xff000000) == 0x5000000)
429 data->smu_features[GNLD_ACG].supported = true; 465 data->smu_features[GNLD_ACG].supported = true;
430
431 if (data->registry_data.didt_support) 466 if (data->registry_data.didt_support)
432 data->smu_features[GNLD_DIDT].supported = true; 467 data->smu_features[GNLD_DIDT].supported = true;
433 468
@@ -754,7 +789,6 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
754 uint32_t config_telemetry = 0; 789 uint32_t config_telemetry = 0;
755 struct pp_atomfwctrl_voltage_table vol_table; 790 struct pp_atomfwctrl_voltage_table vol_table;
756 struct amdgpu_device *adev = hwmgr->adev; 791 struct amdgpu_device *adev = hwmgr->adev;
757 uint32_t reg;
758 792
759 data = kzalloc(sizeof(struct vega10_hwmgr), GFP_KERNEL); 793 data = kzalloc(sizeof(struct vega10_hwmgr), GFP_KERNEL);
760 if (data == NULL) 794 if (data == NULL)
@@ -860,10 +894,7 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
860 advanceFanControlParameters.usFanPWMMinLimit * 894 advanceFanControlParameters.usFanPWMMinLimit *
861 hwmgr->thermal_controller.fanInfo.ulMaxRPM / 100; 895 hwmgr->thermal_controller.fanInfo.ulMaxRPM / 100;
862 896
863 reg = soc15_get_register_offset(DF_HWID, 0, 897 data->mem_channels = (RREG32_SOC15(DF, 0, mmDF_CS_AON0_DramBaseAddress0) &
864 mmDF_CS_AON0_DramBaseAddress0_BASE_IDX,
865 mmDF_CS_AON0_DramBaseAddress0);
866 data->mem_channels = (cgs_read_register(hwmgr->device, reg) &
867 DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK) >> 898 DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK) >>
868 DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT; 899 DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
869 PP_ASSERT_WITH_CODE(data->mem_channels < ARRAY_SIZE(channel_number), 900 PP_ASSERT_WITH_CODE(data->mem_channels < ARRAY_SIZE(channel_number),
@@ -1370,48 +1401,6 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
1370 memcpy(&(data->golden_dpm_table), &(data->dpm_table), 1401 memcpy(&(data->golden_dpm_table), &(data->dpm_table),
1371 sizeof(struct vega10_dpm_table)); 1402 sizeof(struct vega10_dpm_table));
1372 1403
1373 if (PP_CAP(PHM_PlatformCaps_ODNinACSupport) ||
1374 PP_CAP(PHM_PlatformCaps_ODNinDCSupport)) {
1375 data->odn_dpm_table.odn_core_clock_dpm_levels.num_of_pl =
1376 data->dpm_table.gfx_table.count;
1377 for (i = 0; i < data->dpm_table.gfx_table.count; i++) {
1378 data->odn_dpm_table.odn_core_clock_dpm_levels.entries[i].clock =
1379 data->dpm_table.gfx_table.dpm_levels[i].value;
1380 data->odn_dpm_table.odn_core_clock_dpm_levels.entries[i].enabled = true;
1381 }
1382
1383 data->odn_dpm_table.vdd_dependency_on_sclk.count =
1384 dep_gfx_table->count;
1385 for (i = 0; i < dep_gfx_table->count; i++) {
1386 data->odn_dpm_table.vdd_dependency_on_sclk.entries[i].clk =
1387 dep_gfx_table->entries[i].clk;
1388 data->odn_dpm_table.vdd_dependency_on_sclk.entries[i].vddInd =
1389 dep_gfx_table->entries[i].vddInd;
1390 data->odn_dpm_table.vdd_dependency_on_sclk.entries[i].cks_enable =
1391 dep_gfx_table->entries[i].cks_enable;
1392 data->odn_dpm_table.vdd_dependency_on_sclk.entries[i].cks_voffset =
1393 dep_gfx_table->entries[i].cks_voffset;
1394 }
1395
1396 data->odn_dpm_table.odn_memory_clock_dpm_levels.num_of_pl =
1397 data->dpm_table.mem_table.count;
1398 for (i = 0; i < data->dpm_table.mem_table.count; i++) {
1399 data->odn_dpm_table.odn_memory_clock_dpm_levels.entries[i].clock =
1400 data->dpm_table.mem_table.dpm_levels[i].value;
1401 data->odn_dpm_table.odn_memory_clock_dpm_levels.entries[i].enabled = true;
1402 }
1403
1404 data->odn_dpm_table.vdd_dependency_on_mclk.count = dep_mclk_table->count;
1405 for (i = 0; i < dep_mclk_table->count; i++) {
1406 data->odn_dpm_table.vdd_dependency_on_mclk.entries[i].clk =
1407 dep_mclk_table->entries[i].clk;
1408 data->odn_dpm_table.vdd_dependency_on_mclk.entries[i].vddInd =
1409 dep_mclk_table->entries[i].vddInd;
1410 data->odn_dpm_table.vdd_dependency_on_mclk.entries[i].vddci =
1411 dep_mclk_table->entries[i].vddci;
1412 }
1413 }
1414
1415 return 0; 1404 return 0;
1416} 1405}
1417 1406
@@ -1514,18 +1503,18 @@ static int vega10_populate_single_gfx_level(struct pp_hwmgr *hwmgr,
1514{ 1503{
1515 struct phm_ppt_v2_information *table_info = 1504 struct phm_ppt_v2_information *table_info =
1516 (struct phm_ppt_v2_information *)(hwmgr->pptable); 1505 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1517 struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_sclk = 1506 struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_sclk;
1518 table_info->vdd_dep_on_sclk;
1519 struct vega10_hwmgr *data = hwmgr->backend; 1507 struct vega10_hwmgr *data = hwmgr->backend;
1520 struct pp_atomfwctrl_clock_dividers_soc15 dividers; 1508 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1521 uint32_t gfx_max_clock = 1509 uint32_t gfx_max_clock =
1522 hwmgr->platform_descriptor.overdriveLimit.engineClock; 1510 hwmgr->platform_descriptor.overdriveLimit.engineClock;
1523 uint32_t i = 0; 1511 uint32_t i = 0;
1524 1512
1525 if (data->apply_overdrive_next_settings_mask & 1513 if (hwmgr->od_enabled)
1526 DPMTABLE_OD_UPDATE_VDDC)
1527 dep_on_sclk = (struct phm_ppt_v1_clock_voltage_dependency_table *) 1514 dep_on_sclk = (struct phm_ppt_v1_clock_voltage_dependency_table *)
1528 &(data->odn_dpm_table.vdd_dependency_on_sclk); 1515 &(data->odn_dpm_table.vdd_dep_on_sclk);
1516 else
1517 dep_on_sclk = table_info->vdd_dep_on_sclk;
1529 1518
1530 PP_ASSERT_WITH_CODE(dep_on_sclk, 1519 PP_ASSERT_WITH_CODE(dep_on_sclk,
1531 "Invalid SOC_VDD-GFX_CLK Dependency Table!", 1520 "Invalid SOC_VDD-GFX_CLK Dependency Table!",
@@ -1577,23 +1566,32 @@ static int vega10_populate_single_soc_level(struct pp_hwmgr *hwmgr,
1577 uint32_t soc_clock, uint8_t *current_soc_did, 1566 uint32_t soc_clock, uint8_t *current_soc_did,
1578 uint8_t *current_vol_index) 1567 uint8_t *current_vol_index)
1579{ 1568{
1569 struct vega10_hwmgr *data = hwmgr->backend;
1580 struct phm_ppt_v2_information *table_info = 1570 struct phm_ppt_v2_information *table_info =
1581 (struct phm_ppt_v2_information *)(hwmgr->pptable); 1571 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1582 struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_soc = 1572 struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_soc;
1583 table_info->vdd_dep_on_socclk;
1584 struct pp_atomfwctrl_clock_dividers_soc15 dividers; 1573 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1585 uint32_t i; 1574 uint32_t i;
1586 1575
1587 PP_ASSERT_WITH_CODE(dep_on_soc, 1576 if (hwmgr->od_enabled) {
1588 "Invalid SOC_VDD-SOC_CLK Dependency Table!", 1577 dep_on_soc = (struct phm_ppt_v1_clock_voltage_dependency_table *)
1589 return -EINVAL); 1578 &data->odn_dpm_table.vdd_dep_on_socclk;
1590 for (i = 0; i < dep_on_soc->count; i++) { 1579 for (i = 0; i < dep_on_soc->count; i++) {
1591 if (dep_on_soc->entries[i].clk == soc_clock) 1580 if (dep_on_soc->entries[i].clk >= soc_clock)
1592 break; 1581 break;
1582 }
1583 } else {
1584 dep_on_soc = table_info->vdd_dep_on_socclk;
1585 for (i = 0; i < dep_on_soc->count; i++) {
1586 if (dep_on_soc->entries[i].clk == soc_clock)
1587 break;
1588 }
1593 } 1589 }
1590
1594 PP_ASSERT_WITH_CODE(dep_on_soc->count > i, 1591 PP_ASSERT_WITH_CODE(dep_on_soc->count > i,
1595 "Cannot find SOC_CLK in SOC_VDD-SOC_CLK Dependency Table", 1592 "Cannot find SOC_CLK in SOC_VDD-SOC_CLK Dependency Table",
1596 return -EINVAL); 1593 return -EINVAL);
1594
1597 PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(hwmgr, 1595 PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(hwmgr,
1598 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, 1596 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
1599 soc_clock, &dividers), 1597 soc_clock, &dividers),
@@ -1602,22 +1600,6 @@ static int vega10_populate_single_soc_level(struct pp_hwmgr *hwmgr,
1602 1600
1603 *current_soc_did = (uint8_t)dividers.ulDid; 1601 *current_soc_did = (uint8_t)dividers.ulDid;
1604 *current_vol_index = (uint8_t)(dep_on_soc->entries[i].vddInd); 1602 *current_vol_index = (uint8_t)(dep_on_soc->entries[i].vddInd);
1605
1606 return 0;
1607}
1608
1609uint16_t vega10_locate_vddc_given_clock(struct pp_hwmgr *hwmgr,
1610 uint32_t clk,
1611 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table)
1612{
1613 uint16_t i;
1614
1615 for (i = 0; i < dep_table->count; i++) {
1616 if (dep_table->entries[i].clk == clk)
1617 return dep_table->entries[i].vddc;
1618 }
1619
1620 pr_info("[LocateVddcGivenClock] Cannot locate SOC Vddc for this clock!");
1621 return 0; 1603 return 0;
1622} 1604}
1623 1605
@@ -1631,8 +1613,6 @@ static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
1631 struct vega10_hwmgr *data = hwmgr->backend; 1613 struct vega10_hwmgr *data = hwmgr->backend;
1632 struct phm_ppt_v2_information *table_info = 1614 struct phm_ppt_v2_information *table_info =
1633 (struct phm_ppt_v2_information *)(hwmgr->pptable); 1615 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1634 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table =
1635 table_info->vdd_dep_on_socclk;
1636 PPTable_t *pp_table = &(data->smc_state_table.pp_table); 1616 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
1637 struct vega10_single_dpm_table *dpm_table = &(data->dpm_table.gfx_table); 1617 struct vega10_single_dpm_table *dpm_table = &(data->dpm_table.gfx_table);
1638 int result = 0; 1618 int result = 0;
@@ -1663,11 +1643,6 @@ static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
1663 1643
1664 dpm_table = &(data->dpm_table.soc_table); 1644 dpm_table = &(data->dpm_table.soc_table);
1665 for (i = 0; i < dpm_table->count; i++) { 1645 for (i = 0; i < dpm_table->count; i++) {
1666 pp_table->SocVid[i] =
1667 (uint8_t)convert_to_vid(
1668 vega10_locate_vddc_given_clock(hwmgr,
1669 dpm_table->dpm_levels[i].value,
1670 dep_table));
1671 result = vega10_populate_single_soc_level(hwmgr, 1646 result = vega10_populate_single_soc_level(hwmgr,
1672 dpm_table->dpm_levels[i].value, 1647 dpm_table->dpm_levels[i].value,
1673 &(pp_table->SocclkDid[i]), 1648 &(pp_table->SocclkDid[i]),
@@ -1678,7 +1653,6 @@ static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
1678 1653
1679 j = i - 1; 1654 j = i - 1;
1680 while (i < NUM_SOCCLK_DPM_LEVELS) { 1655 while (i < NUM_SOCCLK_DPM_LEVELS) {
1681 pp_table->SocVid[i] = pp_table->SocVid[j];
1682 result = vega10_populate_single_soc_level(hwmgr, 1656 result = vega10_populate_single_soc_level(hwmgr,
1683 dpm_table->dpm_levels[j].value, 1657 dpm_table->dpm_levels[j].value,
1684 &(pp_table->SocclkDid[i]), 1658 &(pp_table->SocclkDid[i]),
@@ -1691,6 +1665,32 @@ static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
1691 return result; 1665 return result;
1692} 1666}
1693 1667
1668static void vega10_populate_vddc_soc_levels(struct pp_hwmgr *hwmgr)
1669{
1670 struct vega10_hwmgr *data = hwmgr->backend;
1671 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
1672 struct phm_ppt_v2_information *table_info = hwmgr->pptable;
1673 struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table;
1674
1675 uint8_t soc_vid = 0;
1676 uint32_t i, max_vddc_level;
1677
1678 if (hwmgr->od_enabled)
1679 vddc_lookup_table = (struct phm_ppt_v1_voltage_lookup_table *)&data->odn_dpm_table.vddc_lookup_table;
1680 else
1681 vddc_lookup_table = table_info->vddc_lookup_table;
1682
1683 max_vddc_level = vddc_lookup_table->count;
1684 for (i = 0; i < max_vddc_level; i++) {
1685 soc_vid = (uint8_t)convert_to_vid(vddc_lookup_table->entries[i].us_vdd);
1686 pp_table->SocVid[i] = soc_vid;
1687 }
1688 while (i < MAX_REGULAR_DPM_NUMBER) {
1689 pp_table->SocVid[i] = soc_vid;
1690 i++;
1691 }
1692}
1693
1694/** 1694/**
1695 * @brief Populates single SMC GFXCLK structure using the provided clock. 1695 * @brief Populates single SMC GFXCLK structure using the provided clock.
1696 * 1696 *
@@ -1705,25 +1705,25 @@ static int vega10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
1705 struct vega10_hwmgr *data = hwmgr->backend; 1705 struct vega10_hwmgr *data = hwmgr->backend;
1706 struct phm_ppt_v2_information *table_info = 1706 struct phm_ppt_v2_information *table_info =
1707 (struct phm_ppt_v2_information *)(hwmgr->pptable); 1707 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1708 struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_mclk = 1708 struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_mclk;
1709 table_info->vdd_dep_on_mclk;
1710 struct pp_atomfwctrl_clock_dividers_soc15 dividers; 1709 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1711 uint32_t mem_max_clock = 1710 uint32_t mem_max_clock =
1712 hwmgr->platform_descriptor.overdriveLimit.memoryClock; 1711 hwmgr->platform_descriptor.overdriveLimit.memoryClock;
1713 uint32_t i = 0; 1712 uint32_t i = 0;
1714 1713
1715 if (data->apply_overdrive_next_settings_mask & 1714 if (hwmgr->od_enabled)
1716 DPMTABLE_OD_UPDATE_VDDC)
1717 dep_on_mclk = (struct phm_ppt_v1_clock_voltage_dependency_table *) 1715 dep_on_mclk = (struct phm_ppt_v1_clock_voltage_dependency_table *)
1718 &data->odn_dpm_table.vdd_dependency_on_mclk; 1716 &data->odn_dpm_table.vdd_dep_on_mclk;
1717 else
1718 dep_on_mclk = table_info->vdd_dep_on_mclk;
1719 1719
1720 PP_ASSERT_WITH_CODE(dep_on_mclk, 1720 PP_ASSERT_WITH_CODE(dep_on_mclk,
1721 "Invalid SOC_VDD-UCLK Dependency Table!", 1721 "Invalid SOC_VDD-UCLK Dependency Table!",
1722 return -EINVAL); 1722 return -EINVAL);
1723 1723
1724 if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_MCLK) 1724 if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_MCLK) {
1725 mem_clock = mem_clock > mem_max_clock ? mem_max_clock : mem_clock; 1725 mem_clock = mem_clock > mem_max_clock ? mem_max_clock : mem_clock;
1726 else { 1726 } else {
1727 for (i = 0; i < dep_on_mclk->count; i++) { 1727 for (i = 0; i < dep_on_mclk->count; i++) {
1728 if (dep_on_mclk->entries[i].clk == mem_clock) 1728 if (dep_on_mclk->entries[i].clk == mem_clock)
1729 break; 1729 break;
@@ -2067,6 +2067,9 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
2067 if (data->smu_features[GNLD_AVFS].supported) { 2067 if (data->smu_features[GNLD_AVFS].supported) {
2068 result = pp_atomfwctrl_get_avfs_information(hwmgr, &avfs_params); 2068 result = pp_atomfwctrl_get_avfs_information(hwmgr, &avfs_params);
2069 if (!result) { 2069 if (!result) {
2070 data->odn_dpm_table.max_vddc = avfs_params.ulMaxVddc;
2071 data->odn_dpm_table.min_vddc = avfs_params.ulMinVddc;
2072
2070 pp_table->MinVoltageVid = (uint8_t) 2073 pp_table->MinVoltageVid = (uint8_t)
2071 convert_to_vid((uint16_t)(avfs_params.ulMinVddc)); 2074 convert_to_vid((uint16_t)(avfs_params.ulMinVddc));
2072 pp_table->MaxVoltageVid = (uint8_t) 2075 pp_table->MaxVoltageVid = (uint8_t)
@@ -2345,6 +2348,22 @@ static int vega10_avfs_enable(struct pp_hwmgr *hwmgr, bool enable)
2345 return 0; 2348 return 0;
2346} 2349}
2347 2350
2351static int vega10_update_avfs(struct pp_hwmgr *hwmgr)
2352{
2353 struct vega10_hwmgr *data = hwmgr->backend;
2354
2355 if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
2356 vega10_avfs_enable(hwmgr, false);
2357 } else if (data->need_update_dpm_table) {
2358 vega10_avfs_enable(hwmgr, false);
2359 vega10_avfs_enable(hwmgr, true);
2360 } else {
2361 vega10_avfs_enable(hwmgr, true);
2362 }
2363
2364 return 0;
2365}
2366
2348static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr) 2367static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr)
2349{ 2368{
2350 int result = 0; 2369 int result = 0;
@@ -2406,6 +2425,10 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
2406 "Failed to setup default DPM tables!", 2425 "Failed to setup default DPM tables!",
2407 return result); 2426 return result);
2408 2427
2428 /* initialize ODN table */
2429 if (hwmgr->od_enabled)
2430 vega10_odn_initial_default_setting(hwmgr);
2431
2409 pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC, 2432 pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC,
2410 VOLTAGE_OBJ_SVID2, &voltage_table); 2433 VOLTAGE_OBJ_SVID2, &voltage_table);
2411 pp_table->MaxVidStep = voltage_table.max_vid_step; 2434 pp_table->MaxVidStep = voltage_table.max_vid_step;
@@ -2452,6 +2475,8 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
2452 "Failed to initialize Memory Level!", 2475 "Failed to initialize Memory Level!",
2453 return result); 2476 return result);
2454 2477
2478 vega10_populate_vddc_soc_levels(hwmgr);
2479
2455 result = vega10_populate_all_display_clock_levels(hwmgr); 2480 result = vega10_populate_all_display_clock_levels(hwmgr);
2456 PP_ASSERT_WITH_CODE(!result, 2481 PP_ASSERT_WITH_CODE(!result,
2457 "Failed to initialize Display Level!", 2482 "Failed to initialize Display Level!",
@@ -2481,6 +2506,12 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
2481 data->vbios_boot_state.mvddc = boot_up_values.usMvddc; 2506 data->vbios_boot_state.mvddc = boot_up_values.usMvddc;
2482 data->vbios_boot_state.gfx_clock = boot_up_values.ulGfxClk; 2507 data->vbios_boot_state.gfx_clock = boot_up_values.ulGfxClk;
2483 data->vbios_boot_state.mem_clock = boot_up_values.ulUClk; 2508 data->vbios_boot_state.mem_clock = boot_up_values.ulUClk;
2509 pp_atomfwctrl_get_clk_information_by_clkid(hwmgr,
2510 SMU9_SYSPLL0_SOCCLK_ID, &boot_up_values.ulSocClk);
2511
2512 pp_atomfwctrl_get_clk_information_by_clkid(hwmgr,
2513 SMU9_SYSPLL0_DCEFCLK_ID, &boot_up_values.ulDCEFClk);
2514
2484 data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk; 2515 data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk;
2485 data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk; 2516 data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk;
2486 if (0 != boot_up_values.usVddc) { 2517 if (0 != boot_up_values.usVddc) {
@@ -2829,7 +2860,7 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
2829 2860
2830 tmp_result = vega10_construct_voltage_tables(hwmgr); 2861 tmp_result = vega10_construct_voltage_tables(hwmgr);
2831 PP_ASSERT_WITH_CODE(!tmp_result, 2862 PP_ASSERT_WITH_CODE(!tmp_result,
2832 "Failed to contruct voltage tables!", 2863 "Failed to construct voltage tables!",
2833 result = tmp_result); 2864 result = tmp_result);
2834 2865
2835 tmp_result = vega10_init_smc_table(hwmgr); 2866 tmp_result = vega10_init_smc_table(hwmgr);
@@ -3028,7 +3059,6 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
3028 bool disable_mclk_switching_for_frame_lock; 3059 bool disable_mclk_switching_for_frame_lock;
3029 bool disable_mclk_switching_for_vr; 3060 bool disable_mclk_switching_for_vr;
3030 bool force_mclk_high; 3061 bool force_mclk_high;
3031 struct cgs_display_info info = {0};
3032 const struct phm_clock_and_voltage_limits *max_limits; 3062 const struct phm_clock_and_voltage_limits *max_limits;
3033 uint32_t i; 3063 uint32_t i;
3034 struct vega10_hwmgr *data = hwmgr->backend; 3064 struct vega10_hwmgr *data = hwmgr->backend;
@@ -3063,11 +3093,9 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
3063 } 3093 }
3064 } 3094 }
3065 3095
3066 cgs_get_active_displays_info(hwmgr->device, &info);
3067
3068 /* result = PHM_CheckVBlankTime(hwmgr, &vblankTooShort);*/ 3096 /* result = PHM_CheckVBlankTime(hwmgr, &vblankTooShort);*/
3069 minimum_clocks.engineClock = hwmgr->display_config.min_core_set_clock; 3097 minimum_clocks.engineClock = hwmgr->display_config->min_core_set_clock;
3070 minimum_clocks.memoryClock = hwmgr->display_config.min_mem_set_clock; 3098 minimum_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock;
3071 3099
3072 if (PP_CAP(PHM_PlatformCaps_StablePState)) { 3100 if (PP_CAP(PHM_PlatformCaps_StablePState)) {
3073 stable_pstate_sclk_dpm_percentage = 3101 stable_pstate_sclk_dpm_percentage =
@@ -3107,10 +3135,10 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
3107 PP_CAP(PHM_PlatformCaps_DisableMclkSwitchForVR); 3135 PP_CAP(PHM_PlatformCaps_DisableMclkSwitchForVR);
3108 force_mclk_high = PP_CAP(PHM_PlatformCaps_ForceMclkHigh); 3136 force_mclk_high = PP_CAP(PHM_PlatformCaps_ForceMclkHigh);
3109 3137
3110 if (info.display_count == 0) 3138 if (hwmgr->display_config->num_display == 0)
3111 disable_mclk_switching = false; 3139 disable_mclk_switching = false;
3112 else 3140 else
3113 disable_mclk_switching = (info.display_count > 1) || 3141 disable_mclk_switching = (hwmgr->display_config->num_display > 1) ||
3114 disable_mclk_switching_for_frame_lock || 3142 disable_mclk_switching_for_frame_lock ||
3115 disable_mclk_switching_for_vr || 3143 disable_mclk_switching_for_vr ||
3116 force_mclk_high; 3144 force_mclk_high;
@@ -3171,87 +3199,11 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
3171 3199
3172static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input) 3200static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input)
3173{ 3201{
3174 const struct phm_set_power_state_input *states =
3175 (const struct phm_set_power_state_input *)input;
3176 const struct vega10_power_state *vega10_ps =
3177 cast_const_phw_vega10_power_state(states->pnew_state);
3178 struct vega10_hwmgr *data = hwmgr->backend; 3202 struct vega10_hwmgr *data = hwmgr->backend;
3179 struct vega10_single_dpm_table *sclk_table =
3180 &(data->dpm_table.gfx_table);
3181 uint32_t sclk = vega10_ps->performance_levels
3182 [vega10_ps->performance_level_count - 1].gfx_clock;
3183 struct vega10_single_dpm_table *mclk_table =
3184 &(data->dpm_table.mem_table);
3185 uint32_t mclk = vega10_ps->performance_levels
3186 [vega10_ps->performance_level_count - 1].mem_clock;
3187 struct PP_Clocks min_clocks = {0};
3188 uint32_t i;
3189 struct cgs_display_info info = {0};
3190
3191 data->need_update_dpm_table = 0;
3192
3193 if (PP_CAP(PHM_PlatformCaps_ODNinACSupport) ||
3194 PP_CAP(PHM_PlatformCaps_ODNinDCSupport)) {
3195 for (i = 0; i < sclk_table->count; i++) {
3196 if (sclk == sclk_table->dpm_levels[i].value)
3197 break;
3198 }
3199
3200 if (!(data->apply_overdrive_next_settings_mask &
3201 DPMTABLE_OD_UPDATE_SCLK) && i >= sclk_table->count) {
3202 /* Check SCLK in DAL's minimum clocks
3203 * in case DeepSleep divider update is required.
3204 */
3205 if (data->display_timing.min_clock_in_sr !=
3206 min_clocks.engineClockInSR &&
3207 (min_clocks.engineClockInSR >=
3208 VEGA10_MINIMUM_ENGINE_CLOCK ||
3209 data->display_timing.min_clock_in_sr >=
3210 VEGA10_MINIMUM_ENGINE_CLOCK))
3211 data->need_update_dpm_table |= DPMTABLE_UPDATE_SCLK;
3212 }
3213
3214 cgs_get_active_displays_info(hwmgr->device, &info);
3215
3216 if (data->display_timing.num_existing_displays !=
3217 info.display_count)
3218 data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK;
3219 } else {
3220 for (i = 0; i < sclk_table->count; i++) {
3221 if (sclk == sclk_table->dpm_levels[i].value)
3222 break;
3223 }
3224
3225 if (i >= sclk_table->count)
3226 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
3227 else {
3228 /* Check SCLK in DAL's minimum clocks
3229 * in case DeepSleep divider update is required.
3230 */
3231 if (data->display_timing.min_clock_in_sr !=
3232 min_clocks.engineClockInSR &&
3233 (min_clocks.engineClockInSR >=
3234 VEGA10_MINIMUM_ENGINE_CLOCK ||
3235 data->display_timing.min_clock_in_sr >=
3236 VEGA10_MINIMUM_ENGINE_CLOCK))
3237 data->need_update_dpm_table |= DPMTABLE_UPDATE_SCLK;
3238 }
3239 3203
3240 for (i = 0; i < mclk_table->count; i++) { 3204 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
3241 if (mclk == mclk_table->dpm_levels[i].value) 3205 data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK;
3242 break;
3243 }
3244
3245 cgs_get_active_displays_info(hwmgr->device, &info);
3246 3206
3247 if (i >= mclk_table->count)
3248 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
3249
3250 if (data->display_timing.num_existing_displays !=
3251 info.display_count ||
3252 i >= mclk_table->count)
3253 data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK;
3254 }
3255 return 0; 3207 return 0;
3256} 3208}
3257 3209
@@ -3259,194 +3211,29 @@ static int vega10_populate_and_upload_sclk_mclk_dpm_levels(
3259 struct pp_hwmgr *hwmgr, const void *input) 3211 struct pp_hwmgr *hwmgr, const void *input)
3260{ 3212{
3261 int result = 0; 3213 int result = 0;
3262 const struct phm_set_power_state_input *states =
3263 (const struct phm_set_power_state_input *)input;
3264 const struct vega10_power_state *vega10_ps =
3265 cast_const_phw_vega10_power_state(states->pnew_state);
3266 struct vega10_hwmgr *data = hwmgr->backend; 3214 struct vega10_hwmgr *data = hwmgr->backend;
3267 uint32_t sclk = vega10_ps->performance_levels
3268 [vega10_ps->performance_level_count - 1].gfx_clock;
3269 uint32_t mclk = vega10_ps->performance_levels
3270 [vega10_ps->performance_level_count - 1].mem_clock;
3271 struct vega10_dpm_table *dpm_table = &data->dpm_table;
3272 struct vega10_dpm_table *golden_dpm_table =
3273 &data->golden_dpm_table;
3274 uint32_t dpm_count, clock_percent;
3275 uint32_t i;
3276 3215
3277 if (PP_CAP(PHM_PlatformCaps_ODNinACSupport) || 3216 if (!data->need_update_dpm_table)
3278 PP_CAP(PHM_PlatformCaps_ODNinDCSupport)) { 3217 return 0;
3279
3280 if (!data->need_update_dpm_table &&
3281 !data->apply_optimized_settings &&
3282 !data->apply_overdrive_next_settings_mask)
3283 return 0;
3284
3285 if (data->apply_overdrive_next_settings_mask &
3286 DPMTABLE_OD_UPDATE_SCLK) {
3287 for (dpm_count = 0;
3288 dpm_count < dpm_table->gfx_table.count;
3289 dpm_count++) {
3290 dpm_table->gfx_table.dpm_levels[dpm_count].enabled =
3291 data->odn_dpm_table.odn_core_clock_dpm_levels.entries[dpm_count].enabled;
3292 dpm_table->gfx_table.dpm_levels[dpm_count].value =
3293 data->odn_dpm_table.odn_core_clock_dpm_levels.entries[dpm_count].clock;
3294 }
3295 }
3296
3297 if (data->apply_overdrive_next_settings_mask &
3298 DPMTABLE_OD_UPDATE_MCLK) {
3299 for (dpm_count = 0;
3300 dpm_count < dpm_table->mem_table.count;
3301 dpm_count++) {
3302 dpm_table->mem_table.dpm_levels[dpm_count].enabled =
3303 data->odn_dpm_table.odn_memory_clock_dpm_levels.entries[dpm_count].enabled;
3304 dpm_table->mem_table.dpm_levels[dpm_count].value =
3305 data->odn_dpm_table.odn_memory_clock_dpm_levels.entries[dpm_count].clock;
3306 }
3307 }
3308
3309 if ((data->need_update_dpm_table & DPMTABLE_UPDATE_SCLK) ||
3310 data->apply_optimized_settings ||
3311 (data->apply_overdrive_next_settings_mask &
3312 DPMTABLE_OD_UPDATE_SCLK)) {
3313 result = vega10_populate_all_graphic_levels(hwmgr);
3314 PP_ASSERT_WITH_CODE(!result,
3315 "Failed to populate SCLK during PopulateNewDPMClocksStates Function!",
3316 return result);
3317 }
3318
3319 if ((data->need_update_dpm_table & DPMTABLE_UPDATE_MCLK) ||
3320 (data->apply_overdrive_next_settings_mask &
3321 DPMTABLE_OD_UPDATE_MCLK)){
3322 result = vega10_populate_all_memory_levels(hwmgr);
3323 PP_ASSERT_WITH_CODE(!result,
3324 "Failed to populate MCLK during PopulateNewDPMClocksStates Function!",
3325 return result);
3326 }
3327 } else {
3328 if (!data->need_update_dpm_table &&
3329 !data->apply_optimized_settings)
3330 return 0;
3331
3332 if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_SCLK &&
3333 data->smu_features[GNLD_DPM_GFXCLK].supported) {
3334 dpm_table->
3335 gfx_table.dpm_levels[dpm_table->gfx_table.count - 1].
3336 value = sclk;
3337 if (hwmgr->od_enabled) {
3338 /* Need to do calculation based on the golden DPM table
3339 * as the Heatmap GPU Clock axis is also based on
3340 * the default values
3341 */
3342 PP_ASSERT_WITH_CODE(
3343 golden_dpm_table->gfx_table.dpm_levels
3344 [golden_dpm_table->gfx_table.count - 1].value,
3345 "Divide by 0!",
3346 return -1);
3347
3348 dpm_count = dpm_table->gfx_table.count < 2 ?
3349 0 : dpm_table->gfx_table.count - 2;
3350 for (i = dpm_count; i > 1; i--) {
3351 if (sclk > golden_dpm_table->gfx_table.dpm_levels
3352 [golden_dpm_table->gfx_table.count - 1].value) {
3353 clock_percent =
3354 ((sclk - golden_dpm_table->gfx_table.dpm_levels
3355 [golden_dpm_table->gfx_table.count - 1].value) *
3356 100) /
3357 golden_dpm_table->gfx_table.dpm_levels
3358 [golden_dpm_table->gfx_table.count - 1].value;
3359
3360 dpm_table->gfx_table.dpm_levels[i].value =
3361 golden_dpm_table->gfx_table.dpm_levels[i].value +
3362 (golden_dpm_table->gfx_table.dpm_levels[i].value *
3363 clock_percent) / 100;
3364 } else if (golden_dpm_table->
3365 gfx_table.dpm_levels[dpm_table->gfx_table.count-1].value >
3366 sclk) {
3367 clock_percent =
3368 ((golden_dpm_table->gfx_table.dpm_levels
3369 [golden_dpm_table->gfx_table.count - 1].value -
3370 sclk) * 100) /
3371 golden_dpm_table->gfx_table.dpm_levels
3372 [golden_dpm_table->gfx_table.count-1].value;
3373
3374 dpm_table->gfx_table.dpm_levels[i].value =
3375 golden_dpm_table->gfx_table.dpm_levels[i].value -
3376 (golden_dpm_table->gfx_table.dpm_levels[i].value *
3377 clock_percent) / 100;
3378 } else
3379 dpm_table->gfx_table.dpm_levels[i].value =
3380 golden_dpm_table->gfx_table.dpm_levels[i].value;
3381 }
3382 }
3383 }
3384 3218
3385 if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_MCLK && 3219 if (data->need_update_dpm_table &
3386 data->smu_features[GNLD_DPM_UCLK].supported) { 3220 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK + DPMTABLE_UPDATE_SOCCLK)) {
3387 dpm_table-> 3221 result = vega10_populate_all_graphic_levels(hwmgr);
3388 mem_table.dpm_levels[dpm_table->mem_table.count - 1]. 3222 PP_ASSERT_WITH_CODE((0 == result),
3389 value = mclk; 3223 "Failed to populate SCLK during PopulateNewDPMClocksStates Function!",
3224 return result);
3225 }
3390 3226
3391 if (hwmgr->od_enabled) { 3227 if (data->need_update_dpm_table &
3392 PP_ASSERT_WITH_CODE( 3228 (DPMTABLE_OD_UPDATE_MCLK + DPMTABLE_UPDATE_MCLK)) {
3393 golden_dpm_table->mem_table.dpm_levels 3229 result = vega10_populate_all_memory_levels(hwmgr);
3394 [golden_dpm_table->mem_table.count - 1].value, 3230 PP_ASSERT_WITH_CODE((0 == result),
3395 "Divide by 0!", 3231 "Failed to populate MCLK during PopulateNewDPMClocksStates Function!",
3396 return -1); 3232 return result);
3233 }
3397 3234
3398 dpm_count = dpm_table->mem_table.count < 2 ? 3235 vega10_populate_vddc_soc_levels(hwmgr);
3399 0 : dpm_table->mem_table.count - 2;
3400 for (i = dpm_count; i > 1; i--) {
3401 if (mclk > golden_dpm_table->mem_table.dpm_levels
3402 [golden_dpm_table->mem_table.count-1].value) {
3403 clock_percent = ((mclk -
3404 golden_dpm_table->mem_table.dpm_levels
3405 [golden_dpm_table->mem_table.count-1].value) *
3406 100) /
3407 golden_dpm_table->mem_table.dpm_levels
3408 [golden_dpm_table->mem_table.count-1].value;
3409
3410 dpm_table->mem_table.dpm_levels[i].value =
3411 golden_dpm_table->mem_table.dpm_levels[i].value +
3412 (golden_dpm_table->mem_table.dpm_levels[i].value *
3413 clock_percent) / 100;
3414 } else if (golden_dpm_table->mem_table.dpm_levels
3415 [dpm_table->mem_table.count-1].value > mclk) {
3416 clock_percent = ((golden_dpm_table->mem_table.dpm_levels
3417 [golden_dpm_table->mem_table.count-1].value - mclk) *
3418 100) /
3419 golden_dpm_table->mem_table.dpm_levels
3420 [golden_dpm_table->mem_table.count-1].value;
3421
3422 dpm_table->mem_table.dpm_levels[i].value =
3423 golden_dpm_table->mem_table.dpm_levels[i].value -
3424 (golden_dpm_table->mem_table.dpm_levels[i].value *
3425 clock_percent) / 100;
3426 } else
3427 dpm_table->mem_table.dpm_levels[i].value =
3428 golden_dpm_table->mem_table.dpm_levels[i].value;
3429 }
3430 }
3431 }
3432 3236
3433 if ((data->need_update_dpm_table &
3434 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK)) ||
3435 data->apply_optimized_settings) {
3436 result = vega10_populate_all_graphic_levels(hwmgr);
3437 PP_ASSERT_WITH_CODE(!result,
3438 "Failed to populate SCLK during PopulateNewDPMClocksStates Function!",
3439 return result);
3440 }
3441
3442 if (data->need_update_dpm_table &
3443 (DPMTABLE_OD_UPDATE_MCLK + DPMTABLE_UPDATE_MCLK)) {
3444 result = vega10_populate_all_memory_levels(hwmgr);
3445 PP_ASSERT_WITH_CODE(!result,
3446 "Failed to populate MCLK during PopulateNewDPMClocksStates Function!",
3447 return result);
3448 }
3449 }
3450 return result; 3237 return result;
3451} 3238}
3452 3239
@@ -3742,8 +3529,9 @@ static int vega10_set_power_state_tasks(struct pp_hwmgr *hwmgr,
3742 PP_ASSERT_WITH_CODE(!result, 3529 PP_ASSERT_WITH_CODE(!result,
3743 "Failed to upload PPtable!", return result); 3530 "Failed to upload PPtable!", return result);
3744 3531
3745 data->apply_optimized_settings = false; 3532 vega10_update_avfs(hwmgr);
3746 data->apply_overdrive_next_settings_mask = 0; 3533
3534 data->need_update_dpm_table &= DPMTABLE_OD_UPDATE_VDDC;
3747 3535
3748 return 0; 3536 return 0;
3749} 3537}
@@ -3793,16 +3581,18 @@ static uint32_t vega10_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
3793} 3581}
3794 3582
3795static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr, 3583static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr,
3796 struct pp_gpu_power *query) 3584 uint32_t *query)
3797{ 3585{
3798 uint32_t value; 3586 uint32_t value;
3799 3587
3588 if (!query)
3589 return -EINVAL;
3590
3800 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr); 3591 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr);
3801 value = smum_get_argument(hwmgr); 3592 value = smum_get_argument(hwmgr);
3802 3593
3803 /* power value is an integer */ 3594 /* SMC returning actual watts, keep consistent with legacy asics, low 8 bit as 8 fractional bits */
3804 memset(query, 0, sizeof *query); 3595 *query = value << 8;
3805 query->average_gpu_power = value << 8;
3806 3596
3807 return 0; 3597 return 0;
3808} 3598}
@@ -3810,22 +3600,18 @@ static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr,
3810static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx, 3600static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
3811 void *value, int *size) 3601 void *value, int *size)
3812{ 3602{
3813 uint32_t sclk_idx, mclk_idx, activity_percent = 0; 3603 struct amdgpu_device *adev = hwmgr->adev;
3604 uint32_t sclk_mhz, mclk_idx, activity_percent = 0;
3814 struct vega10_hwmgr *data = hwmgr->backend; 3605 struct vega10_hwmgr *data = hwmgr->backend;
3815 struct vega10_dpm_table *dpm_table = &data->dpm_table; 3606 struct vega10_dpm_table *dpm_table = &data->dpm_table;
3816 int ret = 0; 3607 int ret = 0;
3817 uint32_t reg, val_vid; 3608 uint32_t val_vid;
3818 3609
3819 switch (idx) { 3610 switch (idx) {
3820 case AMDGPU_PP_SENSOR_GFX_SCLK: 3611 case AMDGPU_PP_SENSOR_GFX_SCLK:
3821 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex); 3612 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetAverageGfxclkActualFrequency);
3822 sclk_idx = smum_get_argument(hwmgr); 3613 sclk_mhz = smum_get_argument(hwmgr);
3823 if (sclk_idx < dpm_table->gfx_table.count) { 3614 *((uint32_t *)value) = sclk_mhz * 100;
3824 *((uint32_t *)value) = dpm_table->gfx_table.dpm_levels[sclk_idx].value;
3825 *size = 4;
3826 } else {
3827 ret = -EINVAL;
3828 }
3829 break; 3615 break;
3830 case AMDGPU_PP_SENSOR_GFX_MCLK: 3616 case AMDGPU_PP_SENSOR_GFX_MCLK:
3831 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex); 3617 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex);
@@ -3856,18 +3642,10 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
3856 *size = 4; 3642 *size = 4;
3857 break; 3643 break;
3858 case AMDGPU_PP_SENSOR_GPU_POWER: 3644 case AMDGPU_PP_SENSOR_GPU_POWER:
3859 if (*size < sizeof(struct pp_gpu_power)) 3645 ret = vega10_get_gpu_power(hwmgr, (uint32_t *)value);
3860 ret = -EINVAL;
3861 else {
3862 *size = sizeof(struct pp_gpu_power);
3863 ret = vega10_get_gpu_power(hwmgr, (struct pp_gpu_power *)value);
3864 }
3865 break; 3646 break;
3866 case AMDGPU_PP_SENSOR_VDDGFX: 3647 case AMDGPU_PP_SENSOR_VDDGFX:
3867 reg = soc15_get_register_offset(SMUIO_HWID, 0, 3648 val_vid = (RREG32_SOC15(SMUIO, 0, mmSMUSVI0_PLANE0_CURRENTVID) &
3868 mmSMUSVI0_PLANE0_CURRENTVID_BASE_IDX,
3869 mmSMUSVI0_PLANE0_CURRENTVID);
3870 val_vid = (cgs_read_register(hwmgr->device, reg) &
3871 SMUSVI0_PLANE0_CURRENTVID__CURRENT_SVI0_PLANE0_VID_MASK) >> 3649 SMUSVI0_PLANE0_CURRENTVID__CURRENT_SVI0_PLANE0_VID_MASK) >>
3872 SMUSVI0_PLANE0_CURRENTVID__CURRENT_SVI0_PLANE0_VID__SHIFT; 3650 SMUSVI0_PLANE0_CURRENTVID__CURRENT_SVI0_PLANE0_VID__SHIFT;
3873 *((uint32_t *)value) = (uint32_t)convert_to_vddc((uint8_t)val_vid); 3651 *((uint32_t *)value) = (uint32_t)convert_to_vddc((uint8_t)val_vid);
@@ -3956,26 +3734,18 @@ static int vega10_notify_smc_display_config_after_ps_adjustment(
3956 (struct phm_ppt_v2_information *)hwmgr->pptable; 3734 (struct phm_ppt_v2_information *)hwmgr->pptable;
3957 struct phm_ppt_v1_clock_voltage_dependency_table *mclk_table = table_info->vdd_dep_on_mclk; 3735 struct phm_ppt_v1_clock_voltage_dependency_table *mclk_table = table_info->vdd_dep_on_mclk;
3958 uint32_t idx; 3736 uint32_t idx;
3959 uint32_t num_active_disps = 0;
3960 struct cgs_display_info info = {0};
3961 struct PP_Clocks min_clocks = {0}; 3737 struct PP_Clocks min_clocks = {0};
3962 uint32_t i; 3738 uint32_t i;
3963 struct pp_display_clock_request clock_req; 3739 struct pp_display_clock_request clock_req;
3964 3740
3965 info.mode_info = NULL; 3741 if (hwmgr->display_config->num_display > 1)
3966
3967 cgs_get_active_displays_info(hwmgr->device, &info);
3968
3969 num_active_disps = info.display_count;
3970
3971 if (num_active_disps > 1)
3972 vega10_notify_smc_display_change(hwmgr, false); 3742 vega10_notify_smc_display_change(hwmgr, false);
3973 else 3743 else
3974 vega10_notify_smc_display_change(hwmgr, true); 3744 vega10_notify_smc_display_change(hwmgr, true);
3975 3745
3976 min_clocks.dcefClock = hwmgr->display_config.min_dcef_set_clk; 3746 min_clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk;
3977 min_clocks.dcefClockInSR = hwmgr->display_config.min_dcef_deep_sleep_set_clk; 3747 min_clocks.dcefClockInSR = hwmgr->display_config->min_dcef_deep_sleep_set_clk;
3978 min_clocks.memoryClock = hwmgr->display_config.min_mem_set_clock; 3748 min_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock;
3979 3749
3980 for (i = 0; i < dpm_table->count; i++) { 3750 for (i = 0; i < dpm_table->count; i++) {
3981 if (dpm_table->dpm_levels[i].value == min_clocks.dcefClock) 3751 if (dpm_table->dpm_levels[i].value == min_clocks.dcefClock)
@@ -4120,6 +3890,47 @@ static void vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
4120 } 3890 }
4121} 3891}
4122 3892
3893static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
3894 enum pp_clock_type type, uint32_t mask)
3895{
3896 struct vega10_hwmgr *data = hwmgr->backend;
3897
3898 switch (type) {
3899 case PP_SCLK:
3900 data->smc_state_table.gfx_boot_level = mask ? (ffs(mask) - 1) : 0;
3901 data->smc_state_table.gfx_max_level = mask ? (fls(mask) - 1) : 0;
3902
3903 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
3904 "Failed to upload boot level to lowest!",
3905 return -EINVAL);
3906
3907 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
3908 "Failed to upload dpm max level to highest!",
3909 return -EINVAL);
3910 break;
3911
3912 case PP_MCLK:
3913 data->smc_state_table.mem_boot_level = mask ? (ffs(mask) - 1) : 0;
3914 data->smc_state_table.mem_max_level = mask ? (fls(mask) - 1) : 0;
3915
3916 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
3917 "Failed to upload boot level to lowest!",
3918 return -EINVAL);
3919
3920 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
3921 "Failed to upload dpm max level to highest!",
3922 return -EINVAL);
3923
3924 break;
3925
3926 case PP_PCIE:
3927 default:
3928 break;
3929 }
3930
3931 return 0;
3932}
3933
4123static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, 3934static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
4124 enum amd_dpm_forced_level level) 3935 enum amd_dpm_forced_level level)
4125{ 3936{
@@ -4356,97 +4167,15 @@ static int vega10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr,
4356 struct vega10_hwmgr *data = hwmgr->backend; 4167 struct vega10_hwmgr *data = hwmgr->backend;
4357 Watermarks_t *table = &(data->smc_state_table.water_marks_table); 4168 Watermarks_t *table = &(data->smc_state_table.water_marks_table);
4358 int result = 0; 4169 int result = 0;
4359 uint32_t i;
4360 4170
4361 if (!data->registry_data.disable_water_mark) { 4171 if (!data->registry_data.disable_water_mark) {
4362 for (i = 0; i < wm_with_clock_ranges->num_wm_sets_dmif; i++) { 4172 smu_set_watermarks_for_clocks_ranges(table, wm_with_clock_ranges);
4363 table->WatermarkRow[WM_DCEFCLK][i].MinClock =
4364 cpu_to_le16((uint16_t)
4365 (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_dcefclk_in_khz) /
4366 100);
4367 table->WatermarkRow[WM_DCEFCLK][i].MaxClock =
4368 cpu_to_le16((uint16_t)
4369 (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_dcefclk_in_khz) /
4370 100);
4371 table->WatermarkRow[WM_DCEFCLK][i].MinUclk =
4372 cpu_to_le16((uint16_t)
4373 (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_memclk_in_khz) /
4374 100);
4375 table->WatermarkRow[WM_DCEFCLK][i].MaxUclk =
4376 cpu_to_le16((uint16_t)
4377 (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_memclk_in_khz) /
4378 100);
4379 table->WatermarkRow[WM_DCEFCLK][i].WmSetting = (uint8_t)
4380 wm_with_clock_ranges->wm_sets_dmif[i].wm_set_id;
4381 }
4382
4383 for (i = 0; i < wm_with_clock_ranges->num_wm_sets_mcif; i++) {
4384 table->WatermarkRow[WM_SOCCLK][i].MinClock =
4385 cpu_to_le16((uint16_t)
4386 (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_socclk_in_khz) /
4387 100);
4388 table->WatermarkRow[WM_SOCCLK][i].MaxClock =
4389 cpu_to_le16((uint16_t)
4390 (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_socclk_in_khz) /
4391 100);
4392 table->WatermarkRow[WM_SOCCLK][i].MinUclk =
4393 cpu_to_le16((uint16_t)
4394 (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_memclk_in_khz) /
4395 100);
4396 table->WatermarkRow[WM_SOCCLK][i].MaxUclk =
4397 cpu_to_le16((uint16_t)
4398 (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_memclk_in_khz) /
4399 100);
4400 table->WatermarkRow[WM_SOCCLK][i].WmSetting = (uint8_t)
4401 wm_with_clock_ranges->wm_sets_mcif[i].wm_set_id;
4402 }
4403 data->water_marks_bitmap = WaterMarksExist; 4173 data->water_marks_bitmap = WaterMarksExist;
4404 } 4174 }
4405 4175
4406 return result; 4176 return result;
4407} 4177}
4408 4178
4409static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
4410 enum pp_clock_type type, uint32_t mask)
4411{
4412 struct vega10_hwmgr *data = hwmgr->backend;
4413
4414 switch (type) {
4415 case PP_SCLK:
4416 data->smc_state_table.gfx_boot_level = mask ? (ffs(mask) - 1) : 0;
4417 data->smc_state_table.gfx_max_level = mask ? (fls(mask) - 1) : 0;
4418
4419 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
4420 "Failed to upload boot level to lowest!",
4421 return -EINVAL);
4422
4423 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
4424 "Failed to upload dpm max level to highest!",
4425 return -EINVAL);
4426 break;
4427
4428 case PP_MCLK:
4429 data->smc_state_table.mem_boot_level = mask ? (ffs(mask) - 1) : 0;
4430 data->smc_state_table.mem_max_level = mask ? (fls(mask) - 1) : 0;
4431
4432 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
4433 "Failed to upload boot level to lowest!",
4434 return -EINVAL);
4435
4436 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
4437 "Failed to upload dpm max level to highest!",
4438 return -EINVAL);
4439
4440 break;
4441
4442 case PP_PCIE:
4443 default:
4444 break;
4445 }
4446
4447 return 0;
4448}
4449
4450static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, 4179static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
4451 enum pp_clock_type type, char *buf) 4180 enum pp_clock_type type, char *buf)
4452{ 4181{
@@ -4454,6 +4183,8 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
4454 struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); 4183 struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
4455 struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); 4184 struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
4456 struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table); 4185 struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table);
4186 struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep = NULL;
4187
4457 int i, now, size = 0; 4188 int i, now, size = 0;
4458 4189
4459 switch (type) { 4190 switch (type) {
@@ -4492,6 +4223,40 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
4492 (pcie_table->pcie_gen[i] == 2) ? "8.0GT/s, x16" : "", 4223 (pcie_table->pcie_gen[i] == 2) ? "8.0GT/s, x16" : "",
4493 (i == now) ? "*" : ""); 4224 (i == now) ? "*" : "");
4494 break; 4225 break;
4226 case OD_SCLK:
4227 if (hwmgr->od_enabled) {
4228 size = sprintf(buf, "%s:\n", "OD_SCLK");
4229 podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
4230 for (i = 0; i < podn_vdd_dep->count; i++)
4231 size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
4232 i, podn_vdd_dep->entries[i].clk / 100,
4233 podn_vdd_dep->entries[i].vddc);
4234 }
4235 break;
4236 case OD_MCLK:
4237 if (hwmgr->od_enabled) {
4238 size = sprintf(buf, "%s:\n", "OD_MCLK");
4239 podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
4240 for (i = 0; i < podn_vdd_dep->count; i++)
4241 size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
4242 i, podn_vdd_dep->entries[i].clk/100,
4243 podn_vdd_dep->entries[i].vddc);
4244 }
4245 break;
4246 case OD_RANGE:
4247 if (hwmgr->od_enabled) {
4248 size = sprintf(buf, "%s:\n", "OD_RANGE");
4249 size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
4250 data->golden_dpm_table.gfx_table.dpm_levels[0].value/100,
4251 hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
4252 size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n",
4253 data->golden_dpm_table.mem_table.dpm_levels[0].value/100,
4254 hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
4255 size += sprintf(buf + size, "VDDC: %7umV %11umV\n",
4256 data->odn_dpm_table.min_vddc,
4257 data->odn_dpm_table.max_vddc);
4258 }
4259 break;
4495 default: 4260 default:
4496 break; 4261 break;
4497 } 4262 }
@@ -4501,10 +4266,8 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
4501static int vega10_display_configuration_changed_task(struct pp_hwmgr *hwmgr) 4266static int vega10_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
4502{ 4267{
4503 struct vega10_hwmgr *data = hwmgr->backend; 4268 struct vega10_hwmgr *data = hwmgr->backend;
4504 int result = 0;
4505 uint32_t num_turned_on_displays = 1;
4506 Watermarks_t *wm_table = &(data->smc_state_table.water_marks_table); 4269 Watermarks_t *wm_table = &(data->smc_state_table.water_marks_table);
4507 struct cgs_display_info info = {0}; 4270 int result = 0;
4508 4271
4509 if ((data->water_marks_bitmap & WaterMarksExist) && 4272 if ((data->water_marks_bitmap & WaterMarksExist) &&
4510 !(data->water_marks_bitmap & WaterMarksLoaded)) { 4273 !(data->water_marks_bitmap & WaterMarksLoaded)) {
@@ -4514,10 +4277,8 @@ static int vega10_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
4514 } 4277 }
4515 4278
4516 if (data->water_marks_bitmap & WaterMarksLoaded) { 4279 if (data->water_marks_bitmap & WaterMarksLoaded) {
4517 cgs_get_active_displays_info(hwmgr->device, &info);
4518 num_turned_on_displays = info.display_count;
4519 smum_send_msg_to_smc_with_parameter(hwmgr, 4280 smum_send_msg_to_smc_with_parameter(hwmgr,
4520 PPSMC_MSG_NumOfDisplays, num_turned_on_displays); 4281 PPSMC_MSG_NumOfDisplays, hwmgr->display_config->num_display);
4521 } 4282 }
4522 4283
4523 return result; 4284 return result;
@@ -4603,15 +4364,12 @@ vega10_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmg
4603{ 4364{
4604 struct vega10_hwmgr *data = hwmgr->backend; 4365 struct vega10_hwmgr *data = hwmgr->backend;
4605 bool is_update_required = false; 4366 bool is_update_required = false;
4606 struct cgs_display_info info = {0, 0, NULL};
4607 4367
4608 cgs_get_active_displays_info(hwmgr->device, &info); 4368 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
4609
4610 if (data->display_timing.num_existing_displays != info.display_count)
4611 is_update_required = true; 4369 is_update_required = true;
4612 4370
4613 if (PP_CAP(PHM_PlatformCaps_SclkDeepSleep)) { 4371 if (PP_CAP(PHM_PlatformCaps_SclkDeepSleep)) {
4614 if (data->display_timing.min_clock_in_sr != hwmgr->display_config.min_core_set_clock_in_sr) 4372 if (data->display_timing.min_clock_in_sr != hwmgr->display_config->min_core_set_clock_in_sr)
4615 is_update_required = true; 4373 is_update_required = true;
4616 } 4374 }
4617 4375
@@ -4886,6 +4644,200 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
4886 return 0; 4644 return 0;
4887} 4645}
4888 4646
4647
4648static bool vega10_check_clk_voltage_valid(struct pp_hwmgr *hwmgr,
4649 enum PP_OD_DPM_TABLE_COMMAND type,
4650 uint32_t clk,
4651 uint32_t voltage)
4652{
4653 struct vega10_hwmgr *data = hwmgr->backend;
4654 struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);
4655 struct vega10_single_dpm_table *golden_table;
4656
4657 if (voltage < odn_table->min_vddc || voltage > odn_table->max_vddc) {
4658 pr_info("OD voltage is out of range [%d - %d] mV\n", odn_table->min_vddc, odn_table->max_vddc);
4659 return false;
4660 }
4661
4662 if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
4663 golden_table = &(data->golden_dpm_table.gfx_table);
4664 if (golden_table->dpm_levels[0].value > clk ||
4665 hwmgr->platform_descriptor.overdriveLimit.engineClock < clk) {
4666 pr_info("OD engine clock is out of range [%d - %d] MHz\n",
4667 golden_table->dpm_levels[0].value/100,
4668 hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
4669 return false;
4670 }
4671 } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
4672 golden_table = &(data->golden_dpm_table.mem_table);
4673 if (golden_table->dpm_levels[0].value > clk ||
4674 hwmgr->platform_descriptor.overdriveLimit.memoryClock < clk) {
4675 pr_info("OD memory clock is out of range [%d - %d] MHz\n",
4676 golden_table->dpm_levels[0].value/100,
4677 hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
4678 return false;
4679 }
4680 } else {
4681 return false;
4682 }
4683
4684 return true;
4685}
4686
4687static void vega10_check_dpm_table_updated(struct pp_hwmgr *hwmgr)
4688{
4689 struct vega10_hwmgr *data = hwmgr->backend;
4690 struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);
4691 struct phm_ppt_v2_information *table_info = hwmgr->pptable;
4692 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table;
4693 struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table;
4694 uint32_t i;
4695
4696 dep_table = table_info->vdd_dep_on_mclk;
4697 odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_mclk);
4698
4699 for (i = 0; i < dep_table->count; i++) {
4700 if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
4701 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;
4702 return;
4703 }
4704 }
4705
4706 dep_table = table_info->vdd_dep_on_sclk;
4707 odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_sclk);
4708 for (i = 0; i < dep_table->count; i++) {
4709 if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
4710 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;
4711 return;
4712 }
4713 }
4714
4715 if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
4716 data->need_update_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
4717 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK;
4718 }
4719}
4720
4721static void vega10_odn_update_soc_table(struct pp_hwmgr *hwmgr,
4722 enum PP_OD_DPM_TABLE_COMMAND type)
4723{
4724 struct vega10_hwmgr *data = hwmgr->backend;
4725 struct phm_ppt_v2_information *table_info = hwmgr->pptable;
4726 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table = table_info->vdd_dep_on_socclk;
4727 struct vega10_single_dpm_table *dpm_table = &data->golden_dpm_table.soc_table;
4728
4729 struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep_on_socclk =
4730 &data->odn_dpm_table.vdd_dep_on_socclk;
4731 struct vega10_odn_vddc_lookup_table *od_vddc_lookup_table = &data->odn_dpm_table.vddc_lookup_table;
4732
4733 struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep;
4734 uint8_t i, j;
4735
4736 if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
4737 podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
4738 for (i = 0; i < podn_vdd_dep->count - 1; i++)
4739 od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc;
4740 if (od_vddc_lookup_table->entries[i].us_vdd < podn_vdd_dep->entries[i].vddc)
4741 od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc;
4742 } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
4743 podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
4744 for (i = 0; i < dpm_table->count; i++) {
4745 for (j = 0; j < od_vddc_lookup_table->count; j++) {
4746 if (od_vddc_lookup_table->entries[j].us_vdd >
4747 podn_vdd_dep->entries[i].vddc)
4748 break;
4749 }
4750 if (j == od_vddc_lookup_table->count) {
4751 od_vddc_lookup_table->entries[j-1].us_vdd =
4752 podn_vdd_dep->entries[i].vddc;
4753 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
4754 }
4755 podn_vdd_dep->entries[i].vddInd = j;
4756 }
4757 dpm_table = &data->dpm_table.soc_table;
4758 for (i = 0; i < dep_table->count; i++) {
4759 if (dep_table->entries[i].vddInd == podn_vdd_dep->entries[dep_table->count-1].vddInd &&
4760 dep_table->entries[i].clk < podn_vdd_dep->entries[dep_table->count-1].clk) {
4761 data->need_update_dpm_table |= DPMTABLE_UPDATE_SOCCLK;
4762 podn_vdd_dep_on_socclk->entries[i].clk = podn_vdd_dep->entries[dep_table->count-1].clk;
4763 dpm_table->dpm_levels[i].value = podn_vdd_dep_on_socclk->entries[i].clk;
4764 }
4765 }
4766 if (podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].clk <
4767 podn_vdd_dep->entries[dep_table->count-1].clk) {
4768 data->need_update_dpm_table |= DPMTABLE_UPDATE_SOCCLK;
4769 podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].clk = podn_vdd_dep->entries[dep_table->count-1].clk;
4770 dpm_table->dpm_levels[podn_vdd_dep_on_socclk->count - 1].value = podn_vdd_dep->entries[dep_table->count-1].clk;
4771 }
4772 if (podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].vddInd <
4773 podn_vdd_dep->entries[dep_table->count-1].vddInd) {
4774 data->need_update_dpm_table |= DPMTABLE_UPDATE_SOCCLK;
4775 podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].vddInd = podn_vdd_dep->entries[dep_table->count-1].vddInd;
4776 }
4777 }
4778}
4779
4780static int vega10_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
4781 enum PP_OD_DPM_TABLE_COMMAND type,
4782 long *input, uint32_t size)
4783{
4784 struct vega10_hwmgr *data = hwmgr->backend;
4785 struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep_table;
4786 struct vega10_single_dpm_table *dpm_table;
4787
4788 uint32_t input_clk;
4789 uint32_t input_vol;
4790 uint32_t input_level;
4791 uint32_t i;
4792
4793 PP_ASSERT_WITH_CODE(input, "NULL user input for clock and voltage",
4794 return -EINVAL);
4795
4796 if (!hwmgr->od_enabled) {
4797 pr_info("OverDrive feature not enabled\n");
4798 return -EINVAL;
4799 }
4800
4801 if (PP_OD_EDIT_SCLK_VDDC_TABLE == type) {
4802 dpm_table = &data->dpm_table.gfx_table;
4803 podn_vdd_dep_table = &data->odn_dpm_table.vdd_dep_on_sclk;
4804 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
4805 } else if (PP_OD_EDIT_MCLK_VDDC_TABLE == type) {
4806 dpm_table = &data->dpm_table.mem_table;
4807 podn_vdd_dep_table = &data->odn_dpm_table.vdd_dep_on_mclk;
4808 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
4809 } else if (PP_OD_RESTORE_DEFAULT_TABLE == type) {
4810 memcpy(&(data->dpm_table), &(data->golden_dpm_table), sizeof(struct vega10_dpm_table));
4811 vega10_odn_initial_default_setting(hwmgr);
4812 return 0;
4813 } else if (PP_OD_COMMIT_DPM_TABLE == type) {
4814 vega10_check_dpm_table_updated(hwmgr);
4815 return 0;
4816 } else {
4817 return -EINVAL;
4818 }
4819
4820 for (i = 0; i < size; i += 3) {
4821 if (i + 3 > size || input[i] >= podn_vdd_dep_table->count) {
4822 pr_info("invalid clock voltage input\n");
4823 return 0;
4824 }
4825 input_level = input[i];
4826 input_clk = input[i+1] * 100;
4827 input_vol = input[i+2];
4828
4829 if (vega10_check_clk_voltage_valid(hwmgr, type, input_clk, input_vol)) {
4830 dpm_table->dpm_levels[input_level].value = input_clk;
4831 podn_vdd_dep_table->entries[input_level].clk = input_clk;
4832 podn_vdd_dep_table->entries[input_level].vddc = input_vol;
4833 } else {
4834 return -EINVAL;
4835 }
4836 }
4837 vega10_odn_update_soc_table(hwmgr, type);
4838 return 0;
4839}
4840
4889static const struct pp_hwmgr_func vega10_hwmgr_funcs = { 4841static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
4890 .backend_init = vega10_hwmgr_backend_init, 4842 .backend_init = vega10_hwmgr_backend_init,
4891 .backend_fini = vega10_hwmgr_backend_fini, 4843 .backend_fini = vega10_hwmgr_backend_fini,
@@ -4944,6 +4896,7 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
4944 .get_power_profile_mode = vega10_get_power_profile_mode, 4896 .get_power_profile_mode = vega10_get_power_profile_mode,
4945 .set_power_profile_mode = vega10_set_power_profile_mode, 4897 .set_power_profile_mode = vega10_set_power_profile_mode,
4946 .set_power_limit = vega10_set_power_limit, 4898 .set_power_limit = vega10_set_power_limit,
4899 .odn_edit_dpm_table = vega10_odn_edit_dpm_table,
4947}; 4900};
4948 4901
4949int vega10_enable_smc_features(struct pp_hwmgr *hwmgr, 4902int vega10_enable_smc_features(struct pp_hwmgr *hwmgr,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
index 5339ea1f3dce..aadd6cbc7e85 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
@@ -282,15 +282,21 @@ struct vega10_registry_data {
282 282
283struct vega10_odn_clock_voltage_dependency_table { 283struct vega10_odn_clock_voltage_dependency_table {
284 uint32_t count; 284 uint32_t count;
285 struct phm_ppt_v1_clock_voltage_dependency_record 285 struct phm_ppt_v1_clock_voltage_dependency_record entries[MAX_REGULAR_DPM_NUMBER];
286 entries[MAX_REGULAR_DPM_NUMBER]; 286};
287
288struct vega10_odn_vddc_lookup_table {
289 uint32_t count;
290 struct phm_ppt_v1_voltage_lookup_record entries[MAX_REGULAR_DPM_NUMBER];
287}; 291};
288 292
289struct vega10_odn_dpm_table { 293struct vega10_odn_dpm_table {
290 struct phm_odn_clock_levels odn_core_clock_dpm_levels; 294 struct vega10_odn_clock_voltage_dependency_table vdd_dep_on_sclk;
291 struct phm_odn_clock_levels odn_memory_clock_dpm_levels; 295 struct vega10_odn_clock_voltage_dependency_table vdd_dep_on_mclk;
292 struct vega10_odn_clock_voltage_dependency_table vdd_dependency_on_sclk; 296 struct vega10_odn_clock_voltage_dependency_table vdd_dep_on_socclk;
293 struct vega10_odn_clock_voltage_dependency_table vdd_dependency_on_mclk; 297 struct vega10_odn_vddc_lookup_table vddc_lookup_table;
298 uint32_t max_vddc;
299 uint32_t min_vddc;
294}; 300};
295 301
296struct vega10_odn_fan_table { 302struct vega10_odn_fan_table {
@@ -301,8 +307,8 @@ struct vega10_odn_fan_table {
301}; 307};
302 308
303struct vega10_hwmgr { 309struct vega10_hwmgr {
304 struct vega10_dpm_table dpm_table; 310 struct vega10_dpm_table dpm_table;
305 struct vega10_dpm_table golden_dpm_table; 311 struct vega10_dpm_table golden_dpm_table;
306 struct vega10_registry_data registry_data; 312 struct vega10_registry_data registry_data;
307 struct vega10_vbios_boot_state vbios_boot_state; 313 struct vega10_vbios_boot_state vbios_boot_state;
308 struct vega10_mclk_latency_table mclk_latency_table; 314 struct vega10_mclk_latency_table mclk_latency_table;
@@ -368,12 +374,8 @@ struct vega10_hwmgr {
368 bool need_long_memory_training; 374 bool need_long_memory_training;
369 375
370 /* Internal settings to apply the application power optimization parameters */ 376 /* Internal settings to apply the application power optimization parameters */
371 bool apply_optimized_settings;
372 uint32_t disable_dpm_mask; 377 uint32_t disable_dpm_mask;
373 378
374 /* ---- Overdrive next setting ---- */
375 uint32_t apply_overdrive_next_settings_mask;
376
377 /* ---- SMU9 ---- */ 379 /* ---- SMU9 ---- */
378 struct smu_features smu_features[GNLD_FEATURES_MAX]; 380 struct smu_features smu_features[GNLD_FEATURES_MAX];
379 struct vega10_smc_state_table smc_state_table; 381 struct vega10_smc_state_table smc_state_table;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
index ba63faefc61f..a9efd8554fbc 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
@@ -27,7 +27,7 @@
27#include "vega10_ppsmc.h" 27#include "vega10_ppsmc.h"
28#include "vega10_inc.h" 28#include "vega10_inc.h"
29#include "pp_debug.h" 29#include "pp_debug.h"
30#include "pp_soc15.h" 30#include "soc15_common.h"
31 31
32static const struct vega10_didt_config_reg SEDiDtTuningCtrlConfig_Vega10[] = 32static const struct vega10_didt_config_reg SEDiDtTuningCtrlConfig_Vega10[] =
33{ 33{
@@ -888,36 +888,36 @@ static void vega10_didt_set_mask(struct pp_hwmgr *hwmgr, const bool enable)
888 if (PP_CAP(PHM_PlatformCaps_DiDtEDCEnable)) { 888 if (PP_CAP(PHM_PlatformCaps_DiDtEDCEnable)) {
889 if (PP_CAP(PHM_PlatformCaps_SQRamping)) { 889 if (PP_CAP(PHM_PlatformCaps_SQRamping)) {
890 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_EDC_CTRL); 890 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_EDC_CTRL);
891 data = CGS_REG_SET_FIELD(data, DIDT_SQ_EDC_CTRL, EDC_EN, en); 891 data = REG_SET_FIELD(data, DIDT_SQ_EDC_CTRL, EDC_EN, en);
892 data = CGS_REG_SET_FIELD(data, DIDT_SQ_EDC_CTRL, EDC_SW_RST, ~en); 892 data = REG_SET_FIELD(data, DIDT_SQ_EDC_CTRL, EDC_SW_RST, ~en);
893 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_EDC_CTRL, data); 893 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_EDC_CTRL, data);
894 } 894 }
895 895
896 if (PP_CAP(PHM_PlatformCaps_DBRamping)) { 896 if (PP_CAP(PHM_PlatformCaps_DBRamping)) {
897 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_EDC_CTRL); 897 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_EDC_CTRL);
898 data = CGS_REG_SET_FIELD(data, DIDT_DB_EDC_CTRL, EDC_EN, en); 898 data = REG_SET_FIELD(data, DIDT_DB_EDC_CTRL, EDC_EN, en);
899 data = CGS_REG_SET_FIELD(data, DIDT_DB_EDC_CTRL, EDC_SW_RST, ~en); 899 data = REG_SET_FIELD(data, DIDT_DB_EDC_CTRL, EDC_SW_RST, ~en);
900 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_EDC_CTRL, data); 900 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_EDC_CTRL, data);
901 } 901 }
902 902
903 if (PP_CAP(PHM_PlatformCaps_TDRamping)) { 903 if (PP_CAP(PHM_PlatformCaps_TDRamping)) {
904 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_EDC_CTRL); 904 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_EDC_CTRL);
905 data = CGS_REG_SET_FIELD(data, DIDT_TD_EDC_CTRL, EDC_EN, en); 905 data = REG_SET_FIELD(data, DIDT_TD_EDC_CTRL, EDC_EN, en);
906 data = CGS_REG_SET_FIELD(data, DIDT_TD_EDC_CTRL, EDC_SW_RST, ~en); 906 data = REG_SET_FIELD(data, DIDT_TD_EDC_CTRL, EDC_SW_RST, ~en);
907 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_EDC_CTRL, data); 907 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_EDC_CTRL, data);
908 } 908 }
909 909
910 if (PP_CAP(PHM_PlatformCaps_TCPRamping)) { 910 if (PP_CAP(PHM_PlatformCaps_TCPRamping)) {
911 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_EDC_CTRL); 911 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_EDC_CTRL);
912 data = CGS_REG_SET_FIELD(data, DIDT_TCP_EDC_CTRL, EDC_EN, en); 912 data = REG_SET_FIELD(data, DIDT_TCP_EDC_CTRL, EDC_EN, en);
913 data = CGS_REG_SET_FIELD(data, DIDT_TCP_EDC_CTRL, EDC_SW_RST, ~en); 913 data = REG_SET_FIELD(data, DIDT_TCP_EDC_CTRL, EDC_SW_RST, ~en);
914 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_EDC_CTRL, data); 914 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_EDC_CTRL, data);
915 } 915 }
916 916
917 if (PP_CAP(PHM_PlatformCaps_DBRRamping)) { 917 if (PP_CAP(PHM_PlatformCaps_DBRRamping)) {
918 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_EDC_CTRL); 918 data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_EDC_CTRL);
919 data = CGS_REG_SET_FIELD(data, DIDT_DBR_EDC_CTRL, EDC_EN, en); 919 data = REG_SET_FIELD(data, DIDT_DBR_EDC_CTRL, EDC_EN, en);
920 data = CGS_REG_SET_FIELD(data, DIDT_DBR_EDC_CTRL, EDC_SW_RST, ~en); 920 data = REG_SET_FIELD(data, DIDT_DBR_EDC_CTRL, EDC_SW_RST, ~en);
921 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_EDC_CTRL, data); 921 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_EDC_CTRL, data);
922 } 922 }
923 } 923 }
@@ -930,20 +930,18 @@ static void vega10_didt_set_mask(struct pp_hwmgr *hwmgr, const bool enable)
930 930
931static int vega10_enable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr) 931static int vega10_enable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr)
932{ 932{
933 struct amdgpu_device *adev = hwmgr->adev;
933 int result; 934 int result;
934 uint32_t num_se = 0, count, data; 935 uint32_t num_se = 0, count, data;
935 struct amdgpu_device *adev = hwmgr->adev;
936 uint32_t reg;
937 936
938 num_se = adev->gfx.config.max_shader_engines; 937 num_se = adev->gfx.config.max_shader_engines;
939 938
940 cgs_enter_safe_mode(hwmgr->device, true); 939 adev->gfx.rlc.funcs->enter_safe_mode(adev);
941 940
942 cgs_lock_grbm_idx(hwmgr->device, true); 941 mutex_lock(&adev->grbm_idx_mutex);
943 reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
944 for (count = 0; count < num_se; count++) { 942 for (count = 0; count < num_se; count++) {
945 data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); 943 data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
946 cgs_write_register(hwmgr->device, reg, data); 944 WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data);
947 945
948 result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT); 946 result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT);
949 result |= vega10_program_didt_config_registers(hwmgr, SEDiDtStallPatternConfig_vega10, VEGA10_CONFIGREG_DIDT); 947 result |= vega10_program_didt_config_registers(hwmgr, SEDiDtStallPatternConfig_vega10, VEGA10_CONFIGREG_DIDT);
@@ -958,43 +956,43 @@ static int vega10_enable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr)
958 if (0 != result) 956 if (0 != result)
959 break; 957 break;
960 } 958 }
961 cgs_write_register(hwmgr->device, reg, 0xE0000000); 959 WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xE0000000);
962 cgs_lock_grbm_idx(hwmgr->device, false); 960 mutex_unlock(&adev->grbm_idx_mutex);
963 961
964 vega10_didt_set_mask(hwmgr, true); 962 vega10_didt_set_mask(hwmgr, true);
965 963
966 cgs_enter_safe_mode(hwmgr->device, false); 964 adev->gfx.rlc.funcs->exit_safe_mode(adev);
967 965
968 return 0; 966 return 0;
969} 967}
970 968
971static int vega10_disable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr) 969static int vega10_disable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr)
972{ 970{
973 cgs_enter_safe_mode(hwmgr->device, true); 971 struct amdgpu_device *adev = hwmgr->adev;
972
973 adev->gfx.rlc.funcs->enter_safe_mode(adev);
974 974
975 vega10_didt_set_mask(hwmgr, false); 975 vega10_didt_set_mask(hwmgr, false);
976 976
977 cgs_enter_safe_mode(hwmgr->device, false); 977 adev->gfx.rlc.funcs->exit_safe_mode(adev);
978 978
979 return 0; 979 return 0;
980} 980}
981 981
982static int vega10_enable_psm_gc_didt_config(struct pp_hwmgr *hwmgr) 982static int vega10_enable_psm_gc_didt_config(struct pp_hwmgr *hwmgr)
983{ 983{
984 struct amdgpu_device *adev = hwmgr->adev;
984 int result; 985 int result;
985 uint32_t num_se = 0, count, data; 986 uint32_t num_se = 0, count, data;
986 struct amdgpu_device *adev = hwmgr->adev;
987 uint32_t reg;
988 987
989 num_se = adev->gfx.config.max_shader_engines; 988 num_se = adev->gfx.config.max_shader_engines;
990 989
991 cgs_enter_safe_mode(hwmgr->device, true); 990 adev->gfx.rlc.funcs->enter_safe_mode(adev);
992 991
993 cgs_lock_grbm_idx(hwmgr->device, true); 992 mutex_lock(&adev->grbm_idx_mutex);
994 reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
995 for (count = 0; count < num_se; count++) { 993 for (count = 0; count < num_se; count++) {
996 data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); 994 data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
997 cgs_write_register(hwmgr->device, reg, data); 995 WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data);
998 996
999 result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT); 997 result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT);
1000 result |= vega10_program_didt_config_registers(hwmgr, SEDiDtStallPatternConfig_vega10, VEGA10_CONFIGREG_DIDT); 998 result |= vega10_program_didt_config_registers(hwmgr, SEDiDtStallPatternConfig_vega10, VEGA10_CONFIGREG_DIDT);
@@ -1003,12 +1001,12 @@ static int vega10_enable_psm_gc_didt_config(struct pp_hwmgr *hwmgr)
1003 if (0 != result) 1001 if (0 != result)
1004 break; 1002 break;
1005 } 1003 }
1006 cgs_write_register(hwmgr->device, reg, 0xE0000000); 1004 WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xE0000000);
1007 cgs_lock_grbm_idx(hwmgr->device, false); 1005 mutex_unlock(&adev->grbm_idx_mutex);
1008 1006
1009 vega10_didt_set_mask(hwmgr, true); 1007 vega10_didt_set_mask(hwmgr, true);
1010 1008
1011 cgs_enter_safe_mode(hwmgr->device, false); 1009 adev->gfx.rlc.funcs->exit_safe_mode(adev);
1012 1010
1013 vega10_program_gc_didt_config_registers(hwmgr, GCDiDtDroopCtrlConfig_vega10); 1011 vega10_program_gc_didt_config_registers(hwmgr, GCDiDtDroopCtrlConfig_vega10);
1014 if (PP_CAP(PHM_PlatformCaps_GCEDC)) 1012 if (PP_CAP(PHM_PlatformCaps_GCEDC))
@@ -1022,13 +1020,14 @@ static int vega10_enable_psm_gc_didt_config(struct pp_hwmgr *hwmgr)
1022 1020
1023static int vega10_disable_psm_gc_didt_config(struct pp_hwmgr *hwmgr) 1021static int vega10_disable_psm_gc_didt_config(struct pp_hwmgr *hwmgr)
1024{ 1022{
1023 struct amdgpu_device *adev = hwmgr->adev;
1025 uint32_t data; 1024 uint32_t data;
1026 1025
1027 cgs_enter_safe_mode(hwmgr->device, true); 1026 adev->gfx.rlc.funcs->enter_safe_mode(adev);
1028 1027
1029 vega10_didt_set_mask(hwmgr, false); 1028 vega10_didt_set_mask(hwmgr, false);
1030 1029
1031 cgs_enter_safe_mode(hwmgr->device, false); 1030 adev->gfx.rlc.funcs->exit_safe_mode(adev);
1032 1031
1033 if (PP_CAP(PHM_PlatformCaps_GCEDC)) { 1032 if (PP_CAP(PHM_PlatformCaps_GCEDC)) {
1034 data = 0x00000000; 1033 data = 0x00000000;
@@ -1043,20 +1042,18 @@ static int vega10_disable_psm_gc_didt_config(struct pp_hwmgr *hwmgr)
1043 1042
1044static int vega10_enable_se_edc_config(struct pp_hwmgr *hwmgr) 1043static int vega10_enable_se_edc_config(struct pp_hwmgr *hwmgr)
1045{ 1044{
1045 struct amdgpu_device *adev = hwmgr->adev;
1046 int result; 1046 int result;
1047 uint32_t num_se = 0, count, data; 1047 uint32_t num_se = 0, count, data;
1048 struct amdgpu_device *adev = hwmgr->adev;
1049 uint32_t reg;
1050 1048
1051 num_se = adev->gfx.config.max_shader_engines; 1049 num_se = adev->gfx.config.max_shader_engines;
1052 1050
1053 cgs_enter_safe_mode(hwmgr->device, true); 1051 adev->gfx.rlc.funcs->enter_safe_mode(adev);
1054 1052
1055 cgs_lock_grbm_idx(hwmgr->device, true); 1053 mutex_lock(&adev->grbm_idx_mutex);
1056 reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
1057 for (count = 0; count < num_se; count++) { 1054 for (count = 0; count < num_se; count++) {
1058 data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); 1055 data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
1059 cgs_write_register(hwmgr->device, reg, data); 1056 WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data);
1060 result = vega10_program_didt_config_registers(hwmgr, SEDiDtWeightConfig_Vega10, VEGA10_CONFIGREG_DIDT); 1057 result = vega10_program_didt_config_registers(hwmgr, SEDiDtWeightConfig_Vega10, VEGA10_CONFIGREG_DIDT);
1061 result |= vega10_program_didt_config_registers(hwmgr, SEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT); 1058 result |= vega10_program_didt_config_registers(hwmgr, SEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
1062 result |= vega10_program_didt_config_registers(hwmgr, SEEDCStallDelayConfig_Vega10, VEGA10_CONFIGREG_DIDT); 1059 result |= vega10_program_didt_config_registers(hwmgr, SEEDCStallDelayConfig_Vega10, VEGA10_CONFIGREG_DIDT);
@@ -1067,46 +1064,46 @@ static int vega10_enable_se_edc_config(struct pp_hwmgr *hwmgr)
1067 if (0 != result) 1064 if (0 != result)
1068 break; 1065 break;
1069 } 1066 }
1070 cgs_write_register(hwmgr->device, reg, 0xE0000000); 1067 WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xE0000000);
1071 cgs_lock_grbm_idx(hwmgr->device, false); 1068 mutex_unlock(&adev->grbm_idx_mutex);
1072 1069
1073 vega10_didt_set_mask(hwmgr, true); 1070 vega10_didt_set_mask(hwmgr, true);
1074 1071
1075 cgs_enter_safe_mode(hwmgr->device, false); 1072 adev->gfx.rlc.funcs->exit_safe_mode(adev);
1076 1073
1077 return 0; 1074 return 0;
1078} 1075}
1079 1076
1080static int vega10_disable_se_edc_config(struct pp_hwmgr *hwmgr) 1077static int vega10_disable_se_edc_config(struct pp_hwmgr *hwmgr)
1081{ 1078{
1082 cgs_enter_safe_mode(hwmgr->device, true); 1079 struct amdgpu_device *adev = hwmgr->adev;
1080
1081 adev->gfx.rlc.funcs->enter_safe_mode(adev);
1083 1082
1084 vega10_didt_set_mask(hwmgr, false); 1083 vega10_didt_set_mask(hwmgr, false);
1085 1084
1086 cgs_enter_safe_mode(hwmgr->device, false); 1085 adev->gfx.rlc.funcs->exit_safe_mode(adev);
1087 1086
1088 return 0; 1087 return 0;
1089} 1088}
1090 1089
1091static int vega10_enable_psm_gc_edc_config(struct pp_hwmgr *hwmgr) 1090static int vega10_enable_psm_gc_edc_config(struct pp_hwmgr *hwmgr)
1092{ 1091{
1092 struct amdgpu_device *adev = hwmgr->adev;
1093 int result; 1093 int result;
1094 uint32_t num_se = 0; 1094 uint32_t num_se = 0;
1095 uint32_t count, data; 1095 uint32_t count, data;
1096 struct amdgpu_device *adev = hwmgr->adev;
1097 uint32_t reg;
1098 1096
1099 num_se = adev->gfx.config.max_shader_engines; 1097 num_se = adev->gfx.config.max_shader_engines;
1100 1098
1101 cgs_enter_safe_mode(hwmgr->device, true); 1099 adev->gfx.rlc.funcs->enter_safe_mode(adev);
1102 1100
1103 vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10); 1101 vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10);
1104 1102
1105 cgs_lock_grbm_idx(hwmgr->device, true); 1103 mutex_lock(&adev->grbm_idx_mutex);
1106 reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
1107 for (count = 0; count < num_se; count++) { 1104 for (count = 0; count < num_se; count++) {
1108 data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); 1105 data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
1109 cgs_write_register(hwmgr->device, reg, data); 1106 WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data);
1110 result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT); 1107 result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
1111 result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallDelayConfig_Vega10, VEGA10_CONFIGREG_DIDT); 1108 result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallDelayConfig_Vega10, VEGA10_CONFIGREG_DIDT);
1112 result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCCtrlResetConfig_Vega10, VEGA10_CONFIGREG_DIDT); 1109 result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCCtrlResetConfig_Vega10, VEGA10_CONFIGREG_DIDT);
@@ -1115,12 +1112,12 @@ static int vega10_enable_psm_gc_edc_config(struct pp_hwmgr *hwmgr)
1115 if (0 != result) 1112 if (0 != result)
1116 break; 1113 break;
1117 } 1114 }
1118 cgs_write_register(hwmgr->device, reg, 0xE0000000); 1115 WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xE0000000);
1119 cgs_lock_grbm_idx(hwmgr->device, false); 1116 mutex_unlock(&adev->grbm_idx_mutex);
1120 1117
1121 vega10_didt_set_mask(hwmgr, true); 1118 vega10_didt_set_mask(hwmgr, true);
1122 1119
1123 cgs_enter_safe_mode(hwmgr->device, false); 1120 adev->gfx.rlc.funcs->exit_safe_mode(adev);
1124 1121
1125 vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCDroopCtrlConfig_vega10); 1122 vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCDroopCtrlConfig_vega10);
1126 1123
@@ -1137,13 +1134,14 @@ static int vega10_enable_psm_gc_edc_config(struct pp_hwmgr *hwmgr)
1137 1134
1138static int vega10_disable_psm_gc_edc_config(struct pp_hwmgr *hwmgr) 1135static int vega10_disable_psm_gc_edc_config(struct pp_hwmgr *hwmgr)
1139{ 1136{
1137 struct amdgpu_device *adev = hwmgr->adev;
1140 uint32_t data; 1138 uint32_t data;
1141 1139
1142 cgs_enter_safe_mode(hwmgr->device, true); 1140 adev->gfx.rlc.funcs->enter_safe_mode(adev);
1143 1141
1144 vega10_didt_set_mask(hwmgr, false); 1142 vega10_didt_set_mask(hwmgr, false);
1145 1143
1146 cgs_enter_safe_mode(hwmgr->device, false); 1144 adev->gfx.rlc.funcs->exit_safe_mode(adev);
1147 1145
1148 if (PP_CAP(PHM_PlatformCaps_GCEDC)) { 1146 if (PP_CAP(PHM_PlatformCaps_GCEDC)) {
1149 data = 0x00000000; 1147 data = 0x00000000;
@@ -1158,15 +1156,14 @@ static int vega10_disable_psm_gc_edc_config(struct pp_hwmgr *hwmgr)
1158 1156
1159static int vega10_enable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr) 1157static int vega10_enable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr)
1160{ 1158{
1161 uint32_t reg; 1159 struct amdgpu_device *adev = hwmgr->adev;
1162 int result; 1160 int result;
1163 1161
1164 cgs_enter_safe_mode(hwmgr->device, true); 1162 adev->gfx.rlc.funcs->enter_safe_mode(adev);
1165 1163
1166 cgs_lock_grbm_idx(hwmgr->device, true); 1164 mutex_lock(&adev->grbm_idx_mutex);
1167 reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX); 1165 WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xE0000000);
1168 cgs_write_register(hwmgr->device, reg, 0xE0000000); 1166 mutex_unlock(&adev->grbm_idx_mutex);
1169 cgs_lock_grbm_idx(hwmgr->device, false);
1170 1167
1171 result = vega10_program_didt_config_registers(hwmgr, SEEDCForceStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT); 1168 result = vega10_program_didt_config_registers(hwmgr, SEEDCForceStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
1172 result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlForceStallConfig_Vega10, VEGA10_CONFIGREG_DIDT); 1169 result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlForceStallConfig_Vega10, VEGA10_CONFIGREG_DIDT);
@@ -1175,7 +1172,7 @@ static int vega10_enable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr)
1175 1172
1176 vega10_didt_set_mask(hwmgr, false); 1173 vega10_didt_set_mask(hwmgr, false);
1177 1174
1178 cgs_enter_safe_mode(hwmgr->device, false); 1175 adev->gfx.rlc.funcs->exit_safe_mode(adev);
1179 1176
1180 return 0; 1177 return 0;
1181} 1178}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
index c61d0744860d..0768d259c07c 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
@@ -52,7 +52,7 @@ static const void *get_powerplay_table(struct pp_hwmgr *hwmgr)
52 52
53 if (!table_address) { 53 if (!table_address) {
54 table_address = (ATOM_Vega10_POWERPLAYTABLE *) 54 table_address = (ATOM_Vega10_POWERPLAYTABLE *)
55 cgs_atom_get_data_table(hwmgr->device, index, 55 smu_atom_get_data_table(hwmgr->adev, index,
56 &size, &frev, &crev); 56 &size, &frev, &crev);
57 57
58 hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/ 58 hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
index 9f18226a56ea..aa044c1955fe 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
@@ -25,7 +25,7 @@
25#include "vega10_hwmgr.h" 25#include "vega10_hwmgr.h"
26#include "vega10_ppsmc.h" 26#include "vega10_ppsmc.h"
27#include "vega10_inc.h" 27#include "vega10_inc.h"
28#include "pp_soc15.h" 28#include "soc15_common.h"
29#include "pp_debug.h" 29#include "pp_debug.h"
30 30
31static int vega10_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm) 31static int vega10_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
@@ -89,6 +89,7 @@ int vega10_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,
89 89
90int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed) 90int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
91{ 91{
92 struct amdgpu_device *adev = hwmgr->adev;
92 struct vega10_hwmgr *data = hwmgr->backend; 93 struct vega10_hwmgr *data = hwmgr->backend;
93 uint32_t tach_period; 94 uint32_t tach_period;
94 uint32_t crystal_clock_freq; 95 uint32_t crystal_clock_freq;
@@ -100,10 +101,8 @@ int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
100 if (data->smu_features[GNLD_FAN_CONTROL].supported) { 101 if (data->smu_features[GNLD_FAN_CONTROL].supported) {
101 result = vega10_get_current_rpm(hwmgr, speed); 102 result = vega10_get_current_rpm(hwmgr, speed);
102 } else { 103 } else {
103 uint32_t reg = soc15_get_register_offset(THM_HWID, 0,
104 mmCG_TACH_STATUS_BASE_IDX, mmCG_TACH_STATUS);
105 tach_period = 104 tach_period =
106 CGS_REG_GET_FIELD(cgs_read_register(hwmgr->device, reg), 105 REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_STATUS),
107 CG_TACH_STATUS, 106 CG_TACH_STATUS,
108 TACH_PERIOD); 107 TACH_PERIOD);
109 108
@@ -127,26 +126,23 @@ int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
127*/ 126*/
128int vega10_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode) 127int vega10_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
129{ 128{
130 uint32_t reg; 129 struct amdgpu_device *adev = hwmgr->adev;
131
132 reg = soc15_get_register_offset(THM_HWID, 0,
133 mmCG_FDO_CTRL2_BASE_IDX, mmCG_FDO_CTRL2);
134 130
135 if (hwmgr->fan_ctrl_is_in_default_mode) { 131 if (hwmgr->fan_ctrl_is_in_default_mode) {
136 hwmgr->fan_ctrl_default_mode = 132 hwmgr->fan_ctrl_default_mode =
137 CGS_REG_GET_FIELD(cgs_read_register(hwmgr->device, reg), 133 REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
138 CG_FDO_CTRL2, FDO_PWM_MODE); 134 CG_FDO_CTRL2, FDO_PWM_MODE);
139 hwmgr->tmin = 135 hwmgr->tmin =
140 CGS_REG_GET_FIELD(cgs_read_register(hwmgr->device, reg), 136 REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
141 CG_FDO_CTRL2, TMIN); 137 CG_FDO_CTRL2, TMIN);
142 hwmgr->fan_ctrl_is_in_default_mode = false; 138 hwmgr->fan_ctrl_is_in_default_mode = false;
143 } 139 }
144 140
145 cgs_write_register(hwmgr->device, reg, 141 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
146 CGS_REG_SET_FIELD(cgs_read_register(hwmgr->device, reg), 142 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
147 CG_FDO_CTRL2, TMIN, 0)); 143 CG_FDO_CTRL2, TMIN, 0));
148 cgs_write_register(hwmgr->device, reg, 144 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
149 CGS_REG_SET_FIELD(cgs_read_register(hwmgr->device, reg), 145 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
150 CG_FDO_CTRL2, FDO_PWM_MODE, mode)); 146 CG_FDO_CTRL2, FDO_PWM_MODE, mode));
151 147
152 return 0; 148 return 0;
@@ -159,18 +155,15 @@ int vega10_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
159*/ 155*/
160int vega10_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr) 156int vega10_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr)
161{ 157{
162 uint32_t reg; 158 struct amdgpu_device *adev = hwmgr->adev;
163
164 reg = soc15_get_register_offset(THM_HWID, 0,
165 mmCG_FDO_CTRL2_BASE_IDX, mmCG_FDO_CTRL2);
166 159
167 if (!hwmgr->fan_ctrl_is_in_default_mode) { 160 if (!hwmgr->fan_ctrl_is_in_default_mode) {
168 cgs_write_register(hwmgr->device, reg, 161 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
169 CGS_REG_SET_FIELD(cgs_read_register(hwmgr->device, reg), 162 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
170 CG_FDO_CTRL2, FDO_PWM_MODE, 163 CG_FDO_CTRL2, FDO_PWM_MODE,
171 hwmgr->fan_ctrl_default_mode)); 164 hwmgr->fan_ctrl_default_mode));
172 cgs_write_register(hwmgr->device, reg, 165 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
173 CGS_REG_SET_FIELD(cgs_read_register(hwmgr->device, reg), 166 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
174 CG_FDO_CTRL2, TMIN, 167 CG_FDO_CTRL2, TMIN,
175 hwmgr->tmin << CG_FDO_CTRL2__TMIN__SHIFT)); 168 hwmgr->tmin << CG_FDO_CTRL2__TMIN__SHIFT));
176 hwmgr->fan_ctrl_is_in_default_mode = true; 169 hwmgr->fan_ctrl_is_in_default_mode = true;
@@ -257,10 +250,10 @@ int vega10_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
257int vega10_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, 250int vega10_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr,
258 uint32_t speed) 251 uint32_t speed)
259{ 252{
253 struct amdgpu_device *adev = hwmgr->adev;
260 uint32_t duty100; 254 uint32_t duty100;
261 uint32_t duty; 255 uint32_t duty;
262 uint64_t tmp64; 256 uint64_t tmp64;
263 uint32_t reg;
264 257
265 if (hwmgr->thermal_controller.fanInfo.bNoFan) 258 if (hwmgr->thermal_controller.fanInfo.bNoFan)
266 return 0; 259 return 0;
@@ -271,10 +264,7 @@ int vega10_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr,
271 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) 264 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
272 vega10_fan_ctrl_stop_smc_fan_control(hwmgr); 265 vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
273 266
274 reg = soc15_get_register_offset(THM_HWID, 0, 267 duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
275 mmCG_FDO_CTRL1_BASE_IDX, mmCG_FDO_CTRL1);
276
277 duty100 = CGS_REG_GET_FIELD(cgs_read_register(hwmgr->device, reg),
278 CG_FDO_CTRL1, FMAX_DUTY100); 268 CG_FDO_CTRL1, FMAX_DUTY100);
279 269
280 if (duty100 == 0) 270 if (duty100 == 0)
@@ -284,10 +274,8 @@ int vega10_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr,
284 do_div(tmp64, 100); 274 do_div(tmp64, 100);
285 duty = (uint32_t)tmp64; 275 duty = (uint32_t)tmp64;
286 276
287 reg = soc15_get_register_offset(THM_HWID, 0, 277 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0,
288 mmCG_FDO_CTRL0_BASE_IDX, mmCG_FDO_CTRL0); 278 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0),
289 cgs_write_register(hwmgr->device, reg,
290 CGS_REG_SET_FIELD(cgs_read_register(hwmgr->device, reg),
291 CG_FDO_CTRL0, FDO_STATIC_DUTY, duty)); 279 CG_FDO_CTRL0, FDO_STATIC_DUTY, duty));
292 280
293 return vega10_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC); 281 return vega10_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
@@ -317,10 +305,10 @@ int vega10_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
317*/ 305*/
318int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed) 306int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
319{ 307{
308 struct amdgpu_device *adev = hwmgr->adev;
320 uint32_t tach_period; 309 uint32_t tach_period;
321 uint32_t crystal_clock_freq; 310 uint32_t crystal_clock_freq;
322 int result = 0; 311 int result = 0;
323 uint32_t reg;
324 312
325 if (hwmgr->thermal_controller.fanInfo.bNoFan || 313 if (hwmgr->thermal_controller.fanInfo.bNoFan ||
326 (speed < hwmgr->thermal_controller.fanInfo.ulMinRPM) || 314 (speed < hwmgr->thermal_controller.fanInfo.ulMinRPM) ||
@@ -333,10 +321,8 @@ int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
333 if (!result) { 321 if (!result) {
334 crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev); 322 crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
335 tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed); 323 tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
336 reg = soc15_get_register_offset(THM_HWID, 0, 324 WREG32_SOC15(THM, 0, mmCG_TACH_STATUS,
337 mmCG_TACH_STATUS_BASE_IDX, mmCG_TACH_STATUS); 325 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_STATUS),
338 cgs_write_register(hwmgr->device, reg,
339 CGS_REG_SET_FIELD(cgs_read_register(hwmgr->device, reg),
340 CG_TACH_STATUS, TACH_PERIOD, 326 CG_TACH_STATUS, TACH_PERIOD,
341 tach_period)); 327 tach_period));
342 } 328 }
@@ -350,13 +336,10 @@ int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
350*/ 336*/
351int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr) 337int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr)
352{ 338{
339 struct amdgpu_device *adev = hwmgr->adev;
353 int temp; 340 int temp;
354 uint32_t reg;
355 341
356 reg = soc15_get_register_offset(THM_HWID, 0, 342 temp = RREG32_SOC15(THM, 0, mmCG_MULT_THERMAL_STATUS);
357 mmCG_MULT_THERMAL_STATUS_BASE_IDX, mmCG_MULT_THERMAL_STATUS);
358
359 temp = cgs_read_register(hwmgr->device, reg);
360 343
361 temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >> 344 temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>
362 CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT; 345 CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;
@@ -379,11 +362,12 @@ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr)
379static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, 362static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
380 struct PP_TemperatureRange *range) 363 struct PP_TemperatureRange *range)
381{ 364{
365 struct amdgpu_device *adev = hwmgr->adev;
382 int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP * 366 int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP *
383 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 367 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
384 int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP * 368 int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP *
385 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 369 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
386 uint32_t val, reg; 370 uint32_t val;
387 371
388 if (low < range->min) 372 if (low < range->min)
389 low = range->min; 373 low = range->min;
@@ -393,20 +377,17 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
393 if (low > high) 377 if (low > high)
394 return -EINVAL; 378 return -EINVAL;
395 379
396 reg = soc15_get_register_offset(THM_HWID, 0, 380 val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL);
397 mmTHM_THERMAL_INT_CTRL_BASE_IDX, mmTHM_THERMAL_INT_CTRL);
398
399 val = cgs_read_register(hwmgr->device, reg);
400 381
401 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); 382 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
402 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); 383 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
403 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); 384 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
404 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); 385 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
405 val &= (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK) & 386 val &= (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK) &
406 (~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK) & 387 (~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK) &
407 (~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK); 388 (~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK);
408 389
409 cgs_write_register(hwmgr->device, reg, val); 390 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);
410 391
411 return 0; 392 return 0;
412} 393}
@@ -418,21 +399,17 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
418*/ 399*/
419static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr) 400static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr)
420{ 401{
421 uint32_t reg; 402 struct amdgpu_device *adev = hwmgr->adev;
422 403
423 if (hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution) { 404 if (hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution) {
424 reg = soc15_get_register_offset(THM_HWID, 0, 405 WREG32_SOC15(THM, 0, mmCG_TACH_CTRL,
425 mmCG_TACH_CTRL_BASE_IDX, mmCG_TACH_CTRL); 406 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL),
426 cgs_write_register(hwmgr->device, reg,
427 CGS_REG_SET_FIELD(cgs_read_register(hwmgr->device, reg),
428 CG_TACH_CTRL, EDGE_PER_REV, 407 CG_TACH_CTRL, EDGE_PER_REV,
429 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution - 1)); 408 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution - 1));
430 } 409 }
431 410
432 reg = soc15_get_register_offset(THM_HWID, 0, 411 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
433 mmCG_FDO_CTRL2_BASE_IDX, mmCG_FDO_CTRL2); 412 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
434 cgs_write_register(hwmgr->device, reg,
435 CGS_REG_SET_FIELD(cgs_read_register(hwmgr->device, reg),
436 CG_FDO_CTRL2, TACH_PWM_RESP_RATE, 0x28)); 413 CG_FDO_CTRL2, TACH_PWM_RESP_RATE, 0x28));
437 414
438 return 0; 415 return 0;
@@ -445,9 +422,9 @@ static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr)
445*/ 422*/
446static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr) 423static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
447{ 424{
425 struct amdgpu_device *adev = hwmgr->adev;
448 struct vega10_hwmgr *data = hwmgr->backend; 426 struct vega10_hwmgr *data = hwmgr->backend;
449 uint32_t val = 0; 427 uint32_t val = 0;
450 uint32_t reg;
451 428
452 if (data->smu_features[GNLD_FW_CTF].supported) { 429 if (data->smu_features[GNLD_FW_CTF].supported) {
453 if (data->smu_features[GNLD_FW_CTF].enabled) 430 if (data->smu_features[GNLD_FW_CTF].enabled)
@@ -465,8 +442,7 @@ static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
465 val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT); 442 val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT);
466 val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT); 443 val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT);
467 444
468 reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA); 445 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, val);
469 cgs_write_register(hwmgr->device, reg, val);
470 446
471 return 0; 447 return 0;
472} 448}
@@ -477,8 +453,8 @@ static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
477*/ 453*/
478int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr) 454int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr)
479{ 455{
456 struct amdgpu_device *adev = hwmgr->adev;
480 struct vega10_hwmgr *data = hwmgr->backend; 457 struct vega10_hwmgr *data = hwmgr->backend;
481 uint32_t reg;
482 458
483 if (data->smu_features[GNLD_FW_CTF].supported) { 459 if (data->smu_features[GNLD_FW_CTF].supported) {
484 if (!data->smu_features[GNLD_FW_CTF].enabled) 460 if (!data->smu_features[GNLD_FW_CTF].enabled)
@@ -493,8 +469,7 @@ int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr)
493 data->smu_features[GNLD_FW_CTF].enabled = false; 469 data->smu_features[GNLD_FW_CTF].enabled = false;
494 } 470 }
495 471
496 reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA); 472 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, 0);
497 cgs_write_register(hwmgr->device, reg, 0);
498 473
499 return 0; 474 return 0;
500} 475}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
index 200de46bd06b..782e2098824d 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
@@ -34,7 +34,6 @@
34#include "atomfirmware.h" 34#include "atomfirmware.h"
35#include "cgs_common.h" 35#include "cgs_common.h"
36#include "vega12_inc.h" 36#include "vega12_inc.h"
37#include "pp_soc15.h"
38#include "pppcielanes.h" 37#include "pppcielanes.h"
39#include "vega12_hwmgr.h" 38#include "vega12_hwmgr.h"
40#include "vega12_processpptables.h" 39#include "vega12_processpptables.h"
@@ -546,6 +545,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
546 return -EINVAL); 545 return -EINVAL);
547 546
548 dpm_table->dpm_levels[i].value = clock; 547 dpm_table->dpm_levels[i].value = clock;
548 dpm_table->dpm_levels[i].enabled = true;
549 } 549 }
550 550
551 vega12_init_dpm_state(&(dpm_table->dpm_state)); 551 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -565,6 +565,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
565 return -EINVAL); 565 return -EINVAL);
566 566
567 dpm_table->dpm_levels[i].value = clock; 567 dpm_table->dpm_levels[i].value = clock;
568 dpm_table->dpm_levels[i].enabled = true;
568 } 569 }
569 570
570 vega12_init_dpm_state(&(dpm_table->dpm_state)); 571 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -585,6 +586,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
585 return -EINVAL); 586 return -EINVAL);
586 587
587 dpm_table->dpm_levels[i].value = clock; 588 dpm_table->dpm_levels[i].value = clock;
589 dpm_table->dpm_levels[i].enabled = true;
588 } 590 }
589 591
590 vega12_init_dpm_state(&(dpm_table->dpm_state)); 592 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -605,6 +607,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
605 return -EINVAL); 607 return -EINVAL);
606 608
607 dpm_table->dpm_levels[i].value = clock; 609 dpm_table->dpm_levels[i].value = clock;
610 dpm_table->dpm_levels[i].enabled = true;
608 } 611 }
609 612
610 vega12_init_dpm_state(&(dpm_table->dpm_state)); 613 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -625,6 +628,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
625 return -EINVAL); 628 return -EINVAL);
626 629
627 dpm_table->dpm_levels[i].value = clock; 630 dpm_table->dpm_levels[i].value = clock;
631 dpm_table->dpm_levels[i].enabled = true;
628 } 632 }
629 633
630 vega12_init_dpm_state(&(dpm_table->dpm_state)); 634 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -645,6 +649,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
645 return -EINVAL); 649 return -EINVAL);
646 650
647 dpm_table->dpm_levels[i].value = clock; 651 dpm_table->dpm_levels[i].value = clock;
652 dpm_table->dpm_levels[i].enabled = true;
648 } 653 }
649 654
650 vega12_init_dpm_state(&(dpm_table->dpm_state)); 655 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -666,6 +671,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
666 return -EINVAL); 671 return -EINVAL);
667 672
668 dpm_table->dpm_levels[i].value = clock; 673 dpm_table->dpm_levels[i].value = clock;
674 dpm_table->dpm_levels[i].enabled = true;
669 } 675 }
670 676
671 vega12_init_dpm_state(&(dpm_table->dpm_state)); 677 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -686,6 +692,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
686 return -EINVAL); 692 return -EINVAL);
687 693
688 dpm_table->dpm_levels[i].value = clock; 694 dpm_table->dpm_levels[i].value = clock;
695 dpm_table->dpm_levels[i].enabled = true;
689 } 696 }
690 697
691 vega12_init_dpm_state(&(dpm_table->dpm_state)); 698 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -706,6 +713,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
706 return -EINVAL); 713 return -EINVAL);
707 714
708 dpm_table->dpm_levels[i].value = clock; 715 dpm_table->dpm_levels[i].value = clock;
716 dpm_table->dpm_levels[i].enabled = true;
709 } 717 }
710 718
711 vega12_init_dpm_state(&(dpm_table->dpm_state)); 719 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -726,6 +734,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
726 return -EINVAL); 734 return -EINVAL);
727 735
728 dpm_table->dpm_levels[i].value = clock; 736 dpm_table->dpm_levels[i].value = clock;
737 dpm_table->dpm_levels[i].enabled = true;
729 } 738 }
730 739
731 vega12_init_dpm_state(&(dpm_table->dpm_state)); 740 vega12_init_dpm_state(&(dpm_table->dpm_state));
@@ -992,15 +1001,55 @@ static uint32_t vega12_find_highest_dpm_level(
992 1001
993static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr) 1002static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr)
994{ 1003{
1004 struct vega12_hwmgr *data = hwmgr->backend;
1005 if (data->smc_state_table.gfx_boot_level !=
1006 data->dpm_table.gfx_table.dpm_state.soft_min_level) {
1007 smum_send_msg_to_smc_with_parameter(hwmgr,
1008 PPSMC_MSG_SetSoftMinByFreq,
1009 PPCLK_GFXCLK<<16 | data->dpm_table.gfx_table.dpm_levels[data->smc_state_table.gfx_boot_level].value);
1010 data->dpm_table.gfx_table.dpm_state.soft_min_level =
1011 data->smc_state_table.gfx_boot_level;
1012 }
1013
1014 if (data->smc_state_table.mem_boot_level !=
1015 data->dpm_table.mem_table.dpm_state.soft_min_level) {
1016 smum_send_msg_to_smc_with_parameter(hwmgr,
1017 PPSMC_MSG_SetSoftMinByFreq,
1018 PPCLK_UCLK<<16 | data->dpm_table.mem_table.dpm_levels[data->smc_state_table.mem_boot_level].value);
1019 data->dpm_table.mem_table.dpm_state.soft_min_level =
1020 data->smc_state_table.mem_boot_level;
1021 }
1022
995 return 0; 1023 return 0;
1024
996} 1025}
997 1026
998static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr) 1027static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
999{ 1028{
1029 struct vega12_hwmgr *data = hwmgr->backend;
1030 if (data->smc_state_table.gfx_max_level !=
1031 data->dpm_table.gfx_table.dpm_state.soft_max_level) {
1032 smum_send_msg_to_smc_with_parameter(hwmgr,
1033 PPSMC_MSG_SetSoftMaxByFreq,
1034 /* plus the vale by 1 to align the resolution */
1035 PPCLK_GFXCLK<<16 | (data->dpm_table.gfx_table.dpm_levels[data->smc_state_table.gfx_max_level].value + 1));
1036 data->dpm_table.gfx_table.dpm_state.soft_max_level =
1037 data->smc_state_table.gfx_max_level;
1038 }
1039
1040 if (data->smc_state_table.mem_max_level !=
1041 data->dpm_table.mem_table.dpm_state.soft_max_level) {
1042 smum_send_msg_to_smc_with_parameter(hwmgr,
1043 PPSMC_MSG_SetSoftMaxByFreq,
1044 /* plus the vale by 1 to align the resolution */
1045 PPCLK_UCLK<<16 | (data->dpm_table.mem_table.dpm_levels[data->smc_state_table.mem_max_level].value + 1));
1046 data->dpm_table.mem_table.dpm_state.soft_max_level =
1047 data->smc_state_table.mem_max_level;
1048 }
1049
1000 return 0; 1050 return 0;
1001} 1051}
1002 1052
1003
1004int vega12_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) 1053int vega12_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
1005{ 1054{
1006 struct vega12_hwmgr *data = 1055 struct vega12_hwmgr *data =
@@ -1064,8 +1113,7 @@ static uint32_t vega12_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
1064 return (mem_clk * 100); 1113 return (mem_clk * 100);
1065} 1114}
1066 1115
1067static int vega12_get_gpu_power(struct pp_hwmgr *hwmgr, 1116static int vega12_get_gpu_power(struct pp_hwmgr *hwmgr, uint32_t *query)
1068 struct pp_gpu_power *query)
1069{ 1117{
1070#if 0 1118#if 0
1071 uint32_t value; 1119 uint32_t value;
@@ -1077,7 +1125,7 @@ static int vega12_get_gpu_power(struct pp_hwmgr *hwmgr,
1077 1125
1078 vega12_read_arg_from_smc(hwmgr, &value); 1126 vega12_read_arg_from_smc(hwmgr, &value);
1079 /* power value is an integer */ 1127 /* power value is an integer */
1080 query->average_gpu_power = value << 8; 1128 *query = value << 8;
1081#endif 1129#endif
1082 return 0; 1130 return 0;
1083} 1131}
@@ -1186,12 +1234,8 @@ static int vega12_read_sensor(struct pp_hwmgr *hwmgr, int idx,
1186 *size = 4; 1234 *size = 4;
1187 break; 1235 break;
1188 case AMDGPU_PP_SENSOR_GPU_POWER: 1236 case AMDGPU_PP_SENSOR_GPU_POWER:
1189 if (*size < sizeof(struct pp_gpu_power)) 1237 ret = vega12_get_gpu_power(hwmgr, (uint32_t *)value);
1190 ret = -EINVAL; 1238
1191 else {
1192 *size = sizeof(struct pp_gpu_power);
1193 ret = vega12_get_gpu_power(hwmgr, (struct pp_gpu_power *)value);
1194 }
1195 break; 1239 break;
1196 default: 1240 default:
1197 ret = -EINVAL; 1241 ret = -EINVAL;
@@ -1260,23 +1304,18 @@ static int vega12_notify_smc_display_config_after_ps_adjustment(
1260{ 1304{
1261 struct vega12_hwmgr *data = 1305 struct vega12_hwmgr *data =
1262 (struct vega12_hwmgr *)(hwmgr->backend); 1306 (struct vega12_hwmgr *)(hwmgr->backend);
1263 uint32_t num_active_disps = 0;
1264 struct cgs_display_info info = {0};
1265 struct PP_Clocks min_clocks = {0}; 1307 struct PP_Clocks min_clocks = {0};
1266 struct pp_display_clock_request clock_req; 1308 struct pp_display_clock_request clock_req;
1267 uint32_t clk_request; 1309 uint32_t clk_request;
1268 1310
1269 info.mode_info = NULL; 1311 if (hwmgr->display_config->num_display > 1)
1270 cgs_get_active_displays_info(hwmgr->device, &info);
1271 num_active_disps = info.display_count;
1272 if (num_active_disps > 1)
1273 vega12_notify_smc_display_change(hwmgr, false); 1312 vega12_notify_smc_display_change(hwmgr, false);
1274 else 1313 else
1275 vega12_notify_smc_display_change(hwmgr, true); 1314 vega12_notify_smc_display_change(hwmgr, true);
1276 1315
1277 min_clocks.dcefClock = hwmgr->display_config.min_dcef_set_clk; 1316 min_clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk;
1278 min_clocks.dcefClockInSR = hwmgr->display_config.min_dcef_deep_sleep_set_clk; 1317 min_clocks.dcefClockInSR = hwmgr->display_config->min_dcef_deep_sleep_set_clk;
1279 min_clocks.memoryClock = hwmgr->display_config.min_mem_set_clock; 1318 min_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock;
1280 1319
1281 if (data->smu_features[GNLD_DPM_DCEFCLK].supported) { 1320 if (data->smu_features[GNLD_DPM_DCEFCLK].supported) {
1282 clock_req.clock_type = amd_pp_dcef_clock; 1321 clock_req.clock_type = amd_pp_dcef_clock;
@@ -1832,9 +1871,7 @@ static int vega12_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
1832{ 1871{
1833 struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); 1872 struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1834 int result = 0; 1873 int result = 0;
1835 uint32_t num_turned_on_displays = 1;
1836 Watermarks_t *wm_table = &(data->smc_state_table.water_marks_table); 1874 Watermarks_t *wm_table = &(data->smc_state_table.water_marks_table);
1837 struct cgs_display_info info = {0};
1838 1875
1839 if ((data->water_marks_bitmap & WaterMarksExist) && 1876 if ((data->water_marks_bitmap & WaterMarksExist) &&
1840 !(data->water_marks_bitmap & WaterMarksLoaded)) { 1877 !(data->water_marks_bitmap & WaterMarksLoaded)) {
@@ -1846,12 +1883,9 @@ static int vega12_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
1846 1883
1847 if ((data->water_marks_bitmap & WaterMarksExist) && 1884 if ((data->water_marks_bitmap & WaterMarksExist) &&
1848 data->smu_features[GNLD_DPM_DCEFCLK].supported && 1885 data->smu_features[GNLD_DPM_DCEFCLK].supported &&
1849 data->smu_features[GNLD_DPM_SOCCLK].supported) { 1886 data->smu_features[GNLD_DPM_SOCCLK].supported)
1850 cgs_get_active_displays_info(hwmgr->device, &info);
1851 num_turned_on_displays = info.display_count;
1852 smum_send_msg_to_smc_with_parameter(hwmgr, 1887 smum_send_msg_to_smc_with_parameter(hwmgr,
1853 PPSMC_MSG_NumOfDisplays, num_turned_on_displays); 1888 PPSMC_MSG_NumOfDisplays, hwmgr->display_config->num_display);
1854 }
1855 1889
1856 return result; 1890 return result;
1857} 1891}
@@ -1894,15 +1928,12 @@ vega12_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmg
1894{ 1928{
1895 struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); 1929 struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1896 bool is_update_required = false; 1930 bool is_update_required = false;
1897 struct cgs_display_info info = {0, 0, NULL};
1898
1899 cgs_get_active_displays_info(hwmgr->device, &info);
1900 1931
1901 if (data->display_timing.num_existing_displays != info.display_count) 1932 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
1902 is_update_required = true; 1933 is_update_required = true;
1903 1934
1904 if (data->registry_data.gfx_clk_deep_sleep_support) { 1935 if (data->registry_data.gfx_clk_deep_sleep_support) {
1905 if (data->display_timing.min_clock_in_sr != hwmgr->display_config.min_core_set_clock_in_sr) 1936 if (data->display_timing.min_clock_in_sr != hwmgr->display_config->min_core_set_clock_in_sr)
1906 is_update_required = true; 1937 is_update_required = true;
1907 } 1938 }
1908 1939
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h
index bc98b1df3b65..e81ded1ec198 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h
@@ -33,7 +33,7 @@
33#define WaterMarksExist 1 33#define WaterMarksExist 1
34#define WaterMarksLoaded 2 34#define WaterMarksLoaded 2
35 35
36#define VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS 8 36#define VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS 16
37#define VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS 8 37#define VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS 8
38#define VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS 8 38#define VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS 8
39#define VG12_PSUEDO_NUM_UCLK_DPM_LEVELS 4 39#define VG12_PSUEDO_NUM_UCLK_DPM_LEVELS 4
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c
index b34113f45904..888ddca902d8 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c
@@ -51,7 +51,7 @@ static const void *get_powerplay_table(struct pp_hwmgr *hwmgr)
51 51
52 if (!table_address) { 52 if (!table_address) {
53 table_address = (ATOM_Vega12_POWERPLAYTABLE *) 53 table_address = (ATOM_Vega12_POWERPLAYTABLE *)
54 cgs_atom_get_data_table(hwmgr->device, index, 54 smu_atom_get_data_table(hwmgr->adev, index,
55 &size, &frev, &crev); 55 &size, &frev, &crev);
56 56
57 hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/ 57 hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/
@@ -224,6 +224,11 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
224 ppsmc_pptable->AcgGfxclkSpreadPercent = smc_dpm_table.acggfxclkspreadpercent; 224 ppsmc_pptable->AcgGfxclkSpreadPercent = smc_dpm_table.acggfxclkspreadpercent;
225 ppsmc_pptable->AcgGfxclkSpreadFreq = smc_dpm_table.acggfxclkspreadfreq; 225 ppsmc_pptable->AcgGfxclkSpreadFreq = smc_dpm_table.acggfxclkspreadfreq;
226 226
227 /* 0xFFFF will disable the ACG feature */
228 if (!(hwmgr->feature_mask & PP_ACG_MASK)) {
229 ppsmc_pptable->AcgThresholdFreqHigh = 0xFFFF;
230 ppsmc_pptable->AcgThresholdFreqLow = 0xFFFF;
231 }
227 232
228 return 0; 233 return 0;
229} 234}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
index df0fa815cd6e..cfd9e6ccb790 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
@@ -26,7 +26,7 @@
26#include "vega12_smumgr.h" 26#include "vega12_smumgr.h"
27#include "vega12_ppsmc.h" 27#include "vega12_ppsmc.h"
28#include "vega12_inc.h" 28#include "vega12_inc.h"
29#include "pp_soc15.h" 29#include "soc15_common.h"
30#include "pp_debug.h" 30#include "pp_debug.h"
31 31
32static int vega12_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm) 32static int vega12_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
@@ -147,13 +147,10 @@ int vega12_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
147*/ 147*/
148int vega12_thermal_get_temperature(struct pp_hwmgr *hwmgr) 148int vega12_thermal_get_temperature(struct pp_hwmgr *hwmgr)
149{ 149{
150 struct amdgpu_device *adev = hwmgr->adev;
150 int temp = 0; 151 int temp = 0;
151 uint32_t reg;
152 152
153 reg = soc15_get_register_offset(THM_HWID, 0, 153 temp = RREG32_SOC15(THM, 0, mmCG_MULT_THERMAL_STATUS);
154 mmCG_MULT_THERMAL_STATUS_BASE_IDX, mmCG_MULT_THERMAL_STATUS);
155
156 temp = cgs_read_register(hwmgr->device, reg);
157 154
158 temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >> 155 temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>
159 CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT; 156 CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;
@@ -175,11 +172,12 @@ int vega12_thermal_get_temperature(struct pp_hwmgr *hwmgr)
175static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, 172static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
176 struct PP_TemperatureRange *range) 173 struct PP_TemperatureRange *range)
177{ 174{
175 struct amdgpu_device *adev = hwmgr->adev;
178 int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP * 176 int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP *
179 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 177 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
180 int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP * 178 int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP *
181 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 179 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
182 uint32_t val, reg; 180 uint32_t val;
183 181
184 if (low < range->min) 182 if (low < range->min)
185 low = range->min; 183 low = range->min;
@@ -189,18 +187,15 @@ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
189 if (low > high) 187 if (low > high)
190 return -EINVAL; 188 return -EINVAL;
191 189
192 reg = soc15_get_register_offset(THM_HWID, 0, 190 val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL);
193 mmTHM_THERMAL_INT_CTRL_BASE_IDX, mmTHM_THERMAL_INT_CTRL);
194
195 val = cgs_read_register(hwmgr->device, reg);
196 191
197 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); 192 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
198 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); 193 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
199 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); 194 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
200 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); 195 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
201 val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); 196 val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
202 197
203 cgs_write_register(hwmgr->device, reg, val); 198 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);
204 199
205 return 0; 200 return 0;
206} 201}
@@ -212,15 +207,14 @@ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
212*/ 207*/
213static int vega12_thermal_enable_alert(struct pp_hwmgr *hwmgr) 208static int vega12_thermal_enable_alert(struct pp_hwmgr *hwmgr)
214{ 209{
210 struct amdgpu_device *adev = hwmgr->adev;
215 uint32_t val = 0; 211 uint32_t val = 0;
216 uint32_t reg;
217 212
218 val |= (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT); 213 val |= (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT);
219 val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT); 214 val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT);
220 val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT); 215 val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT);
221 216
222 reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA); 217 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, val);
223 cgs_write_register(hwmgr->device, reg, val);
224 218
225 return 0; 219 return 0;
226} 220}
@@ -231,10 +225,9 @@ static int vega12_thermal_enable_alert(struct pp_hwmgr *hwmgr)
231*/ 225*/
232int vega12_thermal_disable_alert(struct pp_hwmgr *hwmgr) 226int vega12_thermal_disable_alert(struct pp_hwmgr *hwmgr)
233{ 227{
234 uint32_t reg; 228 struct amdgpu_device *adev = hwmgr->adev;
235 229
236 reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA); 230 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, 0);
237 cgs_write_register(hwmgr->device, reg, 0);
238 231
239 return 0; 232 return 0;
240} 233}
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
index 8b78bbecd1bc..a202247c9894 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
@@ -377,11 +377,7 @@ struct phm_clocks {
377#define DPMTABLE_UPDATE_SCLK 0x00000004 377#define DPMTABLE_UPDATE_SCLK 0x00000004
378#define DPMTABLE_UPDATE_MCLK 0x00000008 378#define DPMTABLE_UPDATE_MCLK 0x00000008
379#define DPMTABLE_OD_UPDATE_VDDC 0x00000010 379#define DPMTABLE_OD_UPDATE_VDDC 0x00000010
380 380#define DPMTABLE_UPDATE_SOCCLK 0x00000020
381/* To determine if sclk and mclk are in overdrive state */
382#define SCLK_OVERDRIVE_ENABLED 0x00000001
383#define MCLK_OVERDRIVE_ENABLED 0x00000002
384#define VDDC_OVERDRIVE_ENABLED 0x00000010
385 381
386struct phm_odn_performance_level { 382struct phm_odn_performance_level {
387 uint32_t clock; 383 uint32_t clock;
@@ -414,7 +410,10 @@ extern int phm_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
414 struct pp_power_state *adjusted_ps, 410 struct pp_power_state *adjusted_ps,
415 const struct pp_power_state *current_ps); 411 const struct pp_power_state *current_ps);
416 412
413extern int phm_apply_clock_adjust_rules(struct pp_hwmgr *hwmgr);
414
417extern int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level); 415extern int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level);
416extern int phm_pre_display_configuration_changed(struct pp_hwmgr *hwmgr);
418extern int phm_display_configuration_changed(struct pp_hwmgr *hwmgr); 417extern int phm_display_configuration_changed(struct pp_hwmgr *hwmgr);
419extern int phm_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr); 418extern int phm_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr);
420extern int phm_register_irq_handlers(struct pp_hwmgr *hwmgr); 419extern int phm_register_irq_handlers(struct pp_hwmgr *hwmgr);
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index 17f811d181c8..b99fb8ac822c 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -38,6 +38,8 @@ struct phm_fan_speed_info;
38struct pp_atomctrl_voltage_table; 38struct pp_atomctrl_voltage_table;
39 39
40#define VOLTAGE_SCALE 4 40#define VOLTAGE_SCALE 4
41#define VOLTAGE_VID_OFFSET_SCALE1 625
42#define VOLTAGE_VID_OFFSET_SCALE2 100
41 43
42enum DISPLAY_GAP { 44enum DISPLAY_GAP {
43 DISPLAY_GAP_VBLANK_OR_WM = 0, /* Wait for vblank or MCHG watermark. */ 45 DISPLAY_GAP_VBLANK_OR_WM = 0, /* Wait for vblank or MCHG watermark. */
@@ -64,24 +66,6 @@ struct vi_dpm_table {
64#define PCIE_PERF_REQ_GEN2 3 66#define PCIE_PERF_REQ_GEN2 3
65#define PCIE_PERF_REQ_GEN3 4 67#define PCIE_PERF_REQ_GEN3 4
66 68
67enum PP_FEATURE_MASK {
68 PP_SCLK_DPM_MASK = 0x1,
69 PP_MCLK_DPM_MASK = 0x2,
70 PP_PCIE_DPM_MASK = 0x4,
71 PP_SCLK_DEEP_SLEEP_MASK = 0x8,
72 PP_POWER_CONTAINMENT_MASK = 0x10,
73 PP_UVD_HANDSHAKE_MASK = 0x20,
74 PP_SMC_VOLTAGE_CONTROL_MASK = 0x40,
75 PP_VBI_TIME_SUPPORT_MASK = 0x80,
76 PP_ULV_MASK = 0x100,
77 PP_ENABLE_GFX_CG_THRU_SMU = 0x200,
78 PP_CLOCK_STRETCH_MASK = 0x400,
79 PP_OD_FUZZY_FAN_CONTROL_MASK = 0x800,
80 PP_SOCCLK_DPM_MASK = 0x1000,
81 PP_DCEFCLK_DPM_MASK = 0x2000,
82 PP_OVERDRIVE_MASK = 0x4000,
83};
84
85enum PHM_BackEnd_Magic { 69enum PHM_BackEnd_Magic {
86 PHM_Dummy_Magic = 0xAA5555AA, 70 PHM_Dummy_Magic = 0xAA5555AA,
87 PHM_RV770_Magic = 0xDCBAABCD, 71 PHM_RV770_Magic = 0xDCBAABCD,
@@ -245,6 +229,8 @@ struct pp_hwmgr_func {
245 struct pp_power_state *prequest_ps, 229 struct pp_power_state *prequest_ps,
246 const struct pp_power_state *pcurrent_ps); 230 const struct pp_power_state *pcurrent_ps);
247 231
232 int (*apply_clocks_adjust_rules)(struct pp_hwmgr *hwmgr);
233
248 int (*force_dpm_level)(struct pp_hwmgr *hw_mgr, 234 int (*force_dpm_level)(struct pp_hwmgr *hw_mgr,
249 enum amd_dpm_forced_level level); 235 enum amd_dpm_forced_level level);
250 236
@@ -268,6 +254,7 @@ struct pp_hwmgr_func {
268 const void *state); 254 const void *state);
269 int (*enable_clock_power_gating)(struct pp_hwmgr *hwmgr); 255 int (*enable_clock_power_gating)(struct pp_hwmgr *hwmgr);
270 int (*notify_smc_display_config_after_ps_adjustment)(struct pp_hwmgr *hwmgr); 256 int (*notify_smc_display_config_after_ps_adjustment)(struct pp_hwmgr *hwmgr);
257 int (*pre_display_config_changed)(struct pp_hwmgr *hwmgr);
271 int (*display_config_changed)(struct pp_hwmgr *hwmgr); 258 int (*display_config_changed)(struct pp_hwmgr *hwmgr);
272 int (*disable_clock_power_gating)(struct pp_hwmgr *hwmgr); 259 int (*disable_clock_power_gating)(struct pp_hwmgr *hwmgr);
273 int (*update_clock_gatings)(struct pp_hwmgr *hwmgr, 260 int (*update_clock_gatings)(struct pp_hwmgr *hwmgr,
@@ -312,6 +299,7 @@ struct pp_hwmgr_func {
312 int (*display_clock_voltage_request)(struct pp_hwmgr *hwmgr, 299 int (*display_clock_voltage_request)(struct pp_hwmgr *hwmgr,
313 struct pp_display_clock_request *clock); 300 struct pp_display_clock_request *clock);
314 int (*get_max_high_clocks)(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks); 301 int (*get_max_high_clocks)(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks);
302 int (*gfx_off_control)(struct pp_hwmgr *hwmgr, bool enable);
315 int (*power_off_asic)(struct pp_hwmgr *hwmgr); 303 int (*power_off_asic)(struct pp_hwmgr *hwmgr);
316 int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask); 304 int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask);
317 int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); 305 int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf);
@@ -341,6 +329,7 @@ struct pp_hwmgr_func {
341 long *input, uint32_t size); 329 long *input, uint32_t size);
342 int (*set_power_limit)(struct pp_hwmgr *hwmgr, uint32_t n); 330 int (*set_power_limit)(struct pp_hwmgr *hwmgr, uint32_t n);
343 int (*set_mmhub_powergating_by_smu)(struct pp_hwmgr *hwmgr); 331 int (*set_mmhub_powergating_by_smu)(struct pp_hwmgr *hwmgr);
332 int (*smus_notify_pwe)(struct pp_hwmgr *hwmgr);
344}; 333};
345 334
346struct pp_table_func { 335struct pp_table_func {
@@ -718,6 +707,7 @@ struct pp_hwmgr {
718 uint32_t chip_family; 707 uint32_t chip_family;
719 uint32_t chip_id; 708 uint32_t chip_id;
720 uint32_t smu_version; 709 uint32_t smu_version;
710 bool not_vf;
721 bool pm_en; 711 bool pm_en;
722 struct mutex smu_lock; 712 struct mutex smu_lock;
723 713
@@ -764,7 +754,7 @@ struct pp_hwmgr {
764 struct pp_power_state *request_ps; 754 struct pp_power_state *request_ps;
765 struct pp_power_state *boot_ps; 755 struct pp_power_state *boot_ps;
766 struct pp_power_state *uvd_ps; 756 struct pp_power_state *uvd_ps;
767 struct amd_pp_display_configuration display_config; 757 const struct amd_pp_display_configuration *display_config;
768 uint32_t feature_mask; 758 uint32_t feature_mask;
769 bool avfs_supported; 759 bool avfs_supported;
770 /* UMD Pstate */ 760 /* UMD Pstate */
@@ -782,10 +772,13 @@ struct pp_hwmgr {
782}; 772};
783 773
784int hwmgr_early_init(struct pp_hwmgr *hwmgr); 774int hwmgr_early_init(struct pp_hwmgr *hwmgr);
775int hwmgr_sw_init(struct pp_hwmgr *hwmgr);
776int hwmgr_sw_fini(struct pp_hwmgr *hwmgr);
785int hwmgr_hw_init(struct pp_hwmgr *hwmgr); 777int hwmgr_hw_init(struct pp_hwmgr *hwmgr);
786int hwmgr_hw_fini(struct pp_hwmgr *hwmgr); 778int hwmgr_hw_fini(struct pp_hwmgr *hwmgr);
787int hwmgr_hw_suspend(struct pp_hwmgr *hwmgr); 779int hwmgr_suspend(struct pp_hwmgr *hwmgr);
788int hwmgr_hw_resume(struct pp_hwmgr *hwmgr); 780int hwmgr_resume(struct pp_hwmgr *hwmgr);
781
789int hwmgr_handle_task(struct pp_hwmgr *hwmgr, 782int hwmgr_handle_task(struct pp_hwmgr *hwmgr,
790 enum amd_pp_task task_id, 783 enum amd_pp_task task_id,
791 enum amd_pm_state_type *user_state); 784 enum amd_pm_state_type *user_state);
diff --git a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
index 426bff2aad2b..a2991fa2e6f8 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
@@ -75,13 +75,15 @@
75#define PPSMC_MSG_GetMinGfxclkFrequency 0x2C 75#define PPSMC_MSG_GetMinGfxclkFrequency 0x2C
76#define PPSMC_MSG_GetMaxGfxclkFrequency 0x2D 76#define PPSMC_MSG_GetMaxGfxclkFrequency 0x2D
77#define PPSMC_MSG_SoftReset 0x2E 77#define PPSMC_MSG_SoftReset 0x2E
78#define PPSMC_MSG_SetGfxCGPG 0x2F
78#define PPSMC_MSG_SetSoftMaxGfxClk 0x30 79#define PPSMC_MSG_SetSoftMaxGfxClk 0x30
79#define PPSMC_MSG_SetHardMinGfxClk 0x31 80#define PPSMC_MSG_SetHardMinGfxClk 0x31
80#define PPSMC_MSG_SetSoftMaxSocclkByFreq 0x32 81#define PPSMC_MSG_SetSoftMaxSocclkByFreq 0x32
81#define PPSMC_MSG_SetSoftMaxFclkByFreq 0x33 82#define PPSMC_MSG_SetSoftMaxFclkByFreq 0x33
82#define PPSMC_MSG_SetSoftMaxVcn 0x34 83#define PPSMC_MSG_SetSoftMaxVcn 0x34
83#define PPSMC_MSG_PowerGateMmHub 0x35 84#define PPSMC_MSG_PowerGateMmHub 0x35
84#define PPSMC_Message_Count 0x36 85#define PPSMC_MSG_SetRccPfcPmeRestoreRegister 0x36
86#define PPSMC_Message_Count 0x37
85 87
86 88
87typedef uint16_t PPSMC_Result; 89typedef uint16_t PPSMC_Result;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu75.h b/drivers/gpu/drm/amd/powerplay/inc/smu75.h
new file mode 100644
index 000000000000..771523001533
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu75.h
@@ -0,0 +1,760 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#ifndef SMU75_H
24#define SMU75_H
25
26#pragma pack(push, 1)
27
28typedef struct {
29 uint32_t high;
30 uint32_t low;
31} data_64_t;
32
33typedef struct {
34 data_64_t high;
35 data_64_t low;
36} data_128_t;
37
38#define SMU__DGPU_ONLY
39
40#define SMU__NUM_SCLK_DPM_STATE 8
41#define SMU__NUM_MCLK_DPM_LEVELS 4
42#define SMU__NUM_LCLK_DPM_LEVELS 8
43#define SMU__NUM_PCIE_DPM_LEVELS 8
44
45#define SMU7_CONTEXT_ID_SMC 1
46#define SMU7_CONTEXT_ID_VBIOS 2
47
48#define SMU75_MAX_LEVELS_VDDC 16
49#define SMU75_MAX_LEVELS_VDDGFX 16
50#define SMU75_MAX_LEVELS_VDDCI 8
51#define SMU75_MAX_LEVELS_MVDD 4
52
53#define SMU_MAX_SMIO_LEVELS 4
54
55#define SMU75_MAX_LEVELS_GRAPHICS SMU__NUM_SCLK_DPM_STATE
56#define SMU75_MAX_LEVELS_MEMORY SMU__NUM_MCLK_DPM_LEVELS
57#define SMU75_MAX_LEVELS_GIO SMU__NUM_LCLK_DPM_LEVELS
58#define SMU75_MAX_LEVELS_LINK SMU__NUM_PCIE_DPM_LEVELS
59#define SMU75_MAX_LEVELS_UVD 8
60#define SMU75_MAX_LEVELS_VCE 8
61#define SMU75_MAX_LEVELS_ACP 8
62#define SMU75_MAX_LEVELS_SAMU 8
63#define SMU75_MAX_ENTRIES_SMIO 32
64
65#define DPM_NO_LIMIT 0
66#define DPM_NO_UP 1
67#define DPM_GO_DOWN 2
68#define DPM_GO_UP 3
69
70#define SMU7_FIRST_DPM_GRAPHICS_LEVEL 0
71#define SMU7_FIRST_DPM_MEMORY_LEVEL 0
72
73#define GPIO_CLAMP_MODE_VRHOT 1
74#define GPIO_CLAMP_MODE_THERM 2
75#define GPIO_CLAMP_MODE_DC 4
76
77#define SCRATCH_B_TARG_PCIE_INDEX_SHIFT 0
78#define SCRATCH_B_TARG_PCIE_INDEX_MASK (0x7<<SCRATCH_B_TARG_PCIE_INDEX_SHIFT)
79#define SCRATCH_B_CURR_PCIE_INDEX_SHIFT 3
80#define SCRATCH_B_CURR_PCIE_INDEX_MASK (0x7<<SCRATCH_B_CURR_PCIE_INDEX_SHIFT)
81#define SCRATCH_B_TARG_UVD_INDEX_SHIFT 6
82#define SCRATCH_B_TARG_UVD_INDEX_MASK (0x7<<SCRATCH_B_TARG_UVD_INDEX_SHIFT)
83#define SCRATCH_B_CURR_UVD_INDEX_SHIFT 9
84#define SCRATCH_B_CURR_UVD_INDEX_MASK (0x7<<SCRATCH_B_CURR_UVD_INDEX_SHIFT)
85#define SCRATCH_B_TARG_VCE_INDEX_SHIFT 12
86#define SCRATCH_B_TARG_VCE_INDEX_MASK (0x7<<SCRATCH_B_TARG_VCE_INDEX_SHIFT)
87#define SCRATCH_B_CURR_VCE_INDEX_SHIFT 15
88#define SCRATCH_B_CURR_VCE_INDEX_MASK (0x7<<SCRATCH_B_CURR_VCE_INDEX_SHIFT)
89#define SCRATCH_B_TARG_ACP_INDEX_SHIFT 18
90#define SCRATCH_B_TARG_ACP_INDEX_MASK (0x7<<SCRATCH_B_TARG_ACP_INDEX_SHIFT)
91#define SCRATCH_B_CURR_ACP_INDEX_SHIFT 21
92#define SCRATCH_B_CURR_ACP_INDEX_MASK (0x7<<SCRATCH_B_CURR_ACP_INDEX_SHIFT)
93#define SCRATCH_B_TARG_SAMU_INDEX_SHIFT 24
94#define SCRATCH_B_TARG_SAMU_INDEX_MASK (0x7<<SCRATCH_B_TARG_SAMU_INDEX_SHIFT)
95#define SCRATCH_B_CURR_SAMU_INDEX_SHIFT 27
96#define SCRATCH_B_CURR_SAMU_INDEX_MASK (0x7<<SCRATCH_B_CURR_SAMU_INDEX_SHIFT)
97
98/* Virtualization Defines */
99#define CG_XDMA_MASK 0x1
100#define CG_XDMA_SHIFT 0
101#define CG_UVD_MASK 0x2
102#define CG_UVD_SHIFT 1
103#define CG_VCE_MASK 0x4
104#define CG_VCE_SHIFT 2
105#define CG_SAMU_MASK 0x8
106#define CG_SAMU_SHIFT 3
107#define CG_GFX_MASK 0x10
108#define CG_GFX_SHIFT 4
109#define CG_SDMA_MASK 0x20
110#define CG_SDMA_SHIFT 5
111#define CG_HDP_MASK 0x40
112#define CG_HDP_SHIFT 6
113#define CG_MC_MASK 0x80
114#define CG_MC_SHIFT 7
115#define CG_DRM_MASK 0x100
116#define CG_DRM_SHIFT 8
117#define CG_ROM_MASK 0x200
118#define CG_ROM_SHIFT 9
119#define CG_BIF_MASK 0x400
120#define CG_BIF_SHIFT 10
121
122#if defined SMU__DGPU_ONLY
123#define SMU75_DTE_ITERATIONS 5
124#define SMU75_DTE_SOURCES 3
125#define SMU75_DTE_SINKS 1
126#define SMU75_NUM_CPU_TES 0
127#define SMU75_NUM_GPU_TES 1
128#define SMU75_NUM_NON_TES 2
129#define SMU75_DTE_FAN_SCALAR_MIN 0x100
130#define SMU75_DTE_FAN_SCALAR_MAX 0x166
131#define SMU75_DTE_FAN_TEMP_MAX 93
132#define SMU75_DTE_FAN_TEMP_MIN 83
133#endif
134#define SMU75_THERMAL_INPUT_LOOP_COUNT 2
135#define SMU75_THERMAL_CLAMP_MODE_COUNT 2
136
137#define EXP_M1_1 93
138#define EXP_M2_1 195759
139#define EXP_B_1 111176531
140
141#define EXP_M1_2 67
142#define EXP_M2_2 153720
143#define EXP_B_2 94415767
144
145#define EXP_M1_3 48
146#define EXP_M2_3 119796
147#define EXP_B_3 79195279
148
149#define EXP_M1_4 550
150#define EXP_M2_4 1484190
151#define EXP_B_4 1051432828
152
153#define EXP_M1_5 394
154#define EXP_M2_5 1143049
155#define EXP_B_5 864288432
156
157struct SMU7_HystController_Data {
158 uint16_t waterfall_up;
159 uint16_t waterfall_down;
160 uint16_t waterfall_limit;
161 uint16_t release_cnt;
162 uint16_t release_limit;
163 uint16_t spare;
164};
165
166typedef struct SMU7_HystController_Data SMU7_HystController_Data;
167
168struct SMU75_PIDController {
169 uint32_t Ki;
170 int32_t LFWindupUpperLim;
171 int32_t LFWindupLowerLim;
172 uint32_t StatePrecision;
173 uint32_t LfPrecision;
174 uint32_t LfOffset;
175 uint32_t MaxState;
176 uint32_t MaxLfFraction;
177 uint32_t StateShift;
178};
179
180typedef struct SMU75_PIDController SMU75_PIDController;
181
182struct SMU7_LocalDpmScoreboard {
183 uint32_t PercentageBusy;
184
185 int32_t PIDError;
186 int32_t PIDIntegral;
187 int32_t PIDOutput;
188
189 uint32_t SigmaDeltaAccum;
190 uint32_t SigmaDeltaOutput;
191 uint32_t SigmaDeltaLevel;
192
193 uint32_t UtilizationSetpoint;
194
195 uint8_t TdpClampMode;
196 uint8_t TdcClampMode;
197 uint8_t ThermClampMode;
198 uint8_t VoltageBusy;
199
200 int8_t CurrLevel;
201 int8_t TargLevel;
202 uint8_t LevelChangeInProgress;
203 uint8_t UpHyst;
204
205 uint8_t DownHyst;
206 uint8_t VoltageDownHyst;
207 uint8_t DpmEnable;
208 uint8_t DpmRunning;
209
210 uint8_t DpmForce;
211 uint8_t DpmForceLevel;
212 uint8_t DisplayWatermark;
213 uint8_t McArbIndex;
214
215 uint32_t MinimumPerfSclk;
216
217 uint8_t AcpiReq;
218 uint8_t AcpiAck;
219 uint8_t GfxClkSlow;
220 uint8_t GpioClampMode;
221
222 uint8_t EnableModeSwitchRLCNotification;
223 uint8_t EnabledLevelsChange;
224 uint8_t DteClampMode;
225 uint8_t FpsClampMode;
226
227 uint16_t LevelResidencyCounters [SMU75_MAX_LEVELS_GRAPHICS];
228 uint16_t LevelSwitchCounters [SMU75_MAX_LEVELS_GRAPHICS];
229
230 void (*TargetStateCalculator)(uint8_t);
231 void (*SavedTargetStateCalculator)(uint8_t);
232
233 uint16_t AutoDpmInterval;
234 uint16_t AutoDpmRange;
235
236 uint8_t FpsEnabled;
237 uint8_t MaxPerfLevel;
238 uint8_t AllowLowClkInterruptToHost;
239 uint8_t FpsRunning;
240
241 uint32_t MaxAllowedFrequency;
242
243 uint32_t FilteredSclkFrequency;
244 uint32_t LastSclkFrequency;
245 uint32_t FilteredSclkFrequencyCnt;
246
247 uint8_t MinPerfLevel;
248#ifdef SMU__FIRMWARE_SCKS_PRESENT__1
249 uint8_t ScksClampMode;
250 uint8_t padding[2];
251#else
252 uint8_t padding[3];
253#endif
254
255 uint16_t FpsAlpha;
256 uint16_t DeltaTime;
257 uint32_t CurrentFps;
258 uint32_t FilteredFps;
259 uint32_t FrameCount;
260 uint32_t FrameCountLast;
261 uint16_t FpsTargetScalar;
262 uint16_t FpsWaterfallLimitScalar;
263 uint16_t FpsAlphaScalar;
264 uint16_t spare8;
265 SMU7_HystController_Data HystControllerData;
266};
267
268typedef struct SMU7_LocalDpmScoreboard SMU7_LocalDpmScoreboard;
269
270#define SMU7_MAX_VOLTAGE_CLIENTS 12
271
272typedef uint8_t (*VoltageChangeHandler_t)(uint16_t, uint8_t);
273
274#define VDDC_MASK 0x00007FFF
275#define VDDC_SHIFT 0
276#define VDDCI_MASK 0x3FFF8000
277#define VDDCI_SHIFT 15
278#define PHASES_MASK 0xC0000000
279#define PHASES_SHIFT 30
280
281typedef uint32_t SMU_VoltageLevel;
282
283struct SMU7_VoltageScoreboard {
284 SMU_VoltageLevel TargetVoltage;
285 uint16_t MaxVid;
286 uint8_t HighestVidOffset;
287 uint8_t CurrentVidOffset;
288
289 uint16_t CurrentVddc;
290 uint16_t CurrentVddci;
291
292 uint8_t ControllerBusy;
293 uint8_t CurrentVid;
294 uint8_t CurrentVddciVid;
295 uint8_t padding;
296
297 SMU_VoltageLevel RequestedVoltage[SMU7_MAX_VOLTAGE_CLIENTS];
298 SMU_VoltageLevel TargetVoltageState;
299 uint8_t EnabledRequest[SMU7_MAX_VOLTAGE_CLIENTS];
300
301 uint8_t padding2;
302 uint8_t padding3;
303 uint8_t ControllerEnable;
304 uint8_t ControllerRunning;
305 uint16_t CurrentStdVoltageHiSidd;
306 uint16_t CurrentStdVoltageLoSidd;
307 uint8_t OverrideVoltage;
308 uint8_t padding4;
309 uint8_t padding5;
310 uint8_t CurrentPhases;
311
312 VoltageChangeHandler_t ChangeVddc;
313 VoltageChangeHandler_t ChangeVddci;
314 VoltageChangeHandler_t ChangePhase;
315 VoltageChangeHandler_t ChangeMvdd;
316
317 VoltageChangeHandler_t functionLinks[6];
318
319 uint16_t * VddcFollower1;
320 int16_t Driver_OD_RequestedVidOffset1;
321 int16_t Driver_OD_RequestedVidOffset2;
322};
323
324typedef struct SMU7_VoltageScoreboard SMU7_VoltageScoreboard;
325
326#define SMU7_MAX_PCIE_LINK_SPEEDS 3
327
328struct SMU7_PCIeLinkSpeedScoreboard {
329 uint8_t DpmEnable;
330 uint8_t DpmRunning;
331 uint8_t DpmForce;
332 uint8_t DpmForceLevel;
333
334 uint8_t CurrentLinkSpeed;
335 uint8_t EnabledLevelsChange;
336 uint16_t AutoDpmInterval;
337
338 uint16_t AutoDpmRange;
339 uint16_t AutoDpmCount;
340
341 uint8_t DpmMode;
342 uint8_t AcpiReq;
343 uint8_t AcpiAck;
344 uint8_t CurrentLinkLevel;
345};
346
347typedef struct SMU7_PCIeLinkSpeedScoreboard SMU7_PCIeLinkSpeedScoreboard;
348
349#define SMU7_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16
350#define SMU7_LKGE_LUT_NUM_OF_VOLT_ENTRIES 16
351
352#define SMU7_SCALE_I 7
353#define SMU7_SCALE_R 12
354
355struct SMU7_PowerScoreboard {
356 uint32_t GpuPower;
357
358 uint32_t VddcPower;
359 uint32_t VddcVoltage;
360 uint32_t VddcCurrent;
361
362 uint32_t VddciPower;
363 uint32_t VddciVoltage;
364 uint32_t VddciCurrent;
365
366 uint32_t RocPower;
367
368 uint16_t Telemetry_1_slope;
369 uint16_t Telemetry_2_slope;
370 int32_t Telemetry_1_offset;
371 int32_t Telemetry_2_offset;
372
373 uint8_t MCLK_patch_flag;
374 uint8_t reserved[3];
375};
376
377typedef struct SMU7_PowerScoreboard SMU7_PowerScoreboard;
378
379#define SMU7_SCLK_DPM_CONFIG_MASK 0x01
380#define SMU7_VOLTAGE_CONTROLLER_CONFIG_MASK 0x02
381#define SMU7_THERMAL_CONTROLLER_CONFIG_MASK 0x04
382#define SMU7_MCLK_DPM_CONFIG_MASK 0x08
383#define SMU7_UVD_DPM_CONFIG_MASK 0x10
384#define SMU7_VCE_DPM_CONFIG_MASK 0x20
385#define SMU7_ACP_DPM_CONFIG_MASK 0x40
386#define SMU7_SAMU_DPM_CONFIG_MASK 0x80
387#define SMU7_PCIEGEN_DPM_CONFIG_MASK 0x100
388
389#define SMU7_ACP_MCLK_HANDSHAKE_DISABLE 0x00000001
390#define SMU7_ACP_SCLK_HANDSHAKE_DISABLE 0x00000002
391#define SMU7_UVD_MCLK_HANDSHAKE_DISABLE 0x00000100
392#define SMU7_UVD_SCLK_HANDSHAKE_DISABLE 0x00000200
393#define SMU7_VCE_MCLK_HANDSHAKE_DISABLE 0x00010000
394#define SMU7_VCE_SCLK_HANDSHAKE_DISABLE 0x00020000
395
396struct SMU75_SoftRegisters {
397 uint32_t RefClockFrequency;
398 uint32_t PmTimerPeriod;
399 uint32_t FeatureEnables;
400#if defined (SMU__DGPU_ONLY)
401 uint32_t PreVBlankGap;
402 uint32_t VBlankTimeout;
403 uint32_t TrainTimeGap;
404 uint32_t MvddSwitchTime;
405 uint32_t LongestAcpiTrainTime;
406 uint32_t AcpiDelay;
407 uint32_t G5TrainTime;
408 uint32_t DelayMpllPwron;
409 uint32_t VoltageChangeTimeout;
410#endif
411 uint32_t HandshakeDisables;
412
413 uint8_t DisplayPhy1Config;
414 uint8_t DisplayPhy2Config;
415 uint8_t DisplayPhy3Config;
416 uint8_t DisplayPhy4Config;
417
418 uint8_t DisplayPhy5Config;
419 uint8_t DisplayPhy6Config;
420 uint8_t DisplayPhy7Config;
421 uint8_t DisplayPhy8Config;
422
423 uint32_t AverageGraphicsActivity;
424 uint32_t AverageMemoryActivity;
425 uint32_t AverageGioActivity;
426
427 uint8_t SClkDpmEnabledLevels;
428 uint8_t MClkDpmEnabledLevels;
429 uint8_t LClkDpmEnabledLevels;
430 uint8_t PCIeDpmEnabledLevels;
431
432 uint8_t UVDDpmEnabledLevels;
433 uint8_t SAMUDpmEnabledLevels;
434 uint8_t ACPDpmEnabledLevels;
435 uint8_t VCEDpmEnabledLevels;
436
437 uint32_t DRAM_LOG_ADDR_H;
438 uint32_t DRAM_LOG_ADDR_L;
439 uint32_t DRAM_LOG_PHY_ADDR_H;
440 uint32_t DRAM_LOG_PHY_ADDR_L;
441 uint32_t DRAM_LOG_BUFF_SIZE;
442 uint32_t UlvEnterCount;
443 uint32_t UlvTime;
444 uint32_t UcodeLoadStatus;
445 uint32_t AllowMvddSwitch;
446 uint8_t Activity_Weight;
447 uint8_t Reserved8[3];
448};
449
450typedef struct SMU75_SoftRegisters SMU75_SoftRegisters;
451
452struct SMU75_Firmware_Header {
453 uint32_t Digest[5];
454 uint32_t Version;
455 uint32_t HeaderSize;
456 uint32_t Flags;
457 uint32_t EntryPoint;
458 uint32_t CodeSize;
459 uint32_t ImageSize;
460
461 uint32_t Rtos;
462 uint32_t SoftRegisters;
463 uint32_t DpmTable;
464 uint32_t FanTable;
465 uint32_t CacConfigTable;
466 uint32_t CacStatusTable;
467 uint32_t mcRegisterTable;
468 uint32_t mcArbDramTimingTable;
469 uint32_t PmFuseTable;
470 uint32_t Globals;
471 uint32_t ClockStretcherTable;
472 uint32_t VftTable;
473 uint32_t Reserved1;
474 uint32_t AvfsCksOff_AvfsGbvTable;
475 uint32_t AvfsCksOff_BtcGbvTable;
476 uint32_t MM_AvfsTable;
477 uint32_t PowerSharingTable;
478 uint32_t AvfsTable;
479 uint32_t AvfsCksOffGbvTable;
480 uint32_t AvfsMeanNSigma;
481 uint32_t AvfsSclkOffsetTable;
482 uint32_t Reserved[12];
483 uint32_t Signature;
484};
485
486typedef struct SMU75_Firmware_Header SMU75_Firmware_Header;
487
488#define SMU7_FIRMWARE_HEADER_LOCATION 0x20000
489
490enum DisplayConfig {
491 PowerDown = 1,
492 DP54x4,
493 DP54x2,
494 DP54x1,
495 DP27x4,
496 DP27x2,
497 DP27x1,
498 HDMI297,
499 HDMI162,
500 LVDS,
501 DP324x4,
502 DP324x2,
503 DP324x1
504};
505
506#define MC_BLOCK_COUNT 1
507#define CPL_BLOCK_COUNT 5
508#define SE_BLOCK_COUNT 15
509#define GC_BLOCK_COUNT 24
510
511struct SMU7_Local_Cac {
512 uint8_t BlockId;
513 uint8_t SignalId;
514 uint8_t Threshold;
515 uint8_t Padding;
516};
517
518typedef struct SMU7_Local_Cac SMU7_Local_Cac;
519
520struct SMU7_Local_Cac_Table {
521 SMU7_Local_Cac CplLocalCac[CPL_BLOCK_COUNT];
522 SMU7_Local_Cac McLocalCac[MC_BLOCK_COUNT];
523 SMU7_Local_Cac SeLocalCac[SE_BLOCK_COUNT];
524 SMU7_Local_Cac GcLocalCac[GC_BLOCK_COUNT];
525};
526
527typedef struct SMU7_Local_Cac_Table SMU7_Local_Cac_Table;
528
529#pragma pack(pop)
530
531#define CG_SYS_BITMASK_FIRST_BIT 0
532#define CG_SYS_BITMASK_LAST_BIT 10
533#define CG_SYS_BIF_MGLS_SHIFT 0
534#define CG_SYS_ROM_SHIFT 1
535#define CG_SYS_MC_MGCG_SHIFT 2
536#define CG_SYS_MC_MGLS_SHIFT 3
537#define CG_SYS_SDMA_MGCG_SHIFT 4
538#define CG_SYS_SDMA_MGLS_SHIFT 5
539#define CG_SYS_DRM_MGCG_SHIFT 6
540#define CG_SYS_HDP_MGCG_SHIFT 7
541#define CG_SYS_HDP_MGLS_SHIFT 8
542#define CG_SYS_DRM_MGLS_SHIFT 9
543#define CG_SYS_BIF_MGCG_SHIFT 10
544
545#define CG_SYS_BIF_MGLS_MASK 0x1
546#define CG_SYS_ROM_MASK 0x2
547#define CG_SYS_MC_MGCG_MASK 0x4
548#define CG_SYS_MC_MGLS_MASK 0x8
549#define CG_SYS_SDMA_MGCG_MASK 0x10
550#define CG_SYS_SDMA_MGLS_MASK 0x20
551#define CG_SYS_DRM_MGCG_MASK 0x40
552#define CG_SYS_HDP_MGCG_MASK 0x80
553#define CG_SYS_HDP_MGLS_MASK 0x100
554#define CG_SYS_DRM_MGLS_MASK 0x200
555#define CG_SYS_BIF_MGCG_MASK 0x400
556
557#define CG_GFX_BITMASK_FIRST_BIT 16
558#define CG_GFX_BITMASK_LAST_BIT 24
559
560#define CG_GFX_CGCG_SHIFT 16
561#define CG_GFX_CGLS_SHIFT 17
562#define CG_CPF_MGCG_SHIFT 18
563#define CG_RLC_MGCG_SHIFT 19
564#define CG_GFX_OTHERS_MGCG_SHIFT 20
565#define CG_GFX_3DCG_SHIFT 21
566#define CG_GFX_3DLS_SHIFT 22
567#define CG_GFX_RLC_LS_SHIFT 23
568#define CG_GFX_CP_LS_SHIFT 24
569
570#define CG_GFX_CGCG_MASK 0x00010000
571#define CG_GFX_CGLS_MASK 0x00020000
572#define CG_CPF_MGCG_MASK 0x00040000
573#define CG_RLC_MGCG_MASK 0x00080000
574#define CG_GFX_OTHERS_MGCG_MASK 0x00100000
575#define CG_GFX_3DCG_MASK 0x00200000
576#define CG_GFX_3DLS_MASK 0x00400000
577#define CG_GFX_RLC_LS_MASK 0x00800000
578#define CG_GFX_CP_LS_MASK 0x01000000
579
580
581#define VRCONF_VDDC_MASK 0x000000FF
582#define VRCONF_VDDC_SHIFT 0
583#define VRCONF_VDDGFX_MASK 0x0000FF00
584#define VRCONF_VDDGFX_SHIFT 8
585#define VRCONF_VDDCI_MASK 0x00FF0000
586#define VRCONF_VDDCI_SHIFT 16
587#define VRCONF_MVDD_MASK 0xFF000000
588#define VRCONF_MVDD_SHIFT 24
589
590#define VR_MERGED_WITH_VDDC 0
591#define VR_SVI2_PLANE_1 1
592#define VR_SVI2_PLANE_2 2
593#define VR_SMIO_PATTERN_1 3
594#define VR_SMIO_PATTERN_2 4
595#define VR_STATIC_VOLTAGE 5
596
597#define CLOCK_STRETCHER_MAX_ENTRIES 0x4
598#define CKS_LOOKUPTable_MAX_ENTRIES 0x4
599
600#define CLOCK_STRETCHER_SETTING_DDT_MASK 0x01
601#define CLOCK_STRETCHER_SETTING_DDT_SHIFT 0x0
602#define CLOCK_STRETCHER_SETTING_STRETCH_AMOUNT_MASK 0x1E
603#define CLOCK_STRETCHER_SETTING_STRETCH_AMOUNT_SHIFT 0x1
604#define CLOCK_STRETCHER_SETTING_ENABLE_MASK 0x80
605#define CLOCK_STRETCHER_SETTING_ENABLE_SHIFT 0x7
606
607struct SMU_ClockStretcherDataTableEntry {
608 uint8_t minVID;
609 uint8_t maxVID;
610
611 uint16_t setting;
612};
613typedef struct SMU_ClockStretcherDataTableEntry SMU_ClockStretcherDataTableEntry;
614
615struct SMU_ClockStretcherDataTable {
616 SMU_ClockStretcherDataTableEntry ClockStretcherDataTableEntry[CLOCK_STRETCHER_MAX_ENTRIES];
617};
618typedef struct SMU_ClockStretcherDataTable SMU_ClockStretcherDataTable;
619
620struct SMU_CKS_LOOKUPTableEntry {
621 uint16_t minFreq;
622 uint16_t maxFreq;
623
624 uint8_t setting;
625 uint8_t padding[3];
626};
627typedef struct SMU_CKS_LOOKUPTableEntry SMU_CKS_LOOKUPTableEntry;
628
629struct SMU_CKS_LOOKUPTable {
630 SMU_CKS_LOOKUPTableEntry CKS_LOOKUPTableEntry[CKS_LOOKUPTable_MAX_ENTRIES];
631};
632typedef struct SMU_CKS_LOOKUPTable SMU_CKS_LOOKUPTable;
633
634struct AgmAvfsData_t {
635 uint16_t avgPsmCount[28];
636 uint16_t minPsmCount[28];
637};
638typedef struct AgmAvfsData_t AgmAvfsData_t;
639
640enum VFT_COLUMNS {
641 SCLK0,
642 SCLK1,
643 SCLK2,
644 SCLK3,
645 SCLK4,
646 SCLK5,
647 SCLK6,
648 SCLK7,
649
650 NUM_VFT_COLUMNS
651};
652enum {
653 SCS_FUSE_T0,
654 SCS_FUSE_T1,
655 NUM_SCS_FUSE_TEMPERATURE
656};
657enum {
658 SCKS_ON,
659 SCKS_OFF,
660 NUM_SCKS_STATE_TYPES
661};
662
663#define VFT_TABLE_DEFINED
664
665#define TEMP_RANGE_MAXSTEPS 12
666struct VFT_CELL_t {
667 uint16_t Voltage;
668};
669
670typedef struct VFT_CELL_t VFT_CELL_t;
671#ifdef SMU__FIRMWARE_SCKS_PRESENT__1
672struct SCS_CELL_t {
673 uint16_t PsmCnt[NUM_SCKS_STATE_TYPES];
674};
675typedef struct SCS_CELL_t SCS_CELL_t;
676#endif
677
678struct VFT_TABLE_t {
679 VFT_CELL_t Cell[TEMP_RANGE_MAXSTEPS][NUM_VFT_COLUMNS];
680 uint16_t AvfsGbv [NUM_VFT_COLUMNS];
681 uint16_t BtcGbv [NUM_VFT_COLUMNS];
682 int16_t Temperature [TEMP_RANGE_MAXSTEPS];
683
684#ifdef SMU__FIRMWARE_SCKS_PRESENT__1
685 SCS_CELL_t ScksCell[TEMP_RANGE_MAXSTEPS][NUM_VFT_COLUMNS];
686#endif
687
688 uint8_t NumTemperatureSteps;
689 uint8_t padding[3];
690};
691typedef struct VFT_TABLE_t VFT_TABLE_t;
692
693#define BTCGB_VDROOP_TABLE_MAX_ENTRIES 2
694#define AVFSGB_VDROOP_TABLE_MAX_ENTRIES 2
695
696struct GB_VDROOP_TABLE_t {
697 int32_t a0;
698 int32_t a1;
699 int32_t a2;
700 uint32_t spare;
701};
702typedef struct GB_VDROOP_TABLE_t GB_VDROOP_TABLE_t;
703
704struct SMU_QuadraticCoeffs {
705 int32_t m1;
706 int32_t b;
707
708 int16_t m2;
709 uint8_t m1_shift;
710 uint8_t m2_shift;
711};
712typedef struct SMU_QuadraticCoeffs SMU_QuadraticCoeffs;
713
714struct AVFS_Margin_t {
715 VFT_CELL_t Cell[NUM_VFT_COLUMNS];
716};
717typedef struct AVFS_Margin_t AVFS_Margin_t;
718
719struct AVFS_CksOff_Gbv_t {
720 VFT_CELL_t Cell[NUM_VFT_COLUMNS];
721};
722typedef struct AVFS_CksOff_Gbv_t AVFS_CksOff_Gbv_t;
723
724struct AVFS_CksOff_AvfsGbv_t {
725 VFT_CELL_t Cell[NUM_VFT_COLUMNS];
726};
727typedef struct AVFS_CksOff_AvfsGbv_t AVFS_CksOff_AvfsGbv_t;
728
729struct AVFS_CksOff_BtcGbv_t {
730 VFT_CELL_t Cell[NUM_VFT_COLUMNS];
731};
732typedef struct AVFS_CksOff_BtcGbv_t AVFS_CksOff_BtcGbv_t;
733
734struct AVFS_meanNsigma_t {
735 uint32_t Aconstant[3];
736 uint16_t DC_tol_sigma;
737 uint16_t Platform_mean;
738 uint16_t Platform_sigma;
739 uint16_t PSM_Age_CompFactor;
740 uint8_t Static_Voltage_Offset[NUM_VFT_COLUMNS];
741};
742typedef struct AVFS_meanNsigma_t AVFS_meanNsigma_t;
743
744struct AVFS_Sclk_Offset_t {
745 uint16_t Sclk_Offset[8];
746};
747typedef struct AVFS_Sclk_Offset_t AVFS_Sclk_Offset_t;
748
749struct Power_Sharing_t {
750 uint32_t EnergyCounter;
751 uint32_t EngeryThreshold;
752 uint64_t AM_SCLK_CNT;
753 uint64_t AM_0_BUSY_CNT;
754};
755typedef struct Power_Sharing_t Power_Sharing_t;
756
757
758#endif
759
760
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu75_discrete.h b/drivers/gpu/drm/amd/powerplay/inc/smu75_discrete.h
new file mode 100644
index 000000000000..b64e58a22ddf
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu75_discrete.h
@@ -0,0 +1,886 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#ifndef SMU75_DISCRETE_H
25#define SMU75_DISCRETE_H
26
27#include "smu75.h"
28
29#pragma pack(push, 1)
30
31#define NUM_SCLK_RANGE 8
32
33#define VCO_3_6 1
34#define VCO_2_4 3
35
36#define POSTDIV_DIV_BY_1 0
37#define POSTDIV_DIV_BY_2 1
38#define POSTDIV_DIV_BY_4 2
39#define POSTDIV_DIV_BY_8 3
40#define POSTDIV_DIV_BY_16 4
41
42struct sclkFcwRange_t {
43 uint8_t vco_setting; /* 1: 3-6GHz, 3: 2-4GHz */
44 uint8_t postdiv; /* divide by 2^n */
45 uint16_t fcw_pcc;
46 uint16_t fcw_trans_upper;
47 uint16_t fcw_trans_lower;
48};
49typedef struct sclkFcwRange_t sclkFcwRange_t;
50
51struct SMIO_Pattern {
52 uint16_t Voltage;
53 uint8_t Smio;
54 uint8_t padding;
55};
56
57typedef struct SMIO_Pattern SMIO_Pattern;
58
59struct SMIO_Table {
60 SMIO_Pattern Pattern[SMU_MAX_SMIO_LEVELS];
61};
62
63typedef struct SMIO_Table SMIO_Table;
64
65struct SMU_SclkSetting {
66 uint32_t SclkFrequency;
67 uint16_t Fcw_int;
68 uint16_t Fcw_frac;
69 uint16_t Pcc_fcw_int;
70 uint8_t PllRange;
71 uint8_t SSc_En;
72 uint16_t Sclk_slew_rate;
73 uint16_t Pcc_up_slew_rate;
74 uint16_t Pcc_down_slew_rate;
75 uint16_t Fcw1_int;
76 uint16_t Fcw1_frac;
77 uint16_t Sclk_ss_slew_rate;
78};
79typedef struct SMU_SclkSetting SMU_SclkSetting;
80
81struct SMU75_Discrete_GraphicsLevel {
82 SMU_VoltageLevel MinVoltage;
83
84 uint8_t pcieDpmLevel;
85 uint8_t DeepSleepDivId;
86 uint16_t ActivityLevel;
87
88 uint32_t CgSpllFuncCntl3;
89 uint32_t CgSpllFuncCntl4;
90 uint32_t CcPwrDynRm;
91 uint32_t CcPwrDynRm1;
92
93 uint8_t SclkDid;
94 uint8_t padding;
95 uint8_t EnabledForActivity;
96 uint8_t EnabledForThrottle;
97 uint8_t UpHyst;
98 uint8_t DownHyst;
99 uint8_t VoltageDownHyst;
100 uint8_t PowerThrottle;
101
102 SMU_SclkSetting SclkSetting;
103
104 uint8_t ScksStretchThreshVid[NUM_SCKS_STATE_TYPES];
105 uint16_t Padding;
106};
107
108typedef struct SMU75_Discrete_GraphicsLevel SMU75_Discrete_GraphicsLevel;
109
110struct SMU75_Discrete_ACPILevel {
111 uint32_t Flags;
112 SMU_VoltageLevel MinVoltage;
113 uint32_t SclkFrequency;
114 uint8_t SclkDid;
115 uint8_t DisplayWatermark;
116 uint8_t DeepSleepDivId;
117 uint8_t padding;
118 uint32_t CcPwrDynRm;
119 uint32_t CcPwrDynRm1;
120
121 SMU_SclkSetting SclkSetting;
122};
123
124typedef struct SMU75_Discrete_ACPILevel SMU75_Discrete_ACPILevel;
125
126struct SMU75_Discrete_Ulv {
127 uint32_t CcPwrDynRm;
128 uint32_t CcPwrDynRm1;
129 uint16_t VddcOffset;
130 uint8_t VddcOffsetVid;
131 uint8_t VddcPhase;
132 uint16_t BifSclkDfs;
133 uint16_t Reserved;
134};
135
136typedef struct SMU75_Discrete_Ulv SMU75_Discrete_Ulv;
137
138struct SMU75_Discrete_MemoryLevel {
139 SMU_VoltageLevel MinVoltage;
140 uint32_t MinMvdd;
141
142 uint32_t MclkFrequency;
143
144 uint8_t StutterEnable;
145 uint8_t EnabledForThrottle;
146 uint8_t EnabledForActivity;
147 uint8_t padding_0;
148
149 uint8_t UpHyst;
150 uint8_t DownHyst;
151 uint8_t VoltageDownHyst;
152 uint8_t padding_1;
153
154 uint16_t ActivityLevel;
155 uint8_t DisplayWatermark;
156 uint8_t padding_2;
157
158 uint16_t Fcw_int;
159 uint16_t Fcw_frac;
160 uint8_t Postdiv;
161 uint8_t padding_3[3];
162};
163
164typedef struct SMU75_Discrete_MemoryLevel SMU75_Discrete_MemoryLevel;
165
166struct SMU75_Discrete_LinkLevel {
167 uint8_t PcieGenSpeed;
168 uint8_t PcieLaneCount;
169 uint8_t EnabledForActivity;
170 uint8_t SPC;
171 uint32_t DownThreshold;
172 uint32_t UpThreshold;
173 uint16_t BifSclkDfs;
174 uint16_t Reserved;
175};
176
177typedef struct SMU75_Discrete_LinkLevel SMU75_Discrete_LinkLevel;
178
179
180/* MC ARB DRAM Timing registers. */
181struct SMU75_Discrete_MCArbDramTimingTableEntry {
182 uint32_t McArbDramTiming;
183 uint32_t McArbDramTiming2;
184 uint32_t McArbBurstTime;
185 uint32_t McArbRfshRate;
186 uint32_t McArbMisc3;
187};
188
189typedef struct SMU75_Discrete_MCArbDramTimingTableEntry SMU75_Discrete_MCArbDramTimingTableEntry;
190
191struct SMU75_Discrete_MCArbDramTimingTable {
192 SMU75_Discrete_MCArbDramTimingTableEntry entries[SMU__NUM_SCLK_DPM_STATE][SMU__NUM_MCLK_DPM_LEVELS];
193};
194
195typedef struct SMU75_Discrete_MCArbDramTimingTable SMU75_Discrete_MCArbDramTimingTable;
196
197/* UVD VCLK/DCLK state (level) definition. */
198struct SMU75_Discrete_UvdLevel {
199 uint32_t VclkFrequency;
200 uint32_t DclkFrequency;
201 SMU_VoltageLevel MinVoltage;
202 uint8_t VclkDivider;
203 uint8_t DclkDivider;
204 uint8_t padding[2];
205};
206
207typedef struct SMU75_Discrete_UvdLevel SMU75_Discrete_UvdLevel;
208
209/* Clocks for other external blocks (VCE, ACP, SAMU). */
210struct SMU75_Discrete_ExtClkLevel {
211 uint32_t Frequency;
212 SMU_VoltageLevel MinVoltage;
213 uint8_t Divider;
214 uint8_t padding[3];
215};
216
217typedef struct SMU75_Discrete_ExtClkLevel SMU75_Discrete_ExtClkLevel;
218
219struct SMU75_Discrete_StateInfo {
220 uint32_t SclkFrequency;
221 uint32_t MclkFrequency;
222 uint32_t VclkFrequency;
223 uint32_t DclkFrequency;
224 uint32_t SamclkFrequency;
225 uint32_t AclkFrequency;
226 uint32_t EclkFrequency;
227 uint16_t MvddVoltage;
228 uint16_t padding16;
229 uint8_t DisplayWatermark;
230 uint8_t McArbIndex;
231 uint8_t McRegIndex;
232 uint8_t SeqIndex;
233 uint8_t SclkDid;
234 int8_t SclkIndex;
235 int8_t MclkIndex;
236 uint8_t PCIeGen;
237};
238
239typedef struct SMU75_Discrete_StateInfo SMU75_Discrete_StateInfo;
240
241struct SMU75_Discrete_DpmTable {
242 SMU75_PIDController GraphicsPIDController;
243 SMU75_PIDController MemoryPIDController;
244 SMU75_PIDController LinkPIDController;
245
246 uint32_t SystemFlags;
247
248 uint32_t VRConfig;
249 uint32_t SmioMask1;
250 uint32_t SmioMask2;
251 SMIO_Table SmioTable1;
252 SMIO_Table SmioTable2;
253
254 uint32_t MvddLevelCount;
255
256 uint8_t BapmVddcVidHiSidd [SMU75_MAX_LEVELS_VDDC];
257 uint8_t BapmVddcVidLoSidd [SMU75_MAX_LEVELS_VDDC];
258 uint8_t BapmVddcVidHiSidd2 [SMU75_MAX_LEVELS_VDDC];
259
260 uint8_t GraphicsDpmLevelCount;
261 uint8_t MemoryDpmLevelCount;
262 uint8_t LinkLevelCount;
263 uint8_t MasterDeepSleepControl;
264
265 uint8_t UvdLevelCount;
266 uint8_t VceLevelCount;
267 uint8_t AcpLevelCount;
268 uint8_t SamuLevelCount;
269
270 uint8_t ThermOutGpio;
271 uint8_t ThermOutPolarity;
272 uint8_t ThermOutMode;
273 uint8_t BootPhases;
274
275 uint8_t VRHotLevel;
276 uint8_t LdoRefSel;
277
278 uint8_t Reserved1[2];
279
280 uint16_t FanStartTemperature;
281 uint16_t FanStopTemperature;
282
283 uint16_t MaxVoltage;
284 uint16_t Reserved2;
285 uint32_t Reserved;
286
287 SMU75_Discrete_GraphicsLevel GraphicsLevel [SMU75_MAX_LEVELS_GRAPHICS];
288 SMU75_Discrete_MemoryLevel MemoryACPILevel;
289 SMU75_Discrete_MemoryLevel MemoryLevel [SMU75_MAX_LEVELS_MEMORY];
290 SMU75_Discrete_LinkLevel LinkLevel [SMU75_MAX_LEVELS_LINK];
291 SMU75_Discrete_ACPILevel ACPILevel;
292 SMU75_Discrete_UvdLevel UvdLevel [SMU75_MAX_LEVELS_UVD];
293 SMU75_Discrete_ExtClkLevel VceLevel [SMU75_MAX_LEVELS_VCE];
294 SMU75_Discrete_ExtClkLevel AcpLevel [SMU75_MAX_LEVELS_ACP];
295 SMU75_Discrete_ExtClkLevel SamuLevel [SMU75_MAX_LEVELS_SAMU];
296 SMU75_Discrete_Ulv Ulv;
297
298 uint8_t DisplayWatermark [SMU75_MAX_LEVELS_MEMORY][SMU75_MAX_LEVELS_GRAPHICS];
299
300 uint32_t SclkStepSize;
301 uint32_t Smio [SMU75_MAX_ENTRIES_SMIO];
302
303 uint8_t UvdBootLevel;
304 uint8_t VceBootLevel;
305 uint8_t AcpBootLevel;
306 uint8_t SamuBootLevel;
307
308 uint8_t GraphicsBootLevel;
309 uint8_t GraphicsVoltageChangeEnable;
310 uint8_t GraphicsThermThrottleEnable;
311 uint8_t GraphicsInterval;
312
313 uint8_t VoltageInterval;
314 uint8_t ThermalInterval;
315 uint16_t TemperatureLimitHigh;
316
317 uint16_t TemperatureLimitLow;
318 uint8_t MemoryBootLevel;
319 uint8_t MemoryVoltageChangeEnable;
320
321 uint16_t BootMVdd;
322 uint8_t MemoryInterval;
323 uint8_t MemoryThermThrottleEnable;
324
325 uint16_t VoltageResponseTime;
326 uint16_t PhaseResponseTime;
327
328 uint8_t PCIeBootLinkLevel;
329 uint8_t PCIeGenInterval;
330 uint8_t DTEInterval;
331 uint8_t DTEMode;
332
333 uint8_t SVI2Enable;
334 uint8_t VRHotGpio;
335 uint8_t AcDcGpio;
336 uint8_t ThermGpio;
337
338 uint16_t PPM_PkgPwrLimit;
339 uint16_t PPM_TemperatureLimit;
340
341 uint16_t DefaultTdp;
342 uint16_t TargetTdp;
343
344 uint16_t FpsHighThreshold;
345 uint16_t FpsLowThreshold;
346
347 uint16_t BAPMTI_R [SMU75_DTE_ITERATIONS][SMU75_DTE_SOURCES][SMU75_DTE_SINKS];
348 uint16_t BAPMTI_RC [SMU75_DTE_ITERATIONS][SMU75_DTE_SOURCES][SMU75_DTE_SINKS];
349
350 uint16_t TemperatureLimitEdge;
351 uint16_t TemperatureLimitHotspot;
352
353 uint16_t BootVddc;
354 uint16_t BootVddci;
355
356 uint16_t FanGainEdge;
357 uint16_t FanGainHotspot;
358
359 uint32_t LowSclkInterruptThreshold;
360 uint32_t VddGfxReChkWait;
361
362 uint8_t ClockStretcherAmount;
363 uint8_t Sclk_CKS_masterEn0_7;
364 uint8_t Sclk_CKS_masterEn8_15;
365 uint8_t DPMFreezeAndForced;
366
367 uint8_t Sclk_voltageOffset[8];
368
369 SMU_ClockStretcherDataTable ClockStretcherDataTable;
370 SMU_CKS_LOOKUPTable CKS_LOOKUPTable;
371
372 uint32_t CurrSclkPllRange;
373 sclkFcwRange_t SclkFcwRangeTable[NUM_SCLK_RANGE];
374
375 GB_VDROOP_TABLE_t BTCGB_VDROOP_TABLE[BTCGB_VDROOP_TABLE_MAX_ENTRIES];
376 SMU_QuadraticCoeffs AVFSGB_FUSE_TABLE[AVFSGB_VDROOP_TABLE_MAX_ENTRIES];
377};
378
379typedef struct SMU75_Discrete_DpmTable SMU75_Discrete_DpmTable;
380
381struct SMU75_Discrete_FanTable {
382 uint16_t FdoMode;
383 int16_t TempMin;
384 int16_t TempMed;
385 int16_t TempMax;
386 int16_t Slope1;
387 int16_t Slope2;
388 int16_t FdoMin;
389 int16_t HystUp;
390 int16_t HystDown;
391 int16_t HystSlope;
392 int16_t TempRespLim;
393 int16_t TempCurr;
394 int16_t SlopeCurr;
395 int16_t PwmCurr;
396 uint32_t RefreshPeriod;
397 int16_t FdoMax;
398 uint8_t TempSrc;
399 int8_t Padding;
400};
401
402typedef struct SMU75_Discrete_FanTable SMU75_Discrete_FanTable;
403
404#define SMU7_DISCRETE_GPIO_SCLK_DEBUG 4
405#define SMU7_DISCRETE_GPIO_SCLK_DEBUG_BIT (0x1 << SMU7_DISCRETE_GPIO_SCLK_DEBUG)
406
407
408
409struct SMU7_MclkDpmScoreboard {
410 uint32_t PercentageBusy;
411
412 int32_t PIDError;
413 int32_t PIDIntegral;
414 int32_t PIDOutput;
415
416 uint32_t SigmaDeltaAccum;
417 uint32_t SigmaDeltaOutput;
418 uint32_t SigmaDeltaLevel;
419
420 uint32_t UtilizationSetpoint;
421
422 uint8_t TdpClampMode;
423 uint8_t TdcClampMode;
424 uint8_t ThermClampMode;
425 uint8_t VoltageBusy;
426
427 int8_t CurrLevel;
428 int8_t TargLevel;
429 uint8_t LevelChangeInProgress;
430 uint8_t UpHyst;
431
432 uint8_t DownHyst;
433 uint8_t VoltageDownHyst;
434 uint8_t DpmEnable;
435 uint8_t DpmRunning;
436
437 uint8_t DpmForce;
438 uint8_t DpmForceLevel;
439 uint8_t padding2;
440 uint8_t McArbIndex;
441
442 uint32_t MinimumPerfMclk;
443
444 uint8_t AcpiReq;
445 uint8_t AcpiAck;
446 uint8_t MclkSwitchInProgress;
447 uint8_t MclkSwitchCritical;
448
449 uint8_t IgnoreVBlank;
450 uint8_t TargetMclkIndex;
451 uint8_t TargetMvddIndex;
452 uint8_t MclkSwitchResult;
453
454 uint16_t VbiFailureCount;
455 uint8_t VbiWaitCounter;
456 uint8_t EnabledLevelsChange;
457
458 uint16_t LevelResidencyCounters [SMU75_MAX_LEVELS_MEMORY];
459 uint16_t LevelSwitchCounters [SMU75_MAX_LEVELS_MEMORY];
460
461 void (*TargetStateCalculator)(uint8_t);
462 void (*SavedTargetStateCalculator)(uint8_t);
463
464 uint16_t AutoDpmInterval;
465 uint16_t AutoDpmRange;
466
467 uint16_t VbiTimeoutCount;
468 uint16_t MclkSwitchingTime;
469
470 uint8_t fastSwitch;
471 uint8_t Save_PIC_VDDGFX_EXIT;
472 uint8_t Save_PIC_VDDGFX_ENTER;
473 uint8_t VbiTimeout;
474
475 uint32_t HbmTempRegBackup;
476};
477
478typedef struct SMU7_MclkDpmScoreboard SMU7_MclkDpmScoreboard;
479
480struct SMU7_UlvScoreboard {
481 uint8_t EnterUlv;
482 uint8_t ExitUlv;
483 uint8_t UlvActive;
484 uint8_t WaitingForUlv;
485 uint8_t UlvEnable;
486 uint8_t UlvRunning;
487 uint8_t UlvMasterEnable;
488 uint8_t padding;
489 uint32_t UlvAbortedCount;
490 uint32_t UlvTimeStamp;
491};
492
493typedef struct SMU7_UlvScoreboard SMU7_UlvScoreboard;
494
495struct VddgfxSavedRegisters {
496 uint32_t GPU_DBG[3];
497 uint32_t MEC_BaseAddress_Hi;
498 uint32_t MEC_BaseAddress_Lo;
499 uint32_t THM_TMON0_CTRL2__RDIR_PRESENT;
500 uint32_t THM_TMON1_CTRL2__RDIR_PRESENT;
501 uint32_t CP_INT_CNTL;
502};
503
504typedef struct VddgfxSavedRegisters VddgfxSavedRegisters;
505
506struct SMU7_VddGfxScoreboard {
507 uint8_t VddGfxEnable;
508 uint8_t VddGfxActive;
509 uint8_t VPUResetOccured;
510 uint8_t padding;
511
512 uint32_t VddGfxEnteredCount;
513 uint32_t VddGfxAbortedCount;
514
515 uint32_t VddGfxVid;
516
517 VddgfxSavedRegisters SavedRegisters;
518};
519
520typedef struct SMU7_VddGfxScoreboard SMU7_VddGfxScoreboard;
521
522struct SMU7_TdcLimitScoreboard {
523 uint8_t Enable;
524 uint8_t Running;
525 uint16_t Alpha;
526 uint32_t FilteredIddc;
527 uint32_t IddcLimit;
528 uint32_t IddcHyst;
529 SMU7_HystController_Data HystControllerData;
530};
531
532typedef struct SMU7_TdcLimitScoreboard SMU7_TdcLimitScoreboard;
533
534struct SMU7_PkgPwrLimitScoreboard {
535 uint8_t Enable;
536 uint8_t Running;
537 uint16_t Alpha;
538 uint32_t FilteredPkgPwr;
539 uint32_t Limit;
540 uint32_t Hyst;
541 uint32_t LimitFromDriver;
542 uint8_t PowerSharingEnabled;
543 uint8_t PowerSharingCounter;
544 uint8_t PowerSharingINTEnabled;
545 uint8_t GFXActivityCounterEnabled;
546 uint32_t EnergyCount;
547 uint32_t PSACTCount;
548 uint8_t RollOverRequired;
549 uint8_t RollOverCount;
550 uint8_t padding[2];
551 SMU7_HystController_Data HystControllerData;
552};
553
554typedef struct SMU7_PkgPwrLimitScoreboard SMU7_PkgPwrLimitScoreboard;
555
556struct SMU7_BapmScoreboard {
557 uint32_t source_powers[SMU75_DTE_SOURCES];
558 uint32_t source_powers_last[SMU75_DTE_SOURCES];
559 int32_t entity_temperatures[SMU75_NUM_GPU_TES];
560 int32_t initial_entity_temperatures[SMU75_NUM_GPU_TES];
561 int32_t Limit;
562 int32_t Hyst;
563 int32_t therm_influence_coeff_table[SMU75_DTE_ITERATIONS * SMU75_DTE_SOURCES * SMU75_DTE_SINKS * 2];
564 int32_t therm_node_table[SMU75_DTE_ITERATIONS * SMU75_DTE_SOURCES * SMU75_DTE_SINKS];
565 uint16_t ConfigTDPPowerScalar;
566 uint16_t FanSpeedPowerScalar;
567 uint16_t OverDrivePowerScalar;
568 uint16_t OverDriveLimitScalar;
569 uint16_t FinalPowerScalar;
570 uint8_t VariantID;
571 uint8_t spare997;
572
573 SMU7_HystController_Data HystControllerData;
574
575 int32_t temperature_gradient_slope;
576 int32_t temperature_gradient;
577 uint32_t measured_temperature;
578};
579
580
581typedef struct SMU7_BapmScoreboard SMU7_BapmScoreboard;
582
583struct SMU7_AcpiScoreboard {
584 uint32_t SavedInterruptMask[2];
585 uint8_t LastACPIRequest;
586 uint8_t CgBifResp;
587 uint8_t RequestType;
588 uint8_t Padding;
589 SMU75_Discrete_ACPILevel D0Level;
590};
591
592typedef struct SMU7_AcpiScoreboard SMU7_AcpiScoreboard;
593
594struct SMU75_Discrete_PmFuses {
595 uint8_t BapmVddCVidHiSidd[8];
596
597 uint8_t BapmVddCVidLoSidd[8];
598
599 uint8_t VddCVid[8];
600
601 uint8_t SviLoadLineEn;
602 uint8_t SviLoadLineVddC;
603 uint8_t SviLoadLineTrimVddC;
604 uint8_t SviLoadLineOffsetVddC;
605
606 uint16_t TDC_VDDC_PkgLimit;
607 uint8_t TDC_VDDC_ThrottleReleaseLimitPerc;
608 uint8_t TDC_MAWt;
609
610 uint8_t TdcWaterfallCtl;
611 uint8_t LPMLTemperatureMin;
612 uint8_t LPMLTemperatureMax;
613 uint8_t Reserved;
614
615 uint8_t LPMLTemperatureScaler[16];
616
617 int16_t FuzzyFan_ErrorSetDelta;
618 int16_t FuzzyFan_ErrorRateSetDelta;
619 int16_t FuzzyFan_PwmSetDelta;
620 uint16_t Reserved6;
621
622 uint8_t GnbLPML[16];
623
624 uint8_t GnbLPMLMaxVid;
625 uint8_t GnbLPMLMinVid;
626 uint8_t Reserved1[2];
627
628 uint16_t BapmVddCBaseLeakageHiSidd;
629 uint16_t BapmVddCBaseLeakageLoSidd;
630
631 uint16_t VFT_Temp[3];
632 uint8_t Version;
633 uint8_t padding;
634
635 SMU_QuadraticCoeffs VFT_ATE[3];
636
637 SMU_QuadraticCoeffs AVFS_GB;
638 SMU_QuadraticCoeffs ATE_ACBTC_GB;
639
640 SMU_QuadraticCoeffs P2V;
641
642 uint32_t PsmCharzFreq;
643
644 uint16_t InversionVoltage;
645 uint16_t PsmCharzTemp;
646
647 uint32_t EnabledAvfsModules;
648
649 SMU_QuadraticCoeffs BtcGbv_CksOff;
650};
651
652typedef struct SMU75_Discrete_PmFuses SMU75_Discrete_PmFuses;
653
654struct SMU7_Discrete_Log_Header_Table {
655 uint32_t version;
656 uint32_t asic_id;
657 uint16_t flags;
658 uint16_t entry_size;
659 uint32_t total_size;
660 uint32_t num_of_entries;
661 uint8_t type;
662 uint8_t mode;
663 uint8_t filler_0[2];
664 uint32_t filler_1[2];
665};
666
667typedef struct SMU7_Discrete_Log_Header_Table SMU7_Discrete_Log_Header_Table;
668
669struct SMU7_Discrete_Log_Cntl {
670 uint8_t Enabled;
671 uint8_t Type;
672 uint8_t padding[2];
673 uint32_t BufferSize;
674 uint32_t SamplesLogged;
675 uint32_t SampleSize;
676 uint32_t AddrL;
677 uint32_t AddrH;
678};
679
680typedef struct SMU7_Discrete_Log_Cntl SMU7_Discrete_Log_Cntl;
681
682#if defined SMU__DGPU_ONLY
683#define CAC_ACC_NW_NUM_OF_SIGNALS 87
684#endif
685
686
687struct SMU7_Discrete_Cac_Collection_Table {
688 uint32_t temperature;
689 uint32_t cac_acc_nw[CAC_ACC_NW_NUM_OF_SIGNALS];
690};
691
692typedef struct SMU7_Discrete_Cac_Collection_Table SMU7_Discrete_Cac_Collection_Table;
693
694struct SMU7_Discrete_Cac_Verification_Table {
695 uint32_t VddcTotalPower;
696 uint32_t VddcLeakagePower;
697 uint32_t VddcConstantPower;
698 uint32_t VddcGfxDynamicPower;
699 uint32_t VddcUvdDynamicPower;
700 uint32_t VddcVceDynamicPower;
701 uint32_t VddcAcpDynamicPower;
702 uint32_t VddcPcieDynamicPower;
703 uint32_t VddcDceDynamicPower;
704 uint32_t VddcCurrent;
705 uint32_t VddcVoltage;
706 uint32_t VddciTotalPower;
707 uint32_t VddciLeakagePower;
708 uint32_t VddciConstantPower;
709 uint32_t VddciDynamicPower;
710 uint32_t Vddr1TotalPower;
711 uint32_t Vddr1LeakagePower;
712 uint32_t Vddr1ConstantPower;
713 uint32_t Vddr1DynamicPower;
714 uint32_t spare[4];
715 uint32_t temperature;
716};
717
718typedef struct SMU7_Discrete_Cac_Verification_Table SMU7_Discrete_Cac_Verification_Table;
719
720struct SMU7_Discrete_Pm_Status_Table {
721 int32_t T_meas_max[SMU75_THERMAL_INPUT_LOOP_COUNT];
722 int32_t T_meas_acc[SMU75_THERMAL_INPUT_LOOP_COUNT];
723
724 uint32_t I_calc_max;
725 uint32_t I_calc_acc;
726 uint32_t P_meas_acc;
727 uint32_t V_meas_load_acc;
728 uint32_t I_meas_acc;
729 uint32_t P_meas_acc_vddci;
730 uint32_t V_meas_load_acc_vddci;
731 uint32_t I_meas_acc_vddci;
732
733 uint16_t Sclk_dpm_residency[8];
734 uint16_t Uvd_dpm_residency[8];
735 uint16_t Vce_dpm_residency[8];
736 uint16_t Mclk_dpm_residency[4];
737
738 uint32_t P_roc_acc;
739 uint32_t PkgPwr_max;
740 uint32_t PkgPwr_acc;
741 uint32_t MclkSwitchingTime_max;
742 uint32_t MclkSwitchingTime_acc;
743 uint32_t FanPwm_acc;
744 uint32_t FanRpm_acc;
745 uint32_t Gfx_busy_acc;
746 uint32_t Mc_busy_acc;
747 uint32_t Fps_acc;
748
749 uint32_t AccCnt;
750};
751
752typedef struct SMU7_Discrete_Pm_Status_Table SMU7_Discrete_Pm_Status_Table;
753
754struct SMU7_Discrete_AutoWattMan_Status_Table {
755 int32_t T_meas_acc[SMU75_THERMAL_INPUT_LOOP_COUNT];
756 uint16_t Sclk_dpm_residency[8];
757 uint16_t Mclk_dpm_residency[4];
758 uint32_t TgpPwr_acc;
759 uint32_t Gfx_busy_acc;
760 uint32_t Mc_busy_acc;
761 uint32_t AccCnt;
762};
763
764typedef struct SMU7_Discrete_AutoWattMan_Status_Table SMU7_Discrete_AutoWattMan_Status_Table;
765
766#define SMU7_MAX_GFX_CU_COUNT 24
767#define SMU7_MIN_GFX_CU_COUNT 8
768#define SMU7_GFX_CU_PG_ENABLE_DC_MAX_CU_SHIFT 0
769#define SMU7_GFX_CU_PG_ENABLE_DC_MAX_CU_MASK (0xFFFF << SMU7_GFX_CU_PG_ENABLE_DC_MAX_CU_SHIFT)
770#define SMU7_GFX_CU_PG_ENABLE_AC_MAX_CU_SHIFT 16
771#define SMU7_GFX_CU_PG_ENABLE_AC_MAX_CU_MASK (0xFFFF << SMU7_GFX_CU_PG_ENABLE_AC_MAX_CU_SHIFT)
772
773struct SMU7_GfxCuPgScoreboard {
774 uint8_t Enabled;
775 uint8_t WaterfallUp;
776 uint8_t WaterfallDown;
777 uint8_t WaterfallLimit;
778 uint8_t CurrMaxCu;
779 uint8_t TargMaxCu;
780 uint8_t ClampMode;
781 uint8_t Active;
782 uint8_t MaxSupportedCu;
783 uint8_t MinSupportedCu;
784 uint8_t PendingGfxCuHostInterrupt;
785 uint8_t LastFilteredMaxCuInteger;
786 uint16_t FilteredMaxCu;
787 uint16_t FilteredMaxCuAlpha;
788 uint16_t FilterResetCount;
789 uint16_t FilterResetCountLimit;
790 uint8_t ForceCu;
791 uint8_t ForceCuCount;
792 uint8_t AcModeMaxCu;
793 uint8_t DcModeMaxCu;
794};
795
796typedef struct SMU7_GfxCuPgScoreboard SMU7_GfxCuPgScoreboard;
797
798#define SMU7_SCLK_CAC 0x561
799#define SMU7_MCLK_CAC 0xF9
800#define SMU7_VCLK_CAC 0x2DE
801#define SMU7_DCLK_CAC 0x2DE
802#define SMU7_ECLK_CAC 0x25E
803#define SMU7_ACLK_CAC 0x25E
804#define SMU7_SAMCLK_CAC 0x25E
805#define SMU7_DISPCLK_CAC 0x100
806#define SMU7_CAC_CONSTANT 0x2EE3430
807#define SMU7_CAC_CONSTANT_SHIFT 18
808
809#define SMU7_VDDCI_MCLK_CONST 1765
810#define SMU7_VDDCI_MCLK_CONST_SHIFT 16
811#define SMU7_VDDCI_VDDCI_CONST 50958
812#define SMU7_VDDCI_VDDCI_CONST_SHIFT 14
813#define SMU7_VDDCI_CONST 11781
814#define SMU7_VDDCI_STROBE_PWR 1331
815
816#define SMU7_VDDR1_CONST 693
817#define SMU7_VDDR1_CAC_WEIGHT 20
818#define SMU7_VDDR1_CAC_WEIGHT_SHIFT 19
819#define SMU7_VDDR1_STROBE_PWR 512
820
821#define SMU7_AREA_COEFF_UVD 0xA78
822#define SMU7_AREA_COEFF_VCE 0x190A
823#define SMU7_AREA_COEFF_ACP 0x22D1
824#define SMU7_AREA_COEFF_SAMU 0x534
825
826#define SMU7_THERM_OUT_MODE_DISABLE 0x0
827#define SMU7_THERM_OUT_MODE_THERM_ONLY 0x1
828#define SMU7_THERM_OUT_MODE_THERM_VRHOT 0x2
829
830#define SQ_Enable_MASK 0x1
831#define SQ_IR_MASK 0x2
832#define SQ_PCC_MASK 0x4
833#define SQ_EDC_MASK 0x8
834
835#define TCP_Enable_MASK 0x100
836#define TCP_IR_MASK 0x200
837#define TCP_PCC_MASK 0x400
838#define TCP_EDC_MASK 0x800
839
840#define TD_Enable_MASK 0x10000
841#define TD_IR_MASK 0x20000
842#define TD_PCC_MASK 0x40000
843#define TD_EDC_MASK 0x80000
844
845#define DB_Enable_MASK 0x1000000
846#define DB_IR_MASK 0x2000000
847#define DB_PCC_MASK 0x4000000
848#define DB_EDC_MASK 0x8000000
849
850#define SQ_Enable_SHIFT 0
851#define SQ_IR_SHIFT 1
852#define SQ_PCC_SHIFT 2
853#define SQ_EDC_SHIFT 3
854
855#define TCP_Enable_SHIFT 8
856#define TCP_IR_SHIFT 9
857#define TCP_PCC_SHIFT 10
858#define TCP_EDC_SHIFT 11
859
860#define TD_Enable_SHIFT 16
861#define TD_IR_SHIFT 17
862#define TD_PCC_SHIFT 18
863#define TD_EDC_SHIFT 19
864
865#define DB_Enable_SHIFT 24
866#define DB_IR_SHIFT 25
867#define DB_PCC_SHIFT 26
868#define DB_EDC_SHIFT 27
869
870#define PMFUSES_AVFSSIZE 104
871
872#define BTCGB0_Vdroop_Enable_MASK 0x1
873#define BTCGB1_Vdroop_Enable_MASK 0x2
874#define AVFSGB0_Vdroop_Enable_MASK 0x4
875#define AVFSGB1_Vdroop_Enable_MASK 0x8
876
877#define BTCGB0_Vdroop_Enable_SHIFT 0
878#define BTCGB1_Vdroop_Enable_SHIFT 1
879#define AVFSGB0_Vdroop_Enable_SHIFT 2
880#define AVFSGB1_Vdroop_Enable_SHIFT 3
881
882#pragma pack(pop)
883
884
885#endif
886
diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
index c3ed737ab951..715b5a168831 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
@@ -131,6 +131,7 @@ typedef uint16_t PPSMC_Result;
131#define PPSMC_MSG_RunAcgInOpenLoop 0x5E 131#define PPSMC_MSG_RunAcgInOpenLoop 0x5E
132#define PPSMC_MSG_InitializeAcg 0x5F 132#define PPSMC_MSG_InitializeAcg 0x5F
133#define PPSMC_MSG_GetCurrPkgPwr 0x61 133#define PPSMC_MSG_GetCurrPkgPwr 0x61
134#define PPSMC_MSG_GetAverageGfxclkActualFrequency 0x63
134#define PPSMC_MSG_SetPccThrottleLevel 0x67 135#define PPSMC_MSG_SetPccThrottleLevel 0x67
135#define PPSMC_MSG_UpdatePkgPwrPidAlpha 0x68 136#define PPSMC_MSG_UpdatePkgPwrPidAlpha 0x68
136#define PPSMC_Message_Count 0x69 137#define PPSMC_Message_Count 0x69
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile
index 958755075421..0a200406a1ec 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile
@@ -26,7 +26,7 @@
26SMU_MGR = smumgr.o smu8_smumgr.o tonga_smumgr.o fiji_smumgr.o \ 26SMU_MGR = smumgr.o smu8_smumgr.o tonga_smumgr.o fiji_smumgr.o \
27 polaris10_smumgr.o iceland_smumgr.o \ 27 polaris10_smumgr.o iceland_smumgr.o \
28 smu7_smumgr.o vega10_smumgr.o smu10_smumgr.o ci_smumgr.o \ 28 smu7_smumgr.o vega10_smumgr.o smu10_smumgr.o ci_smumgr.o \
29 vega12_smumgr.o 29 vega12_smumgr.o vegam_smumgr.o
30 30
31AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR)) 31AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR))
32 32
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
index 08d000140eca..2d4ec8ac3a08 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
@@ -61,9 +61,6 @@
61 61
62#define SMC_RAM_END 0x40000 62#define SMC_RAM_END 0x40000
63 63
64#define VOLTAGE_SCALE 4
65#define VOLTAGE_VID_OFFSET_SCALE1 625
66#define VOLTAGE_VID_OFFSET_SCALE2 100
67#define CISLAND_MINIMUM_ENGINE_CLOCK 800 64#define CISLAND_MINIMUM_ENGINE_CLOCK 800
68#define CISLAND_MAX_DEEPSLEEP_DIVIDER_ID 5 65#define CISLAND_MAX_DEEPSLEEP_DIVIDER_ID 5
69 66
@@ -211,9 +208,7 @@ static int ci_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
211{ 208{
212 int ret; 209 int ret;
213 210
214 if (!ci_is_smc_ram_running(hwmgr)) 211 cgs_write_register(hwmgr->device, mmSMC_RESP_0, 0);
215 return -EINVAL;
216
217 cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg); 212 cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg);
218 213
219 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); 214 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0);
@@ -1182,7 +1177,6 @@ static int ci_populate_single_memory_level(
1182 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 1177 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1183 int result = 0; 1178 int result = 0;
1184 bool dll_state_on; 1179 bool dll_state_on;
1185 struct cgs_display_info info = {0};
1186 uint32_t mclk_edc_wr_enable_threshold = 40000; 1180 uint32_t mclk_edc_wr_enable_threshold = 40000;
1187 uint32_t mclk_edc_enable_threshold = 40000; 1181 uint32_t mclk_edc_enable_threshold = 40000;
1188 uint32_t mclk_strobe_mode_threshold = 40000; 1182 uint32_t mclk_strobe_mode_threshold = 40000;
@@ -1236,8 +1230,7 @@ static int ci_populate_single_memory_level(
1236 /* default set to low watermark. Highest level will be set to high later.*/ 1230 /* default set to low watermark. Highest level will be set to high later.*/
1237 memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; 1231 memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
1238 1232
1239 cgs_get_active_displays_info(hwmgr->device, &info); 1233 data->display_timing.num_existing_displays = hwmgr->display_config->num_display;
1240 data->display_timing.num_existing_displays = info.display_count;
1241 1234
1242 /* stutter mode not support on ci */ 1235 /* stutter mode not support on ci */
1243 1236
@@ -2784,7 +2777,6 @@ static int ci_smu_fini(struct pp_hwmgr *hwmgr)
2784{ 2777{
2785 kfree(hwmgr->smu_backend); 2778 kfree(hwmgr->smu_backend);
2786 hwmgr->smu_backend = NULL; 2779 hwmgr->smu_backend = NULL;
2787 cgs_rel_firmware(hwmgr->device, CGS_UCODE_ID_SMU);
2788 return 0; 2780 return 0;
2789} 2781}
2790 2782
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
index faef78321446..53df9405f43a 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
@@ -53,10 +53,7 @@
53 53
54#define FIJI_SMC_SIZE 0x20000 54#define FIJI_SMC_SIZE 0x20000
55 55
56#define VOLTAGE_SCALE 4
57#define POWERTUNE_DEFAULT_SET_MAX 1 56#define POWERTUNE_DEFAULT_SET_MAX 1
58#define VOLTAGE_VID_OFFSET_SCALE1 625
59#define VOLTAGE_VID_OFFSET_SCALE2 100
60#define VDDC_VDDCI_DELTA 300 57#define VDDC_VDDCI_DELTA 300
61#define MC_CG_ARB_FREQ_F1 0x0b 58#define MC_CG_ARB_FREQ_F1 0x0b
62 59
@@ -288,8 +285,7 @@ static int fiji_start_smu(struct pp_hwmgr *hwmgr)
288 struct fiji_smumgr *priv = (struct fiji_smumgr *)(hwmgr->smu_backend); 285 struct fiji_smumgr *priv = (struct fiji_smumgr *)(hwmgr->smu_backend);
289 286
290 /* Only start SMC if SMC RAM is not running */ 287 /* Only start SMC if SMC RAM is not running */
291 if (!(smu7_is_smc_ram_running(hwmgr) 288 if (!smu7_is_smc_ram_running(hwmgr) && hwmgr->not_vf) {
292 || cgs_is_virtualization_enabled(hwmgr->device))) {
293 /* Check if SMU is running in protected mode */ 289 /* Check if SMU is running in protected mode */
294 if (0 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, 290 if (0 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
295 CGS_IND_REG__SMC, 291 CGS_IND_REG__SMC,
@@ -307,13 +303,13 @@ static int fiji_start_smu(struct pp_hwmgr *hwmgr)
307 } 303 }
308 304
309 /* To initialize all clock gating before RLC loaded and running.*/ 305 /* To initialize all clock gating before RLC loaded and running.*/
310 cgs_set_clockgating_state(hwmgr->device, 306 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
311 AMD_IP_BLOCK_TYPE_GFX, AMD_CG_STATE_GATE); 307 AMD_IP_BLOCK_TYPE_GFX, AMD_CG_STATE_GATE);
312 cgs_set_clockgating_state(hwmgr->device, 308 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
313 AMD_IP_BLOCK_TYPE_GMC, AMD_CG_STATE_GATE); 309 AMD_IP_BLOCK_TYPE_GMC, AMD_CG_STATE_GATE);
314 cgs_set_clockgating_state(hwmgr->device, 310 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
315 AMD_IP_BLOCK_TYPE_SDMA, AMD_CG_STATE_GATE); 311 AMD_IP_BLOCK_TYPE_SDMA, AMD_CG_STATE_GATE);
316 cgs_set_clockgating_state(hwmgr->device, 312 amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
317 AMD_IP_BLOCK_TYPE_COMMON, AMD_CG_STATE_GATE); 313 AMD_IP_BLOCK_TYPE_COMMON, AMD_CG_STATE_GATE);
318 314
319 /* Setup SoftRegsStart here for register lookup in case 315 /* Setup SoftRegsStart here for register lookup in case
@@ -335,10 +331,10 @@ static bool fiji_is_hw_avfs_present(struct pp_hwmgr *hwmgr)
335 uint32_t efuse = 0; 331 uint32_t efuse = 0;
336 uint32_t mask = (1 << ((AVFS_EN_MSB - AVFS_EN_LSB) + 1)) - 1; 332 uint32_t mask = (1 << ((AVFS_EN_MSB - AVFS_EN_LSB) + 1)) - 1;
337 333
338 if (cgs_is_virtualization_enabled(hwmgr->device)) 334 if (!hwmgr->not_vf)
339 return 0; 335 return false;
340 336
341 if (!atomctrl_read_efuse(hwmgr->device, AVFS_EN_LSB, AVFS_EN_MSB, 337 if (!atomctrl_read_efuse(hwmgr, AVFS_EN_LSB, AVFS_EN_MSB,
342 mask, &efuse)) { 338 mask, &efuse)) {
343 if (efuse) 339 if (efuse)
344 return true; 340 return true;
@@ -989,11 +985,11 @@ static int fiji_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
989 985
990 threshold = clock * data->fast_watermark_threshold / 100; 986 threshold = clock * data->fast_watermark_threshold / 100;
991 987
992 data->display_timing.min_clock_in_sr = hwmgr->display_config.min_core_set_clock_in_sr; 988 data->display_timing.min_clock_in_sr = hwmgr->display_config->min_core_set_clock_in_sr;
993 989
994 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) 990 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep))
995 level->DeepSleepDivId = smu7_get_sleep_divider_id_from_clock(clock, 991 level->DeepSleepDivId = smu7_get_sleep_divider_id_from_clock(clock,
996 hwmgr->display_config.min_core_set_clock_in_sr); 992 hwmgr->display_config->min_core_set_clock_in_sr);
997 993
998 994
999 /* Default to slow, highest DPM level will be 995 /* Default to slow, highest DPM level will be
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
index d4bb934e7334..415f691c3fa9 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
@@ -60,10 +60,7 @@
60 60
61#define ICELAND_SMC_SIZE 0x20000 61#define ICELAND_SMC_SIZE 0x20000
62 62
63#define VOLTAGE_SCALE 4
64#define POWERTUNE_DEFAULT_SET_MAX 1 63#define POWERTUNE_DEFAULT_SET_MAX 1
65#define VOLTAGE_VID_OFFSET_SCALE1 625
66#define VOLTAGE_VID_OFFSET_SCALE2 100
67#define MC_CG_ARB_FREQ_F1 0x0b 64#define MC_CG_ARB_FREQ_F1 0x0b
68#define VDDC_VDDCI_DELTA 200 65#define VDDC_VDDCI_DELTA 200
69 66
@@ -932,7 +929,7 @@ static int iceland_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
932 graphic_level->PowerThrottle = 0; 929 graphic_level->PowerThrottle = 0;
933 930
934 data->display_timing.min_clock_in_sr = 931 data->display_timing.min_clock_in_sr =
935 hwmgr->display_config.min_core_set_clock_in_sr; 932 hwmgr->display_config->min_core_set_clock_in_sr;
936 933
937 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 934 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
938 PHM_PlatformCaps_SclkDeepSleep)) 935 PHM_PlatformCaps_SclkDeepSleep))
@@ -1236,7 +1233,6 @@ static int iceland_populate_single_memory_level(
1236 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 1233 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1237 int result = 0; 1234 int result = 0;
1238 bool dll_state_on; 1235 bool dll_state_on;
1239 struct cgs_display_info info = {0};
1240 uint32_t mclk_edc_wr_enable_threshold = 40000; 1236 uint32_t mclk_edc_wr_enable_threshold = 40000;
1241 uint32_t mclk_edc_enable_threshold = 40000; 1237 uint32_t mclk_edc_enable_threshold = 40000;
1242 uint32_t mclk_strobe_mode_threshold = 40000; 1238 uint32_t mclk_strobe_mode_threshold = 40000;
@@ -1283,8 +1279,7 @@ static int iceland_populate_single_memory_level(
1283 /* default set to low watermark. Highest level will be set to high later.*/ 1279 /* default set to low watermark. Highest level will be set to high later.*/
1284 memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; 1280 memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
1285 1281
1286 cgs_get_active_displays_info(hwmgr->device, &info); 1282 data->display_timing.num_existing_displays = hwmgr->display_config->num_display;
1287 data->display_timing.num_existing_displays = info.display_count;
1288 1283
1289 /* stutter mode not support on iceland */ 1284 /* stutter mode not support on iceland */
1290 1285
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
index 997a777dd35b..a8c6524f07e4 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -52,8 +52,6 @@
52#include "dce/dce_10_0_sh_mask.h" 52#include "dce/dce_10_0_sh_mask.h"
53 53
54#define POLARIS10_SMC_SIZE 0x20000 54#define POLARIS10_SMC_SIZE 0x20000
55#define VOLTAGE_VID_OFFSET_SCALE1 625
56#define VOLTAGE_VID_OFFSET_SCALE2 100
57#define POWERTUNE_DEFAULT_SET_MAX 1 55#define POWERTUNE_DEFAULT_SET_MAX 1
58#define VDDC_VDDCI_DELTA 200 56#define VDDC_VDDCI_DELTA 200
59#define MC_CG_ARB_FREQ_F1 0x0b 57#define MC_CG_ARB_FREQ_F1 0x0b
@@ -295,25 +293,16 @@ static int polaris10_start_smu(struct pp_hwmgr *hwmgr)
295 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); 293 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
296 294
297 /* Only start SMC if SMC RAM is not running */ 295 /* Only start SMC if SMC RAM is not running */
298 if (!(smu7_is_smc_ram_running(hwmgr) 296 if (!smu7_is_smc_ram_running(hwmgr) && hwmgr->not_vf) {
299 || cgs_is_virtualization_enabled(hwmgr->device))) {
300 smu_data->protected_mode = (uint8_t) (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_MODE)); 297 smu_data->protected_mode = (uint8_t) (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_MODE));
301 smu_data->smu7_data.security_hard_key = (uint8_t) (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_SEL)); 298 smu_data->smu7_data.security_hard_key = (uint8_t) (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_SEL));
302 299
303 /* Check if SMU is running in protected mode */ 300 /* Check if SMU is running in protected mode */
304 if (smu_data->protected_mode == 0) { 301 if (smu_data->protected_mode == 0)
305 result = polaris10_start_smu_in_non_protection_mode(hwmgr); 302 result = polaris10_start_smu_in_non_protection_mode(hwmgr);
306 } else { 303 else
307 result = polaris10_start_smu_in_protection_mode(hwmgr); 304 result = polaris10_start_smu_in_protection_mode(hwmgr);
308 305
309 /* If failed, try with different security Key. */
310 if (result != 0) {
311 smu_data->smu7_data.security_hard_key ^= 1;
312 cgs_rel_firmware(hwmgr->device, CGS_UCODE_ID_SMU);
313 result = polaris10_start_smu_in_protection_mode(hwmgr);
314 }
315 }
316
317 if (result != 0) 306 if (result != 0)
318 PP_ASSERT_WITH_CODE(0, "Failed to load SMU ucode.", return result); 307 PP_ASSERT_WITH_CODE(0, "Failed to load SMU ucode.", return result);
319 308
@@ -951,11 +940,11 @@ static int polaris10_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
951 level->DownHyst = data->current_profile_setting.sclk_down_hyst; 940 level->DownHyst = data->current_profile_setting.sclk_down_hyst;
952 level->VoltageDownHyst = 0; 941 level->VoltageDownHyst = 0;
953 level->PowerThrottle = 0; 942 level->PowerThrottle = 0;
954 data->display_timing.min_clock_in_sr = hwmgr->display_config.min_core_set_clock_in_sr; 943 data->display_timing.min_clock_in_sr = hwmgr->display_config->min_core_set_clock_in_sr;
955 944
956 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) 945 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep))
957 level->DeepSleepDivId = smu7_get_sleep_divider_id_from_clock(clock, 946 level->DeepSleepDivId = smu7_get_sleep_divider_id_from_clock(clock,
958 hwmgr->display_config.min_core_set_clock_in_sr); 947 hwmgr->display_config->min_core_set_clock_in_sr);
959 948
960 /* Default to slow, highest DPM level will be 949 /* Default to slow, highest DPM level will be
961 * set to PPSMC_DISPLAY_WATERMARK_LOW later. 950 * set to PPSMC_DISPLAY_WATERMARK_LOW later.
@@ -1085,11 +1074,9 @@ static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
1085 struct phm_ppt_v1_information *table_info = 1074 struct phm_ppt_v1_information *table_info =
1086 (struct phm_ppt_v1_information *)(hwmgr->pptable); 1075 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1087 int result = 0; 1076 int result = 0;
1088 struct cgs_display_info info = {0, 0, NULL};
1089 uint32_t mclk_stutter_mode_threshold = 40000; 1077 uint32_t mclk_stutter_mode_threshold = 40000;
1090 phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_table = NULL; 1078 phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_table = NULL;
1091 1079
1092 cgs_get_active_displays_info(hwmgr->device, &info);
1093 1080
1094 if (hwmgr->od_enabled) 1081 if (hwmgr->od_enabled)
1095 vdd_dep_table = (phm_ppt_v1_clock_voltage_dependency_table *)&data->odn_dpm_table.vdd_dependency_on_mclk; 1082 vdd_dep_table = (phm_ppt_v1_clock_voltage_dependency_table *)&data->odn_dpm_table.vdd_dependency_on_mclk;
@@ -1115,7 +1102,7 @@ static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
1115 mem_level->StutterEnable = false; 1102 mem_level->StutterEnable = false;
1116 mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; 1103 mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
1117 1104
1118 data->display_timing.num_existing_displays = info.display_count; 1105 data->display_timing.num_existing_displays = hwmgr->display_config->num_display;
1119 1106
1120 if (mclk_stutter_mode_threshold && 1107 if (mclk_stutter_mode_threshold &&
1121 (clock <= mclk_stutter_mode_threshold) && 1108 (clock <= mclk_stutter_mode_threshold) &&
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c
index bc53f2beda30..0a563f6fe9ea 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c
@@ -23,7 +23,7 @@
23 23
24#include "smumgr.h" 24#include "smumgr.h"
25#include "smu10_inc.h" 25#include "smu10_inc.h"
26#include "pp_soc15.h" 26#include "soc15_common.h"
27#include "smu10_smumgr.h" 27#include "smu10_smumgr.h"
28#include "ppatomctrl.h" 28#include "ppatomctrl.h"
29#include "rv_ppsmc.h" 29#include "rv_ppsmc.h"
@@ -33,8 +33,6 @@
33#include "pp_debug.h" 33#include "pp_debug.h"
34 34
35 35
36#define VOLTAGE_SCALE 4
37
38#define BUFFER_SIZE 80000 36#define BUFFER_SIZE 80000
39#define MAX_STRING_SIZE 15 37#define MAX_STRING_SIZE 15
40#define BUFFER_SIZETWO 131072 38#define BUFFER_SIZETWO 131072
@@ -49,48 +47,41 @@
49 47
50static uint32_t smu10_wait_for_response(struct pp_hwmgr *hwmgr) 48static uint32_t smu10_wait_for_response(struct pp_hwmgr *hwmgr)
51{ 49{
50 struct amdgpu_device *adev = hwmgr->adev;
52 uint32_t reg; 51 uint32_t reg;
53 52
54 reg = soc15_get_register_offset(MP1_HWID, 0, 53 reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
55 mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
56 54
57 phm_wait_for_register_unequal(hwmgr, reg, 55 phm_wait_for_register_unequal(hwmgr, reg,
58 0, MP1_C2PMSG_90__CONTENT_MASK); 56 0, MP1_C2PMSG_90__CONTENT_MASK);
59 57
60 return cgs_read_register(hwmgr->device, reg); 58 return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
61} 59}
62 60
63static int smu10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, 61static int smu10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
64 uint16_t msg) 62 uint16_t msg)
65{ 63{
66 uint32_t reg; 64 struct amdgpu_device *adev = hwmgr->adev;
67 65
68 reg = soc15_get_register_offset(MP1_HWID, 0, 66 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg);
69 mmMP1_SMN_C2PMSG_66_BASE_IDX, mmMP1_SMN_C2PMSG_66);
70 cgs_write_register(hwmgr->device, reg, msg);
71 67
72 return 0; 68 return 0;
73} 69}
74 70
75static int smu10_read_arg_from_smc(struct pp_hwmgr *hwmgr) 71static int smu10_read_arg_from_smc(struct pp_hwmgr *hwmgr)
76{ 72{
77 uint32_t reg; 73 struct amdgpu_device *adev = hwmgr->adev;
78
79 reg = soc15_get_register_offset(MP1_HWID, 0,
80 mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
81 74
82 return cgs_read_register(hwmgr->device, reg); 75 return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
83} 76}
84 77
85static int smu10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) 78static int smu10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
86{ 79{
87 uint32_t reg; 80 struct amdgpu_device *adev = hwmgr->adev;
88 81
89 smu10_wait_for_response(hwmgr); 82 smu10_wait_for_response(hwmgr);
90 83
91 reg = soc15_get_register_offset(MP1_HWID, 0, 84 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
92 mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
93 cgs_write_register(hwmgr->device, reg, 0);
94 85
95 smu10_send_msg_to_smc_without_waiting(hwmgr, msg); 86 smu10_send_msg_to_smc_without_waiting(hwmgr, msg);
96 87
@@ -104,17 +95,13 @@ static int smu10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
104static int smu10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, 95static int smu10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
105 uint16_t msg, uint32_t parameter) 96 uint16_t msg, uint32_t parameter)
106{ 97{
107 uint32_t reg; 98 struct amdgpu_device *adev = hwmgr->adev;
108 99
109 smu10_wait_for_response(hwmgr); 100 smu10_wait_for_response(hwmgr);
110 101
111 reg = soc15_get_register_offset(MP1_HWID, 0, 102 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
112 mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
113 cgs_write_register(hwmgr->device, reg, 0);
114 103
115 reg = soc15_get_register_offset(MP1_HWID, 0, 104 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter);
116 mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
117 cgs_write_register(hwmgr->device, reg, parameter);
118 105
119 smu10_send_msg_to_smc_without_waiting(hwmgr, msg); 106 smu10_send_msg_to_smc_without_waiting(hwmgr, msg);
120 107
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
index 0399c10d2be0..d644a9bb9078 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
@@ -167,24 +167,25 @@ int smu7_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
167{ 167{
168 int ret; 168 int ret;
169 169
170 if (!smu7_is_smc_ram_running(hwmgr))
171 return -EINVAL;
172
173
174 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); 170 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0);
175 171
176 ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP); 172 ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP);
177 173
178 if (ret != 1) 174 if (ret == 0xFE)
179 pr_info("\n failed to send pre message %x ret is %d \n", msg, ret); 175 pr_debug("last message was not supported\n");
176 else if (ret != 1)
177 pr_info("\n last message was failed ret is %d\n", ret);
180 178
179 cgs_write_register(hwmgr->device, mmSMC_RESP_0, 0);
181 cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg); 180 cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg);
182 181
183 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); 182 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0);
184 183
185 ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP); 184 ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP);
186 185
187 if (ret != 1) 186 if (ret == 0xFE)
187 pr_debug("message %x was not supported\n", msg);
188 else if (ret != 1)
188 pr_info("\n failed to send message %x ret is %d \n", msg, ret); 189 pr_info("\n failed to send message %x ret is %d \n", msg, ret);
189 190
190 return 0; 191 return 0;
@@ -199,10 +200,6 @@ int smu7_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, uint16_t msg)
199 200
200int smu7_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter) 201int smu7_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter)
201{ 202{
202 if (!smu7_is_smc_ram_running(hwmgr)) {
203 return -EINVAL;
204 }
205
206 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); 203 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0);
207 204
208 cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, parameter); 205 cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, parameter);
@@ -231,16 +228,6 @@ int smu7_send_msg_to_smc_offset(struct pp_hwmgr *hwmgr)
231 return 0; 228 return 0;
232} 229}
233 230
234int smu7_wait_for_smc_inactive(struct pp_hwmgr *hwmgr)
235{
236 if (!smu7_is_smc_ram_running(hwmgr))
237 return -EINVAL;
238
239 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, SMC_SYSCON_CLOCK_CNTL_0, cken, 0);
240 return 0;
241}
242
243
244enum cgs_ucode_id smu7_convert_fw_type_to_cgs(uint32_t fw_type) 231enum cgs_ucode_id smu7_convert_fw_type_to_cgs(uint32_t fw_type)
245{ 232{
246 enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM; 233 enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM;
@@ -296,11 +283,9 @@ int smu7_read_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_t
296 283
297 result = smu7_set_smc_sram_address(hwmgr, smc_addr, limit); 284 result = smu7_set_smc_sram_address(hwmgr, smc_addr, limit);
298 285
299 if (result) 286 *value = result ? 0 : cgs_read_register(hwmgr->device, mmSMC_IND_DATA_11);
300 return result;
301 287
302 *value = cgs_read_register(hwmgr->device, mmSMC_IND_DATA_11); 288 return result;
303 return 0;
304} 289}
305 290
306int smu7_write_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_t value, uint32_t limit) 291int smu7_write_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_t value, uint32_t limit)
@@ -375,7 +360,7 @@ static int smu7_populate_single_firmware_entry(struct pp_hwmgr *hwmgr,
375 entry->meta_data_addr_low = 0; 360 entry->meta_data_addr_low = 0;
376 361
377 /* digest need be excluded out */ 362 /* digest need be excluded out */
378 if (cgs_is_virtualization_enabled(hwmgr->device)) 363 if (!hwmgr->not_vf)
379 info.image_size -= 20; 364 info.image_size -= 20;
380 entry->data_size_byte = info.image_size; 365 entry->data_size_byte = info.image_size;
381 entry->num_register_entries = 0; 366 entry->num_register_entries = 0;
@@ -409,7 +394,7 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr)
409 0x0); 394 0x0);
410 395
411 if (hwmgr->chip_id > CHIP_TOPAZ) { /* add support for Topaz */ 396 if (hwmgr->chip_id > CHIP_TOPAZ) { /* add support for Topaz */
412 if (!cgs_is_virtualization_enabled(hwmgr->device)) { 397 if (hwmgr->not_vf) {
413 smu7_send_msg_to_smc_with_parameter(hwmgr, 398 smu7_send_msg_to_smc_with_parameter(hwmgr,
414 PPSMC_MSG_SMU_DRAM_ADDR_HI, 399 PPSMC_MSG_SMU_DRAM_ADDR_HI,
415 upper_32_bits(smu_data->smu_buffer.mc_addr)); 400 upper_32_bits(smu_data->smu_buffer.mc_addr));
@@ -467,7 +452,7 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr)
467 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 452 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,
468 UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]), 453 UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]),
469 "Failed to Get Firmware Entry.", return -EINVAL); 454 "Failed to Get Firmware Entry.", return -EINVAL);
470 if (cgs_is_virtualization_enabled(hwmgr->device)) 455 if (!hwmgr->not_vf)
471 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 456 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,
472 UCODE_ID_MEC_STORAGE, &toc->entry[toc->num_entries++]), 457 UCODE_ID_MEC_STORAGE, &toc->entry[toc->num_entries++]),
473 "Failed to Get Firmware Entry.", return -EINVAL); 458 "Failed to Get Firmware Entry.", return -EINVAL);
@@ -608,7 +593,7 @@ int smu7_init(struct pp_hwmgr *hwmgr)
608 smu_data->header = smu_data->header_buffer.kaddr; 593 smu_data->header = smu_data->header_buffer.kaddr;
609 smu_data->header_buffer.mc_addr = mc_addr; 594 smu_data->header_buffer.mc_addr = mc_addr;
610 595
611 if (cgs_is_virtualization_enabled(hwmgr->device)) 596 if (!hwmgr->not_vf)
612 return 0; 597 return 0;
613 598
614 smu_data->smu_buffer.data_size = 200*4096; 599 smu_data->smu_buffer.data_size = 200*4096;
@@ -643,13 +628,12 @@ int smu7_smu_fini(struct pp_hwmgr *hwmgr)
643 &smu_data->header_buffer.mc_addr, 628 &smu_data->header_buffer.mc_addr,
644 &smu_data->header_buffer.kaddr); 629 &smu_data->header_buffer.kaddr);
645 630
646 if (!cgs_is_virtualization_enabled(hwmgr->device)) 631 if (hwmgr->not_vf)
647 amdgpu_bo_free_kernel(&smu_data->smu_buffer.handle, 632 amdgpu_bo_free_kernel(&smu_data->smu_buffer.handle,
648 &smu_data->smu_buffer.mc_addr, 633 &smu_data->smu_buffer.mc_addr,
649 &smu_data->smu_buffer.kaddr); 634 &smu_data->smu_buffer.kaddr);
650 635
651 kfree(hwmgr->smu_backend); 636 kfree(hwmgr->smu_backend);
652 hwmgr->smu_backend = NULL; 637 hwmgr->smu_backend = NULL;
653 cgs_rel_firmware(hwmgr->device, CGS_UCODE_ID_SMU);
654 return 0; 638 return 0;
655} 639}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
index 126d300259ba..39c9bfda0ab4 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
@@ -67,7 +67,6 @@ int smu7_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, uint16_t msg,
67int smu7_send_msg_to_smc_with_parameter_without_waiting(struct pp_hwmgr *hwmgr, 67int smu7_send_msg_to_smc_with_parameter_without_waiting(struct pp_hwmgr *hwmgr,
68 uint16_t msg, uint32_t parameter); 68 uint16_t msg, uint32_t parameter);
69int smu7_send_msg_to_smc_offset(struct pp_hwmgr *hwmgr); 69int smu7_send_msg_to_smc_offset(struct pp_hwmgr *hwmgr);
70int smu7_wait_for_smc_inactive(struct pp_hwmgr *hwmgr);
71 70
72enum cgs_ucode_id smu7_convert_fw_type_to_cgs(uint32_t fw_type); 71enum cgs_ucode_id smu7_convert_fw_type_to_cgs(uint32_t fw_type);
73int smu7_read_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, 72int smu7_read_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr,
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
index c28b60aae5f8..c9837935f0f5 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
@@ -41,9 +41,11 @@ MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
41MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin"); 41MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
42MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin"); 42MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin");
43MODULE_FIRMWARE("amdgpu/polaris12_smc.bin"); 43MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
44MODULE_FIRMWARE("amdgpu/vegam_smc.bin");
44MODULE_FIRMWARE("amdgpu/vega10_smc.bin"); 45MODULE_FIRMWARE("amdgpu/vega10_smc.bin");
45MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin"); 46MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin");
46MODULE_FIRMWARE("amdgpu/vega12_smc.bin"); 47MODULE_FIRMWARE("amdgpu/vega12_smc.bin");
48MODULE_FIRMWARE("amdgpu/vega20_smc.bin");
47 49
48int smum_thermal_avfs_enable(struct pp_hwmgr *hwmgr) 50int smum_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
49{ 51{
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
index b51d7468c3e7..782b19fc2e70 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
@@ -55,11 +55,7 @@
55#include "dce/dce_10_0_d.h" 55#include "dce/dce_10_0_d.h"
56#include "dce/dce_10_0_sh_mask.h" 56#include "dce/dce_10_0_sh_mask.h"
57 57
58
59#define VOLTAGE_SCALE 4
60#define POWERTUNE_DEFAULT_SET_MAX 1 58#define POWERTUNE_DEFAULT_SET_MAX 1
61#define VOLTAGE_VID_OFFSET_SCALE1 625
62#define VOLTAGE_VID_OFFSET_SCALE2 100
63#define MC_CG_ARB_FREQ_F1 0x0b 59#define MC_CG_ARB_FREQ_F1 0x0b
64#define VDDC_VDDCI_DELTA 200 60#define VDDC_VDDCI_DELTA 200
65 61
@@ -199,8 +195,7 @@ static int tonga_start_smu(struct pp_hwmgr *hwmgr)
199 int result; 195 int result;
200 196
201 /* Only start SMC if SMC RAM is not running */ 197 /* Only start SMC if SMC RAM is not running */
202 if (!(smu7_is_smc_ram_running(hwmgr) || 198 if (!smu7_is_smc_ram_running(hwmgr) && hwmgr->not_vf) {
203 cgs_is_virtualization_enabled(hwmgr->device))) {
204 /*Check if SMU is running in protected mode*/ 199 /*Check if SMU is running in protected mode*/
205 if (0 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, 200 if (0 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
206 SMU_FIRMWARE, SMU_MODE)) { 201 SMU_FIRMWARE, SMU_MODE)) {
@@ -651,7 +646,7 @@ static int tonga_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
651 graphic_level->PowerThrottle = 0; 646 graphic_level->PowerThrottle = 0;
652 647
653 data->display_timing.min_clock_in_sr = 648 data->display_timing.min_clock_in_sr =
654 hwmgr->display_config.min_core_set_clock_in_sr; 649 hwmgr->display_config->min_core_set_clock_in_sr;
655 650
656 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 651 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
657 PHM_PlatformCaps_SclkDeepSleep)) 652 PHM_PlatformCaps_SclkDeepSleep))
@@ -957,18 +952,17 @@ static int tonga_populate_single_memory_level(
957 SMU72_Discrete_MemoryLevel *memory_level 952 SMU72_Discrete_MemoryLevel *memory_level
958 ) 953 )
959{ 954{
960 uint32_t mvdd = 0;
961 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 955 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
962 struct phm_ppt_v1_information *pptable_info = 956 struct phm_ppt_v1_information *pptable_info =
963 (struct phm_ppt_v1_information *)(hwmgr->pptable); 957 (struct phm_ppt_v1_information *)(hwmgr->pptable);
964 int result = 0;
965 bool dll_state_on;
966 struct cgs_display_info info = {0};
967 uint32_t mclk_edc_wr_enable_threshold = 40000; 958 uint32_t mclk_edc_wr_enable_threshold = 40000;
968 uint32_t mclk_stutter_mode_threshold = 30000; 959 uint32_t mclk_stutter_mode_threshold = 30000;
969 uint32_t mclk_edc_enable_threshold = 40000; 960 uint32_t mclk_edc_enable_threshold = 40000;
970 uint32_t mclk_strobe_mode_threshold = 40000; 961 uint32_t mclk_strobe_mode_threshold = 40000;
971 phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_table = NULL; 962 phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_table = NULL;
963 int result = 0;
964 bool dll_state_on;
965 uint32_t mvdd = 0;
972 966
973 if (hwmgr->od_enabled) 967 if (hwmgr->od_enabled)
974 vdd_dep_table = (phm_ppt_v1_clock_voltage_dependency_table *)&data->odn_dpm_table.vdd_dependency_on_mclk; 968 vdd_dep_table = (phm_ppt_v1_clock_voltage_dependency_table *)&data->odn_dpm_table.vdd_dependency_on_mclk;
@@ -1009,8 +1003,7 @@ static int tonga_populate_single_memory_level(
1009 /* default set to low watermark. Highest level will be set to high later.*/ 1003 /* default set to low watermark. Highest level will be set to high later.*/
1010 memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; 1004 memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
1011 1005
1012 cgs_get_active_displays_info(hwmgr->device, &info); 1006 data->display_timing.num_existing_displays = hwmgr->display_config->num_display;
1013 data->display_timing.num_existing_displays = info.display_count;
1014 1007
1015 if ((mclk_stutter_mode_threshold != 0) && 1008 if ((mclk_stutter_mode_threshold != 0) &&
1016 (memory_clock <= mclk_stutter_mode_threshold) && 1009 (memory_clock <= mclk_stutter_mode_threshold) &&
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
index 4aafb043bcb0..e84669c448a3 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
@@ -23,7 +23,7 @@
23 23
24#include "smumgr.h" 24#include "smumgr.h"
25#include "vega10_inc.h" 25#include "vega10_inc.h"
26#include "pp_soc15.h" 26#include "soc15_common.h"
27#include "vega10_smumgr.h" 27#include "vega10_smumgr.h"
28#include "vega10_hwmgr.h" 28#include "vega10_hwmgr.h"
29#include "vega10_ppsmc.h" 29#include "vega10_ppsmc.h"
@@ -35,8 +35,6 @@
35#define AVFS_EN_MSB 1568 35#define AVFS_EN_MSB 1568
36#define AVFS_EN_LSB 1568 36#define AVFS_EN_LSB 1568
37 37
38#define VOLTAGE_SCALE 4
39
40/* Microcode file is stored in this buffer */ 38/* Microcode file is stored in this buffer */
41#define BUFFER_SIZE 80000 39#define BUFFER_SIZE 80000
42#define MAX_STRING_SIZE 15 40#define MAX_STRING_SIZE 15
@@ -54,18 +52,13 @@
54 52
55static bool vega10_is_smc_ram_running(struct pp_hwmgr *hwmgr) 53static bool vega10_is_smc_ram_running(struct pp_hwmgr *hwmgr)
56{ 54{
57 uint32_t mp1_fw_flags, reg; 55 struct amdgpu_device *adev = hwmgr->adev;
58 56 uint32_t mp1_fw_flags;
59 reg = soc15_get_register_offset(NBIF_HWID, 0,
60 mmPCIE_INDEX2_BASE_IDX, mmPCIE_INDEX2);
61 57
62 cgs_write_register(hwmgr->device, reg, 58 WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2,
63 (MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); 59 (MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff)));
64 60
65 reg = soc15_get_register_offset(NBIF_HWID, 0, 61 mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2);
66 mmPCIE_DATA2_BASE_IDX, mmPCIE_DATA2);
67
68 mp1_fw_flags = cgs_read_register(hwmgr->device, reg);
69 62
70 if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) 63 if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK)
71 return true; 64 return true;
@@ -81,11 +74,11 @@ static bool vega10_is_smc_ram_running(struct pp_hwmgr *hwmgr)
81 */ 74 */
82static uint32_t vega10_wait_for_response(struct pp_hwmgr *hwmgr) 75static uint32_t vega10_wait_for_response(struct pp_hwmgr *hwmgr)
83{ 76{
77 struct amdgpu_device *adev = hwmgr->adev;
84 uint32_t reg; 78 uint32_t reg;
85 uint32_t ret; 79 uint32_t ret;
86 80
87 reg = soc15_get_register_offset(MP1_HWID, 0, 81 reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
88 mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
89 82
90 ret = phm_wait_for_register_unequal(hwmgr, reg, 83 ret = phm_wait_for_register_unequal(hwmgr, reg,
91 0, MP1_C2PMSG_90__CONTENT_MASK); 84 0, MP1_C2PMSG_90__CONTENT_MASK);
@@ -93,7 +86,7 @@ static uint32_t vega10_wait_for_response(struct pp_hwmgr *hwmgr)
93 if (ret) 86 if (ret)
94 pr_err("No response from smu\n"); 87 pr_err("No response from smu\n");
95 88
96 return cgs_read_register(hwmgr->device, reg); 89 return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
97} 90}
98 91
99/* 92/*
@@ -105,11 +98,9 @@ static uint32_t vega10_wait_for_response(struct pp_hwmgr *hwmgr)
105static int vega10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, 98static int vega10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
106 uint16_t msg) 99 uint16_t msg)
107{ 100{
108 uint32_t reg; 101 struct amdgpu_device *adev = hwmgr->adev;
109 102
110 reg = soc15_get_register_offset(MP1_HWID, 0, 103 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg);
111 mmMP1_SMN_C2PMSG_66_BASE_IDX, mmMP1_SMN_C2PMSG_66);
112 cgs_write_register(hwmgr->device, reg, msg);
113 104
114 return 0; 105 return 0;
115} 106}
@@ -122,14 +113,12 @@ static int vega10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
122 */ 113 */
123static int vega10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) 114static int vega10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
124{ 115{
125 uint32_t reg; 116 struct amdgpu_device *adev = hwmgr->adev;
126 uint32_t ret; 117 uint32_t ret;
127 118
128 vega10_wait_for_response(hwmgr); 119 vega10_wait_for_response(hwmgr);
129 120
130 reg = soc15_get_register_offset(MP1_HWID, 0, 121 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
131 mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
132 cgs_write_register(hwmgr->device, reg, 0);
133 122
134 vega10_send_msg_to_smc_without_waiting(hwmgr, msg); 123 vega10_send_msg_to_smc_without_waiting(hwmgr, msg);
135 124
@@ -150,18 +139,14 @@ static int vega10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
150static int vega10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, 139static int vega10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
151 uint16_t msg, uint32_t parameter) 140 uint16_t msg, uint32_t parameter)
152{ 141{
153 uint32_t reg; 142 struct amdgpu_device *adev = hwmgr->adev;
154 uint32_t ret; 143 uint32_t ret;
155 144
156 vega10_wait_for_response(hwmgr); 145 vega10_wait_for_response(hwmgr);
157 146
158 reg = soc15_get_register_offset(MP1_HWID, 0, 147 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
159 mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
160 cgs_write_register(hwmgr->device, reg, 0);
161 148
162 reg = soc15_get_register_offset(MP1_HWID, 0, 149 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter);
163 mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
164 cgs_write_register(hwmgr->device, reg, parameter);
165 150
166 vega10_send_msg_to_smc_without_waiting(hwmgr, msg); 151 vega10_send_msg_to_smc_without_waiting(hwmgr, msg);
167 152
@@ -174,12 +159,9 @@ static int vega10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
174 159
175static int vega10_get_argument(struct pp_hwmgr *hwmgr) 160static int vega10_get_argument(struct pp_hwmgr *hwmgr)
176{ 161{
177 uint32_t reg; 162 struct amdgpu_device *adev = hwmgr->adev;
178
179 reg = soc15_get_register_offset(MP1_HWID, 0,
180 mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
181 163
182 return cgs_read_register(hwmgr->device, reg); 164 return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
183} 165}
184 166
185static int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr, 167static int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c
index 651a3f28734b..7d9b40e8b1bf 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c
@@ -23,7 +23,7 @@
23 23
24#include "smumgr.h" 24#include "smumgr.h"
25#include "vega12_inc.h" 25#include "vega12_inc.h"
26#include "pp_soc15.h" 26#include "soc15_common.h"
27#include "vega12_smumgr.h" 27#include "vega12_smumgr.h"
28#include "vega12_ppsmc.h" 28#include "vega12_ppsmc.h"
29#include "vega12/smu9_driver_if.h" 29#include "vega12/smu9_driver_if.h"
@@ -44,18 +44,13 @@
44 44
45static bool vega12_is_smc_ram_running(struct pp_hwmgr *hwmgr) 45static bool vega12_is_smc_ram_running(struct pp_hwmgr *hwmgr)
46{ 46{
47 uint32_t mp1_fw_flags, reg; 47 struct amdgpu_device *adev = hwmgr->adev;
48 uint32_t mp1_fw_flags;
48 49
49 reg = soc15_get_register_offset(NBIF_HWID, 0, 50 WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2,
50 mmPCIE_INDEX2_BASE_IDX, mmPCIE_INDEX2);
51
52 cgs_write_register(hwmgr->device, reg,
53 (MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); 51 (MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff)));
54 52
55 reg = soc15_get_register_offset(NBIF_HWID, 0, 53 mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2);
56 mmPCIE_DATA2_BASE_IDX, mmPCIE_DATA2);
57
58 mp1_fw_flags = cgs_read_register(hwmgr->device, reg);
59 54
60 if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> 55 if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
61 MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) 56 MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
@@ -72,15 +67,15 @@ static bool vega12_is_smc_ram_running(struct pp_hwmgr *hwmgr)
72 */ 67 */
73static uint32_t vega12_wait_for_response(struct pp_hwmgr *hwmgr) 68static uint32_t vega12_wait_for_response(struct pp_hwmgr *hwmgr)
74{ 69{
70 struct amdgpu_device *adev = hwmgr->adev;
75 uint32_t reg; 71 uint32_t reg;
76 72
77 reg = soc15_get_register_offset(MP1_HWID, 0, 73 reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
78 mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
79 74
80 phm_wait_for_register_unequal(hwmgr, reg, 75 phm_wait_for_register_unequal(hwmgr, reg,
81 0, MP1_C2PMSG_90__CONTENT_MASK); 76 0, MP1_C2PMSG_90__CONTENT_MASK);
82 77
83 return cgs_read_register(hwmgr->device, reg); 78 return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
84} 79}
85 80
86/* 81/*
@@ -92,11 +87,9 @@ static uint32_t vega12_wait_for_response(struct pp_hwmgr *hwmgr)
92int vega12_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, 87int vega12_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
93 uint16_t msg) 88 uint16_t msg)
94{ 89{
95 uint32_t reg; 90 struct amdgpu_device *adev = hwmgr->adev;
96 91
97 reg = soc15_get_register_offset(MP1_HWID, 0, 92 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg);
98 mmMP1_SMN_C2PMSG_66_BASE_IDX, mmMP1_SMN_C2PMSG_66);
99 cgs_write_register(hwmgr->device, reg, msg);
100 93
101 return 0; 94 return 0;
102} 95}
@@ -109,13 +102,11 @@ int vega12_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
109 */ 102 */
110int vega12_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) 103int vega12_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
111{ 104{
112 uint32_t reg; 105 struct amdgpu_device *adev = hwmgr->adev;
113 106
114 vega12_wait_for_response(hwmgr); 107 vega12_wait_for_response(hwmgr);
115 108
116 reg = soc15_get_register_offset(MP1_HWID, 0, 109 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
117 mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
118 cgs_write_register(hwmgr->device, reg, 0);
119 110
120 vega12_send_msg_to_smc_without_waiting(hwmgr, msg); 111 vega12_send_msg_to_smc_without_waiting(hwmgr, msg);
121 112
@@ -135,17 +126,13 @@ int vega12_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
135int vega12_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, 126int vega12_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
136 uint16_t msg, uint32_t parameter) 127 uint16_t msg, uint32_t parameter)
137{ 128{
138 uint32_t reg; 129 struct amdgpu_device *adev = hwmgr->adev;
139 130
140 vega12_wait_for_response(hwmgr); 131 vega12_wait_for_response(hwmgr);
141 132
142 reg = soc15_get_register_offset(MP1_HWID, 0, 133 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
143 mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
144 cgs_write_register(hwmgr->device, reg, 0);
145 134
146 reg = soc15_get_register_offset(MP1_HWID, 0, 135 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter);
147 mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
148 cgs_write_register(hwmgr->device, reg, parameter);
149 136
150 vega12_send_msg_to_smc_without_waiting(hwmgr, msg); 137 vega12_send_msg_to_smc_without_waiting(hwmgr, msg);
151 138
@@ -166,11 +153,9 @@ int vega12_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
166int vega12_send_msg_to_smc_with_parameter_without_waiting( 153int vega12_send_msg_to_smc_with_parameter_without_waiting(
167 struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter) 154 struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter)
168{ 155{
169 uint32_t reg; 156 struct amdgpu_device *adev = hwmgr->adev;
170 157
171 reg = soc15_get_register_offset(MP1_HWID, 0, 158 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, parameter);
172 mmMP1_SMN_C2PMSG_66_BASE_IDX, mmMP1_SMN_C2PMSG_66);
173 cgs_write_register(hwmgr->device, reg, parameter);
174 159
175 return vega12_send_msg_to_smc_without_waiting(hwmgr, msg); 160 return vega12_send_msg_to_smc_without_waiting(hwmgr, msg);
176} 161}
@@ -183,12 +168,9 @@ int vega12_send_msg_to_smc_with_parameter_without_waiting(
183 */ 168 */
184int vega12_read_arg_from_smc(struct pp_hwmgr *hwmgr, uint32_t *arg) 169int vega12_read_arg_from_smc(struct pp_hwmgr *hwmgr, uint32_t *arg)
185{ 170{
186 uint32_t reg; 171 struct amdgpu_device *adev = hwmgr->adev;
187
188 reg = soc15_get_register_offset(MP1_HWID, 0,
189 mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
190 172
191 *arg = cgs_read_register(hwmgr->device, reg); 173 *arg = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
192 174
193 return 0; 175 return 0;
194} 176}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c
new file mode 100644
index 000000000000..2de48959ac93
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c
@@ -0,0 +1,2383 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#include "pp_debug.h"
24#include "smumgr.h"
25#include "smu_ucode_xfer_vi.h"
26#include "vegam_smumgr.h"
27#include "smu/smu_7_1_3_d.h"
28#include "smu/smu_7_1_3_sh_mask.h"
29#include "gmc/gmc_8_1_d.h"
30#include "gmc/gmc_8_1_sh_mask.h"
31#include "oss/oss_3_0_d.h"
32#include "gca/gfx_8_0_d.h"
33#include "bif/bif_5_0_d.h"
34#include "bif/bif_5_0_sh_mask.h"
35#include "ppatomctrl.h"
36#include "cgs_common.h"
37#include "smu7_ppsmc.h"
38
39#include "smu7_dyn_defaults.h"
40
41#include "smu7_hwmgr.h"
42#include "hardwaremanager.h"
43#include "ppatomctrl.h"
44#include "atombios.h"
45#include "pppcielanes.h"
46
47#include "dce/dce_11_2_d.h"
48#include "dce/dce_11_2_sh_mask.h"
49
50#define PPVEGAM_TARGETACTIVITY_DFLT 50
51
52#define VOLTAGE_VID_OFFSET_SCALE1 625
53#define VOLTAGE_VID_OFFSET_SCALE2 100
54#define POWERTUNE_DEFAULT_SET_MAX 1
55#define VDDC_VDDCI_DELTA 200
56#define MC_CG_ARB_FREQ_F1 0x0b
57
58#define STRAP_ASIC_RO_LSB 2168
59#define STRAP_ASIC_RO_MSB 2175
60
61#define PPSMC_MSG_ApplyAvfsCksOffVoltage ((uint16_t) 0x415)
62#define PPSMC_MSG_EnableModeSwitchRLCNotification ((uint16_t) 0x305)
63
64static const struct vegam_pt_defaults
65vegam_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = {
66 /* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt,
67 * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */
68 { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000,
69 { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61},
70 { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } },
71};
72
73static const sclkFcwRange_t Range_Table[NUM_SCLK_RANGE] = {
74 {VCO_2_4, POSTDIV_DIV_BY_16, 75, 160, 112},
75 {VCO_3_6, POSTDIV_DIV_BY_16, 112, 224, 160},
76 {VCO_2_4, POSTDIV_DIV_BY_8, 75, 160, 112},
77 {VCO_3_6, POSTDIV_DIV_BY_8, 112, 224, 160},
78 {VCO_2_4, POSTDIV_DIV_BY_4, 75, 160, 112},
79 {VCO_3_6, POSTDIV_DIV_BY_4, 112, 216, 160},
80 {VCO_2_4, POSTDIV_DIV_BY_2, 75, 160, 108},
81 {VCO_3_6, POSTDIV_DIV_BY_2, 112, 216, 160} };
82
83static int vegam_smu_init(struct pp_hwmgr *hwmgr)
84{
85 struct vegam_smumgr *smu_data;
86
87 smu_data = kzalloc(sizeof(struct vegam_smumgr), GFP_KERNEL);
88 if (smu_data == NULL)
89 return -ENOMEM;
90
91 hwmgr->smu_backend = smu_data;
92
93 if (smu7_init(hwmgr)) {
94 kfree(smu_data);
95 return -EINVAL;
96 }
97
98 return 0;
99}
100
101static int vegam_start_smu_in_protection_mode(struct pp_hwmgr *hwmgr)
102{
103 int result = 0;
104
105 /* Wait for smc boot up */
106 /* PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND, RCU_UC_EVENTS, boot_seq_done, 0) */
107
108 /* Assert reset */
109 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
110 SMC_SYSCON_RESET_CNTL, rst_reg, 1);
111
112 result = smu7_upload_smu_firmware_image(hwmgr);
113 if (result != 0)
114 return result;
115
116 /* Clear status */
117 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMU_STATUS, 0);
118
119 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
120 SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
121
122 /* De-assert reset */
123 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
124 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
125
126
127 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1);
128
129
130 /* Call Test SMU message with 0x20000 offset to trigger SMU start */
131 smu7_send_msg_to_smc_offset(hwmgr);
132
133 /* Wait done bit to be set */
134 /* Check pass/failed indicator */
135
136 PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND, SMU_STATUS, SMU_DONE, 0);
137
138 if (1 != PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
139 SMU_STATUS, SMU_PASS))
140 PP_ASSERT_WITH_CODE(false, "SMU Firmware start failed!", return -1);
141
142 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixFIRMWARE_FLAGS, 0);
143
144 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
145 SMC_SYSCON_RESET_CNTL, rst_reg, 1);
146
147 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
148 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
149
150 /* Wait for firmware to initialize */
151 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
152
153 return result;
154}
155
156static int vegam_start_smu_in_non_protection_mode(struct pp_hwmgr *hwmgr)
157{
158 int result = 0;
159
160 /* wait for smc boot up */
161 PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND, RCU_UC_EVENTS, boot_seq_done, 0);
162
163 /* Clear firmware interrupt enable flag */
164 /* PHM_WRITE_VFPF_INDIRECT_FIELD(pSmuMgr, SMC_IND, SMC_SYSCON_MISC_CNTL, pre_fetcher_en, 1); */
165 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
166 ixFIRMWARE_FLAGS, 0);
167
168 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
169 SMC_SYSCON_RESET_CNTL,
170 rst_reg, 1);
171
172 result = smu7_upload_smu_firmware_image(hwmgr);
173 if (result != 0)
174 return result;
175
176 /* Set smc instruct start point at 0x0 */
177 smu7_program_jump_on_start(hwmgr);
178
179 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
180 SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
181
182 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
183 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
184
185 /* Wait for firmware to initialize */
186
187 PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND,
188 FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
189
190 return result;
191}
192
193static int vegam_start_smu(struct pp_hwmgr *hwmgr)
194{
195 int result = 0;
196 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
197
198 /* Only start SMC if SMC RAM is not running */
199 if (!smu7_is_smc_ram_running(hwmgr) && hwmgr->not_vf) {
200 smu_data->protected_mode = (uint8_t)(PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
201 CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_MODE));
202 smu_data->smu7_data.security_hard_key = (uint8_t)(PHM_READ_VFPF_INDIRECT_FIELD(
203 hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_SEL));
204
205 /* Check if SMU is running in protected mode */
206 if (smu_data->protected_mode == 0)
207 result = vegam_start_smu_in_non_protection_mode(hwmgr);
208 else
209 result = vegam_start_smu_in_protection_mode(hwmgr);
210
211 if (result != 0)
212 PP_ASSERT_WITH_CODE(0, "Failed to load SMU ucode.", return result);
213 }
214
215 /* Setup SoftRegsStart here for register lookup in case DummyBackEnd is used and ProcessFirmwareHeader is not executed */
216 smu7_read_smc_sram_dword(hwmgr,
217 SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU75_Firmware_Header, SoftRegisters),
218 &(smu_data->smu7_data.soft_regs_start),
219 0x40000);
220
221 result = smu7_request_smu_load_fw(hwmgr);
222
223 return result;
224}
225
226static int vegam_process_firmware_header(struct pp_hwmgr *hwmgr)
227{
228 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
229 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
230 uint32_t tmp;
231 int result;
232 bool error = false;
233
234 result = smu7_read_smc_sram_dword(hwmgr,
235 SMU7_FIRMWARE_HEADER_LOCATION +
236 offsetof(SMU75_Firmware_Header, DpmTable),
237 &tmp, SMC_RAM_END);
238
239 if (0 == result)
240 smu_data->smu7_data.dpm_table_start = tmp;
241
242 error |= (0 != result);
243
244 result = smu7_read_smc_sram_dword(hwmgr,
245 SMU7_FIRMWARE_HEADER_LOCATION +
246 offsetof(SMU75_Firmware_Header, SoftRegisters),
247 &tmp, SMC_RAM_END);
248
249 if (!result) {
250 data->soft_regs_start = tmp;
251 smu_data->smu7_data.soft_regs_start = tmp;
252 }
253
254 error |= (0 != result);
255
256 result = smu7_read_smc_sram_dword(hwmgr,
257 SMU7_FIRMWARE_HEADER_LOCATION +
258 offsetof(SMU75_Firmware_Header, mcRegisterTable),
259 &tmp, SMC_RAM_END);
260
261 if (!result)
262 smu_data->smu7_data.mc_reg_table_start = tmp;
263
264 result = smu7_read_smc_sram_dword(hwmgr,
265 SMU7_FIRMWARE_HEADER_LOCATION +
266 offsetof(SMU75_Firmware_Header, FanTable),
267 &tmp, SMC_RAM_END);
268
269 if (!result)
270 smu_data->smu7_data.fan_table_start = tmp;
271
272 error |= (0 != result);
273
274 result = smu7_read_smc_sram_dword(hwmgr,
275 SMU7_FIRMWARE_HEADER_LOCATION +
276 offsetof(SMU75_Firmware_Header, mcArbDramTimingTable),
277 &tmp, SMC_RAM_END);
278
279 if (!result)
280 smu_data->smu7_data.arb_table_start = tmp;
281
282 error |= (0 != result);
283
284 result = smu7_read_smc_sram_dword(hwmgr,
285 SMU7_FIRMWARE_HEADER_LOCATION +
286 offsetof(SMU75_Firmware_Header, Version),
287 &tmp, SMC_RAM_END);
288
289 if (!result)
290 hwmgr->microcode_version_info.SMC = tmp;
291
292 error |= (0 != result);
293
294 return error ? -1 : 0;
295}
296
297static bool vegam_is_dpm_running(struct pp_hwmgr *hwmgr)
298{
299 return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device,
300 CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON))
301 ? true : false;
302}
303
304static uint32_t vegam_get_mac_definition(uint32_t value)
305{
306 switch (value) {
307 case SMU_MAX_LEVELS_GRAPHICS:
308 return SMU75_MAX_LEVELS_GRAPHICS;
309 case SMU_MAX_LEVELS_MEMORY:
310 return SMU75_MAX_LEVELS_MEMORY;
311 case SMU_MAX_LEVELS_LINK:
312 return SMU75_MAX_LEVELS_LINK;
313 case SMU_MAX_ENTRIES_SMIO:
314 return SMU75_MAX_ENTRIES_SMIO;
315 case SMU_MAX_LEVELS_VDDC:
316 return SMU75_MAX_LEVELS_VDDC;
317 case SMU_MAX_LEVELS_VDDGFX:
318 return SMU75_MAX_LEVELS_VDDGFX;
319 case SMU_MAX_LEVELS_VDDCI:
320 return SMU75_MAX_LEVELS_VDDCI;
321 case SMU_MAX_LEVELS_MVDD:
322 return SMU75_MAX_LEVELS_MVDD;
323 case SMU_UVD_MCLK_HANDSHAKE_DISABLE:
324 return SMU7_UVD_MCLK_HANDSHAKE_DISABLE |
325 SMU7_VCE_MCLK_HANDSHAKE_DISABLE;
326 }
327
328 pr_warn("can't get the mac of %x\n", value);
329 return 0;
330}
331
332static int vegam_update_uvd_smc_table(struct pp_hwmgr *hwmgr)
333{
334 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
335 uint32_t mm_boot_level_offset, mm_boot_level_value;
336 struct phm_ppt_v1_information *table_info =
337 (struct phm_ppt_v1_information *)(hwmgr->pptable);
338
339 smu_data->smc_state_table.UvdBootLevel = 0;
340 if (table_info->mm_dep_table->count > 0)
341 smu_data->smc_state_table.UvdBootLevel =
342 (uint8_t) (table_info->mm_dep_table->count - 1);
343 mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + offsetof(SMU75_Discrete_DpmTable,
344 UvdBootLevel);
345 mm_boot_level_offset /= 4;
346 mm_boot_level_offset *= 4;
347 mm_boot_level_value = cgs_read_ind_register(hwmgr->device,
348 CGS_IND_REG__SMC, mm_boot_level_offset);
349 mm_boot_level_value &= 0x00FFFFFF;
350 mm_boot_level_value |= smu_data->smc_state_table.UvdBootLevel << 24;
351 cgs_write_ind_register(hwmgr->device,
352 CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
353
354 if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
355 PHM_PlatformCaps_UVDDPM) ||
356 phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
357 PHM_PlatformCaps_StablePState))
358 smum_send_msg_to_smc_with_parameter(hwmgr,
359 PPSMC_MSG_UVDDPM_SetEnabledMask,
360 (uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel));
361 return 0;
362}
363
364static int vegam_update_vce_smc_table(struct pp_hwmgr *hwmgr)
365{
366 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
367 uint32_t mm_boot_level_offset, mm_boot_level_value;
368 struct phm_ppt_v1_information *table_info =
369 (struct phm_ppt_v1_information *)(hwmgr->pptable);
370
371 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
372 PHM_PlatformCaps_StablePState))
373 smu_data->smc_state_table.VceBootLevel =
374 (uint8_t) (table_info->mm_dep_table->count - 1);
375 else
376 smu_data->smc_state_table.VceBootLevel = 0;
377
378 mm_boot_level_offset = smu_data->smu7_data.dpm_table_start +
379 offsetof(SMU75_Discrete_DpmTable, VceBootLevel);
380 mm_boot_level_offset /= 4;
381 mm_boot_level_offset *= 4;
382 mm_boot_level_value = cgs_read_ind_register(hwmgr->device,
383 CGS_IND_REG__SMC, mm_boot_level_offset);
384 mm_boot_level_value &= 0xFF00FFFF;
385 mm_boot_level_value |= smu_data->smc_state_table.VceBootLevel << 16;
386 cgs_write_ind_register(hwmgr->device,
387 CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
388
389 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
390 smum_send_msg_to_smc_with_parameter(hwmgr,
391 PPSMC_MSG_VCEDPM_SetEnabledMask,
392 (uint32_t)1 << smu_data->smc_state_table.VceBootLevel);
393 return 0;
394}
395
396static int vegam_update_samu_smc_table(struct pp_hwmgr *hwmgr)
397{
398 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
399 uint32_t mm_boot_level_offset, mm_boot_level_value;
400
401
402 smu_data->smc_state_table.SamuBootLevel = 0;
403 mm_boot_level_offset = smu_data->smu7_data.dpm_table_start +
404 offsetof(SMU75_Discrete_DpmTable, SamuBootLevel);
405
406 mm_boot_level_offset /= 4;
407 mm_boot_level_offset *= 4;
408 mm_boot_level_value = cgs_read_ind_register(hwmgr->device,
409 CGS_IND_REG__SMC, mm_boot_level_offset);
410 mm_boot_level_value &= 0xFFFFFF00;
411 mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0;
412 cgs_write_ind_register(hwmgr->device,
413 CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
414
415 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
416 PHM_PlatformCaps_StablePState))
417 smum_send_msg_to_smc_with_parameter(hwmgr,
418 PPSMC_MSG_SAMUDPM_SetEnabledMask,
419 (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel));
420 return 0;
421}
422
423
424static int vegam_update_bif_smc_table(struct pp_hwmgr *hwmgr)
425{
426 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
427 struct phm_ppt_v1_information *table_info =
428 (struct phm_ppt_v1_information *)(hwmgr->pptable);
429 struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table;
430 int max_entry, i;
431
432 max_entry = (SMU75_MAX_LEVELS_LINK < pcie_table->count) ?
433 SMU75_MAX_LEVELS_LINK :
434 pcie_table->count;
435 /* Setup BIF_SCLK levels */
436 for (i = 0; i < max_entry; i++)
437 smu_data->bif_sclk_table[i] = pcie_table->entries[i].pcie_sclk;
438 return 0;
439}
440
441static int vegam_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type)
442{
443 switch (type) {
444 case SMU_UVD_TABLE:
445 vegam_update_uvd_smc_table(hwmgr);
446 break;
447 case SMU_VCE_TABLE:
448 vegam_update_vce_smc_table(hwmgr);
449 break;
450 case SMU_SAMU_TABLE:
451 vegam_update_samu_smc_table(hwmgr);
452 break;
453 case SMU_BIF_TABLE:
454 vegam_update_bif_smc_table(hwmgr);
455 break;
456 default:
457 break;
458 }
459 return 0;
460}
461
462static void vegam_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
463{
464 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
465 struct phm_ppt_v1_information *table_info =
466 (struct phm_ppt_v1_information *)(hwmgr->pptable);
467
468 if (table_info &&
469 table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX &&
470 table_info->cac_dtp_table->usPowerTuneDataSetID)
471 smu_data->power_tune_defaults =
472 &vegam_power_tune_data_set_array
473 [table_info->cac_dtp_table->usPowerTuneDataSetID - 1];
474 else
475 smu_data->power_tune_defaults = &vegam_power_tune_data_set_array[0];
476
477}
478
479static int vegam_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr,
480 SMU75_Discrete_DpmTable *table)
481{
482 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
483 uint32_t count, level;
484
485 if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) {
486 count = data->mvdd_voltage_table.count;
487 if (count > SMU_MAX_SMIO_LEVELS)
488 count = SMU_MAX_SMIO_LEVELS;
489 for (level = 0; level < count; level++) {
490 table->SmioTable2.Pattern[level].Voltage = PP_HOST_TO_SMC_US(
491 data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE);
492 /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/
493 table->SmioTable2.Pattern[level].Smio =
494 (uint8_t) level;
495 table->Smio[level] |=
496 data->mvdd_voltage_table.entries[level].smio_low;
497 }
498 table->SmioMask2 = data->mvdd_voltage_table.mask_low;
499
500 table->MvddLevelCount = (uint32_t) PP_HOST_TO_SMC_UL(count);
501 }
502
503 return 0;
504}
505
506static int vegam_populate_smc_vddci_table(struct pp_hwmgr *hwmgr,
507 struct SMU75_Discrete_DpmTable *table)
508{
509 uint32_t count, level;
510 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
511
512 count = data->vddci_voltage_table.count;
513
514 if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) {
515 if (count > SMU_MAX_SMIO_LEVELS)
516 count = SMU_MAX_SMIO_LEVELS;
517 for (level = 0; level < count; ++level) {
518 table->SmioTable1.Pattern[level].Voltage = PP_HOST_TO_SMC_US(
519 data->vddci_voltage_table.entries[level].value * VOLTAGE_SCALE);
520 table->SmioTable1.Pattern[level].Smio = (uint8_t) level;
521
522 table->Smio[level] |= data->vddci_voltage_table.entries[level].smio_low;
523 }
524 }
525
526 table->SmioMask1 = data->vddci_voltage_table.mask_low;
527
528 return 0;
529}
530
531static int vegam_populate_cac_table(struct pp_hwmgr *hwmgr,
532 struct SMU75_Discrete_DpmTable *table)
533{
534 uint32_t count;
535 uint8_t index;
536 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
537 struct phm_ppt_v1_information *table_info =
538 (struct phm_ppt_v1_information *)(hwmgr->pptable);
539 struct phm_ppt_v1_voltage_lookup_table *lookup_table =
540 table_info->vddc_lookup_table;
541 /* tables is already swapped, so in order to use the value from it,
542 * we need to swap it back.
543 * We are populating vddc CAC data to BapmVddc table
544 * in split and merged mode
545 */
546 for (count = 0; count < lookup_table->count; count++) {
547 index = phm_get_voltage_index(lookup_table,
548 data->vddc_voltage_table.entries[count].value);
549 table->BapmVddcVidLoSidd[count] =
550 convert_to_vid(lookup_table->entries[index].us_cac_low);
551 table->BapmVddcVidHiSidd[count] =
552 convert_to_vid(lookup_table->entries[index].us_cac_mid);
553 table->BapmVddcVidHiSidd2[count] =
554 convert_to_vid(lookup_table->entries[index].us_cac_high);
555 }
556
557 return 0;
558}
559
560static int vegam_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr,
561 struct SMU75_Discrete_DpmTable *table)
562{
563 vegam_populate_smc_vddci_table(hwmgr, table);
564 vegam_populate_smc_mvdd_table(hwmgr, table);
565 vegam_populate_cac_table(hwmgr, table);
566
567 return 0;
568}
569
570static int vegam_populate_ulv_level(struct pp_hwmgr *hwmgr,
571 struct SMU75_Discrete_Ulv *state)
572{
573 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
574 struct phm_ppt_v1_information *table_info =
575 (struct phm_ppt_v1_information *)(hwmgr->pptable);
576
577 state->CcPwrDynRm = 0;
578 state->CcPwrDynRm1 = 0;
579
580 state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset;
581 state->VddcOffsetVid = (uint8_t)(table_info->us_ulv_voltage_offset *
582 VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1);
583
584 state->VddcPhase = data->vddc_phase_shed_control ^ 0x3;
585
586 CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm);
587 CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1);
588 CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset);
589
590 return 0;
591}
592
593static int vegam_populate_ulv_state(struct pp_hwmgr *hwmgr,
594 struct SMU75_Discrete_DpmTable *table)
595{
596 return vegam_populate_ulv_level(hwmgr, &table->Ulv);
597}
598
599static int vegam_populate_smc_link_level(struct pp_hwmgr *hwmgr,
600 struct SMU75_Discrete_DpmTable *table)
601{
602 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
603 struct vegam_smumgr *smu_data =
604 (struct vegam_smumgr *)(hwmgr->smu_backend);
605 struct smu7_dpm_table *dpm_table = &data->dpm_table;
606 int i;
607
608 /* Index (dpm_table->pcie_speed_table.count)
609 * is reserved for PCIE boot level. */
610 for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) {
611 table->LinkLevel[i].PcieGenSpeed =
612 (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value;
613 table->LinkLevel[i].PcieLaneCount = (uint8_t)encode_pcie_lane_width(
614 dpm_table->pcie_speed_table.dpm_levels[i].param1);
615 table->LinkLevel[i].EnabledForActivity = 1;
616 table->LinkLevel[i].SPC = (uint8_t)(data->pcie_spc_cap & 0xff);
617 table->LinkLevel[i].DownThreshold = PP_HOST_TO_SMC_UL(5);
618 table->LinkLevel[i].UpThreshold = PP_HOST_TO_SMC_UL(30);
619 }
620
621 smu_data->smc_state_table.LinkLevelCount =
622 (uint8_t)dpm_table->pcie_speed_table.count;
623
624/* To Do move to hwmgr */
625 data->dpm_level_enable_mask.pcie_dpm_enable_mask =
626 phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table);
627
628 return 0;
629}
630
631static int vegam_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr,
632 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table,
633 uint32_t clock, SMU_VoltageLevel *voltage, uint32_t *mvdd)
634{
635 uint32_t i;
636 uint16_t vddci;
637 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
638
639 *voltage = *mvdd = 0;
640
641 /* clock - voltage dependency table is empty table */
642 if (dep_table->count == 0)
643 return -EINVAL;
644
645 for (i = 0; i < dep_table->count; i++) {
646 /* find first sclk bigger than request */
647 if (dep_table->entries[i].clk >= clock) {
648 *voltage |= (dep_table->entries[i].vddc *
649 VOLTAGE_SCALE) << VDDC_SHIFT;
650 if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control)
651 *voltage |= (data->vbios_boot_state.vddci_bootup_value *
652 VOLTAGE_SCALE) << VDDCI_SHIFT;
653 else if (dep_table->entries[i].vddci)
654 *voltage |= (dep_table->entries[i].vddci *
655 VOLTAGE_SCALE) << VDDCI_SHIFT;
656 else {
657 vddci = phm_find_closest_vddci(&(data->vddci_voltage_table),
658 (dep_table->entries[i].vddc -
659 (uint16_t)VDDC_VDDCI_DELTA));
660 *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
661 }
662
663 if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control)
664 *mvdd = data->vbios_boot_state.mvdd_bootup_value *
665 VOLTAGE_SCALE;
666 else if (dep_table->entries[i].mvdd)
667 *mvdd = (uint32_t) dep_table->entries[i].mvdd *
668 VOLTAGE_SCALE;
669
670 *voltage |= 1 << PHASES_SHIFT;
671 return 0;
672 }
673 }
674
675 /* sclk is bigger than max sclk in the dependence table */
676 *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
677 vddci = phm_find_closest_vddci(&(data->vddci_voltage_table),
678 (dep_table->entries[i - 1].vddc -
679 (uint16_t)VDDC_VDDCI_DELTA));
680
681 if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control)
682 *voltage |= (data->vbios_boot_state.vddci_bootup_value *
683 VOLTAGE_SCALE) << VDDCI_SHIFT;
684 else if (dep_table->entries[i - 1].vddci)
685 *voltage |= (dep_table->entries[i - 1].vddci *
686 VOLTAGE_SCALE) << VDDC_SHIFT;
687 else
688 *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
689
690 if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control)
691 *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE;
692 else if (dep_table->entries[i].mvdd)
693 *mvdd = (uint32_t) dep_table->entries[i - 1].mvdd * VOLTAGE_SCALE;
694
695 return 0;
696}
697
698static void vegam_get_sclk_range_table(struct pp_hwmgr *hwmgr,
699 SMU75_Discrete_DpmTable *table)
700{
701 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
702 uint32_t i, ref_clk;
703
704 struct pp_atom_ctrl_sclk_range_table range_table_from_vbios = { { {0} } };
705
706 ref_clk = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
707
708 if (0 == atomctrl_get_smc_sclk_range_table(hwmgr, &range_table_from_vbios)) {
709 for (i = 0; i < NUM_SCLK_RANGE; i++) {
710 table->SclkFcwRangeTable[i].vco_setting =
711 range_table_from_vbios.entry[i].ucVco_setting;
712 table->SclkFcwRangeTable[i].postdiv =
713 range_table_from_vbios.entry[i].ucPostdiv;
714 table->SclkFcwRangeTable[i].fcw_pcc =
715 range_table_from_vbios.entry[i].usFcw_pcc;
716
717 table->SclkFcwRangeTable[i].fcw_trans_upper =
718 range_table_from_vbios.entry[i].usFcw_trans_upper;
719 table->SclkFcwRangeTable[i].fcw_trans_lower =
720 range_table_from_vbios.entry[i].usRcw_trans_lower;
721
722 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc);
723 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper);
724 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower);
725 }
726 return;
727 }
728
729 for (i = 0; i < NUM_SCLK_RANGE; i++) {
730 smu_data->range_table[i].trans_lower_frequency =
731 (ref_clk * Range_Table[i].fcw_trans_lower) >> Range_Table[i].postdiv;
732 smu_data->range_table[i].trans_upper_frequency =
733 (ref_clk * Range_Table[i].fcw_trans_upper) >> Range_Table[i].postdiv;
734
735 table->SclkFcwRangeTable[i].vco_setting = Range_Table[i].vco_setting;
736 table->SclkFcwRangeTable[i].postdiv = Range_Table[i].postdiv;
737 table->SclkFcwRangeTable[i].fcw_pcc = Range_Table[i].fcw_pcc;
738
739 table->SclkFcwRangeTable[i].fcw_trans_upper = Range_Table[i].fcw_trans_upper;
740 table->SclkFcwRangeTable[i].fcw_trans_lower = Range_Table[i].fcw_trans_lower;
741
742 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc);
743 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper);
744 CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower);
745 }
746}
747
748static int vegam_calculate_sclk_params(struct pp_hwmgr *hwmgr,
749 uint32_t clock, SMU_SclkSetting *sclk_setting)
750{
751 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
752 const SMU75_Discrete_DpmTable *table = &(smu_data->smc_state_table);
753 struct pp_atomctrl_clock_dividers_ai dividers;
754 uint32_t ref_clock;
755 uint32_t pcc_target_percent, pcc_target_freq, ss_target_percent, ss_target_freq;
756 uint8_t i;
757 int result;
758 uint64_t temp;
759
760 sclk_setting->SclkFrequency = clock;
761 /* get the engine clock dividers for this clock value */
762 result = atomctrl_get_engine_pll_dividers_ai(hwmgr, clock, &dividers);
763 if (result == 0) {
764 sclk_setting->Fcw_int = dividers.usSclk_fcw_int;
765 sclk_setting->Fcw_frac = dividers.usSclk_fcw_frac;
766 sclk_setting->Pcc_fcw_int = dividers.usPcc_fcw_int;
767 sclk_setting->PllRange = dividers.ucSclkPllRange;
768 sclk_setting->Sclk_slew_rate = 0x400;
769 sclk_setting->Pcc_up_slew_rate = dividers.usPcc_fcw_slew_frac;
770 sclk_setting->Pcc_down_slew_rate = 0xffff;
771 sclk_setting->SSc_En = dividers.ucSscEnable;
772 sclk_setting->Fcw1_int = dividers.usSsc_fcw1_int;
773 sclk_setting->Fcw1_frac = dividers.usSsc_fcw1_frac;
774 sclk_setting->Sclk_ss_slew_rate = dividers.usSsc_fcw_slew_frac;
775 return result;
776 }
777
778 ref_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
779
780 for (i = 0; i < NUM_SCLK_RANGE; i++) {
781 if (clock > smu_data->range_table[i].trans_lower_frequency
782 && clock <= smu_data->range_table[i].trans_upper_frequency) {
783 sclk_setting->PllRange = i;
784 break;
785 }
786 }
787
788 sclk_setting->Fcw_int = (uint16_t)
789 ((clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) /
790 ref_clock);
791 temp = clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv;
792 temp <<= 0x10;
793 do_div(temp, ref_clock);
794 sclk_setting->Fcw_frac = temp & 0xffff;
795
796 pcc_target_percent = 10; /* Hardcode 10% for now. */
797 pcc_target_freq = clock - (clock * pcc_target_percent / 100);
798 sclk_setting->Pcc_fcw_int = (uint16_t)
799 ((pcc_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) /
800 ref_clock);
801
802 ss_target_percent = 2; /* Hardcode 2% for now. */
803 sclk_setting->SSc_En = 0;
804 if (ss_target_percent) {
805 sclk_setting->SSc_En = 1;
806 ss_target_freq = clock - (clock * ss_target_percent / 100);
807 sclk_setting->Fcw1_int = (uint16_t)
808 ((ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) /
809 ref_clock);
810 temp = ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv;
811 temp <<= 0x10;
812 do_div(temp, ref_clock);
813 sclk_setting->Fcw1_frac = temp & 0xffff;
814 }
815
816 return 0;
817}
818
819static uint8_t vegam_get_sleep_divider_id_from_clock(uint32_t clock,
820 uint32_t clock_insr)
821{
822 uint8_t i;
823 uint32_t temp;
824 uint32_t min = max(clock_insr, (uint32_t)SMU7_MINIMUM_ENGINE_CLOCK);
825
826 PP_ASSERT_WITH_CODE((clock >= min),
827 "Engine clock can't satisfy stutter requirement!",
828 return 0);
829 for (i = 31; ; i--) {
830 temp = clock / (i + 1);
831
832 if (temp >= min || i == 0)
833 break;
834 }
835 return i;
836}
837
838static int vegam_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
839 uint32_t clock, struct SMU75_Discrete_GraphicsLevel *level)
840{
841 int result;
842 /* PP_Clocks minClocks; */
843 uint32_t mvdd;
844 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
845 struct phm_ppt_v1_information *table_info =
846 (struct phm_ppt_v1_information *)(hwmgr->pptable);
847 SMU_SclkSetting curr_sclk_setting = { 0 };
848
849 result = vegam_calculate_sclk_params(hwmgr, clock, &curr_sclk_setting);
850
851 /* populate graphics levels */
852 result = vegam_get_dependency_volt_by_clk(hwmgr,
853 table_info->vdd_dep_on_sclk, clock,
854 &level->MinVoltage, &mvdd);
855
856 PP_ASSERT_WITH_CODE((0 == result),
857 "can not find VDDC voltage value for "
858 "VDDC engine clock dependency table",
859 return result);
860 level->ActivityLevel = (uint16_t)(SclkDPMTuning_VEGAM >> DPMTuning_Activity_Shift);
861
862 level->CcPwrDynRm = 0;
863 level->CcPwrDynRm1 = 0;
864 level->EnabledForActivity = 0;
865 level->EnabledForThrottle = 1;
866 level->VoltageDownHyst = 0;
867 level->PowerThrottle = 0;
868 data->display_timing.min_clock_in_sr = hwmgr->display_config->min_core_set_clock_in_sr;
869
870 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep))
871 level->DeepSleepDivId = vegam_get_sleep_divider_id_from_clock(clock,
872 hwmgr->display_config->min_core_set_clock_in_sr);
873
874 level->SclkSetting = curr_sclk_setting;
875
876 CONVERT_FROM_HOST_TO_SMC_UL(level->MinVoltage);
877 CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm);
878 CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1);
879 CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel);
880 CONVERT_FROM_HOST_TO_SMC_UL(level->SclkSetting.SclkFrequency);
881 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_int);
882 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_frac);
883 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_fcw_int);
884 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_slew_rate);
885 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_up_slew_rate);
886 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_down_slew_rate);
887 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_int);
888 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_frac);
889 CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_ss_slew_rate);
890 return 0;
891}
892
893static int vegam_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
894{
895 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
896 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
897 struct smu7_dpm_table *dpm_table = &hw_data->dpm_table;
898 struct phm_ppt_v1_information *table_info =
899 (struct phm_ppt_v1_information *)(hwmgr->pptable);
900 struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table;
901 uint8_t pcie_entry_cnt = (uint8_t) hw_data->dpm_table.pcie_speed_table.count;
902 int result = 0;
903 uint32_t array = smu_data->smu7_data.dpm_table_start +
904 offsetof(SMU75_Discrete_DpmTable, GraphicsLevel);
905 uint32_t array_size = sizeof(struct SMU75_Discrete_GraphicsLevel) *
906 SMU75_MAX_LEVELS_GRAPHICS;
907 struct SMU75_Discrete_GraphicsLevel *levels =
908 smu_data->smc_state_table.GraphicsLevel;
909 uint32_t i, max_entry;
910 uint8_t hightest_pcie_level_enabled = 0,
911 lowest_pcie_level_enabled = 0,
912 mid_pcie_level_enabled = 0,
913 count = 0;
914
915 vegam_get_sclk_range_table(hwmgr, &(smu_data->smc_state_table));
916
917 for (i = 0; i < dpm_table->sclk_table.count; i++) {
918
919 result = vegam_populate_single_graphic_level(hwmgr,
920 dpm_table->sclk_table.dpm_levels[i].value,
921 &(smu_data->smc_state_table.GraphicsLevel[i]));
922 if (result)
923 return result;
924
925 levels[i].UpHyst = (uint8_t)
926 (SclkDPMTuning_VEGAM >> DPMTuning_Uphyst_Shift);
927 levels[i].DownHyst = (uint8_t)
928 (SclkDPMTuning_VEGAM >> DPMTuning_Downhyst_Shift);
929 /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */
930 if (i > 1)
931 levels[i].DeepSleepDivId = 0;
932 }
933 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
934 PHM_PlatformCaps_SPLLShutdownSupport))
935 smu_data->smc_state_table.GraphicsLevel[0].SclkSetting.SSc_En = 0;
936
937 smu_data->smc_state_table.GraphicsDpmLevelCount =
938 (uint8_t)dpm_table->sclk_table.count;
939 hw_data->dpm_level_enable_mask.sclk_dpm_enable_mask =
940 phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table);
941
942 for (i = 0; i < dpm_table->sclk_table.count; i++)
943 levels[i].EnabledForActivity =
944 (hw_data->dpm_level_enable_mask.sclk_dpm_enable_mask >> i) & 0x1;
945
946 if (pcie_table != NULL) {
947 PP_ASSERT_WITH_CODE((1 <= pcie_entry_cnt),
948 "There must be 1 or more PCIE levels defined in PPTable.",
949 return -EINVAL);
950 max_entry = pcie_entry_cnt - 1;
951 for (i = 0; i < dpm_table->sclk_table.count; i++)
952 levels[i].pcieDpmLevel =
953 (uint8_t) ((i < max_entry) ? i : max_entry);
954 } else {
955 while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
956 ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &
957 (1 << (hightest_pcie_level_enabled + 1))) != 0))
958 hightest_pcie_level_enabled++;
959
960 while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
961 ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &
962 (1 << lowest_pcie_level_enabled)) == 0))
963 lowest_pcie_level_enabled++;
964
965 while ((count < hightest_pcie_level_enabled) &&
966 ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask &
967 (1 << (lowest_pcie_level_enabled + 1 + count))) == 0))
968 count++;
969
970 mid_pcie_level_enabled = (lowest_pcie_level_enabled + 1 + count) <
971 hightest_pcie_level_enabled ?
972 (lowest_pcie_level_enabled + 1 + count) :
973 hightest_pcie_level_enabled;
974
975 /* set pcieDpmLevel to hightest_pcie_level_enabled */
976 for (i = 2; i < dpm_table->sclk_table.count; i++)
977 levels[i].pcieDpmLevel = hightest_pcie_level_enabled;
978
979 /* set pcieDpmLevel to lowest_pcie_level_enabled */
980 levels[0].pcieDpmLevel = lowest_pcie_level_enabled;
981
982 /* set pcieDpmLevel to mid_pcie_level_enabled */
983 levels[1].pcieDpmLevel = mid_pcie_level_enabled;
984 }
985 /* level count will send to smc once at init smc table and never change */
986 result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels,
987 (uint32_t)array_size, SMC_RAM_END);
988
989 return result;
990}
991
992static int vegam_calculate_mclk_params(struct pp_hwmgr *hwmgr,
993 uint32_t clock, struct SMU75_Discrete_MemoryLevel *mem_level)
994{
995 struct pp_atomctrl_memory_clock_param_ai mpll_param;
996
997 PP_ASSERT_WITH_CODE(!atomctrl_get_memory_pll_dividers_ai(hwmgr,
998 clock, &mpll_param),
999 "Failed to retrieve memory pll parameter.",
1000 return -EINVAL);
1001
1002 mem_level->MclkFrequency = (uint32_t)mpll_param.ulClock;
1003 mem_level->Fcw_int = (uint16_t)mpll_param.ulMclk_fcw_int;
1004 mem_level->Fcw_frac = (uint16_t)mpll_param.ulMclk_fcw_frac;
1005 mem_level->Postdiv = (uint8_t)mpll_param.ulPostDiv;
1006
1007 return 0;
1008}
1009
1010static int vegam_populate_single_memory_level(struct pp_hwmgr *hwmgr,
1011 uint32_t clock, struct SMU75_Discrete_MemoryLevel *mem_level)
1012{
1013 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1014 struct phm_ppt_v1_information *table_info =
1015 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1016 int result = 0;
1017 uint32_t mclk_stutter_mode_threshold = 60000;
1018
1019
1020 if (table_info->vdd_dep_on_mclk) {
1021 result = vegam_get_dependency_volt_by_clk(hwmgr,
1022 table_info->vdd_dep_on_mclk, clock,
1023 &mem_level->MinVoltage, &mem_level->MinMvdd);
1024 PP_ASSERT_WITH_CODE(!result,
1025 "can not find MinVddc voltage value from memory "
1026 "VDDC voltage dependency table", return result);
1027 }
1028
1029 result = vegam_calculate_mclk_params(hwmgr, clock, mem_level);
1030 PP_ASSERT_WITH_CODE(!result,
1031 "Failed to calculate mclk params.",
1032 return -EINVAL);
1033
1034 mem_level->EnabledForThrottle = 1;
1035 mem_level->EnabledForActivity = 0;
1036 mem_level->VoltageDownHyst = 0;
1037 mem_level->ActivityLevel = (uint16_t)
1038 (MemoryDPMTuning_VEGAM >> DPMTuning_Activity_Shift);
1039 mem_level->StutterEnable = false;
1040 mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
1041
1042 data->display_timing.num_existing_displays = hwmgr->display_config->num_display;
1043
1044 if (mclk_stutter_mode_threshold &&
1045 (clock <= mclk_stutter_mode_threshold) &&
1046 (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL,
1047 STUTTER_ENABLE) & 0x1))
1048 mem_level->StutterEnable = true;
1049
1050 if (!result) {
1051 CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinMvdd);
1052 CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MclkFrequency);
1053 CONVERT_FROM_HOST_TO_SMC_US(mem_level->Fcw_int);
1054 CONVERT_FROM_HOST_TO_SMC_US(mem_level->Fcw_frac);
1055 CONVERT_FROM_HOST_TO_SMC_US(mem_level->ActivityLevel);
1056 CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinVoltage);
1057 }
1058
1059 return result;
1060}
1061
1062static int vegam_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
1063{
1064 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
1065 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1066 struct smu7_dpm_table *dpm_table = &hw_data->dpm_table;
1067 int result;
1068 /* populate MCLK dpm table to SMU7 */
1069 uint32_t array = smu_data->smu7_data.dpm_table_start +
1070 offsetof(SMU75_Discrete_DpmTable, MemoryLevel);
1071 uint32_t array_size = sizeof(SMU75_Discrete_MemoryLevel) *
1072 SMU75_MAX_LEVELS_MEMORY;
1073 struct SMU75_Discrete_MemoryLevel *levels =
1074 smu_data->smc_state_table.MemoryLevel;
1075 uint32_t i;
1076
1077 for (i = 0; i < dpm_table->mclk_table.count; i++) {
1078 PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value),
1079 "can not populate memory level as memory clock is zero",
1080 return -EINVAL);
1081 result = vegam_populate_single_memory_level(hwmgr,
1082 dpm_table->mclk_table.dpm_levels[i].value,
1083 &levels[i]);
1084
1085 if (result)
1086 return result;
1087
1088 levels[i].UpHyst = (uint8_t)
1089 (MemoryDPMTuning_VEGAM >> DPMTuning_Uphyst_Shift);
1090 levels[i].DownHyst = (uint8_t)
1091 (MemoryDPMTuning_VEGAM >> DPMTuning_Downhyst_Shift);
1092 }
1093
1094 smu_data->smc_state_table.MemoryDpmLevelCount =
1095 (uint8_t)dpm_table->mclk_table.count;
1096 hw_data->dpm_level_enable_mask.mclk_dpm_enable_mask =
1097 phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table);
1098
1099 for (i = 0; i < dpm_table->mclk_table.count; i++)
1100 levels[i].EnabledForActivity =
1101 (hw_data->dpm_level_enable_mask.mclk_dpm_enable_mask >> i) & 0x1;
1102
1103 levels[dpm_table->mclk_table.count - 1].DisplayWatermark =
1104 PPSMC_DISPLAY_WATERMARK_HIGH;
1105
1106 /* level count will send to smc once at init smc table and never change */
1107 result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels,
1108 (uint32_t)array_size, SMC_RAM_END);
1109
1110 return result;
1111}
1112
1113static int vegam_populate_mvdd_value(struct pp_hwmgr *hwmgr,
1114 uint32_t mclk, SMIO_Pattern *smio_pat)
1115{
1116 const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1117 struct phm_ppt_v1_information *table_info =
1118 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1119 uint32_t i = 0;
1120
1121 if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) {
1122 /* find mvdd value which clock is more than request */
1123 for (i = 0; i < table_info->vdd_dep_on_mclk->count; i++) {
1124 if (mclk <= table_info->vdd_dep_on_mclk->entries[i].clk) {
1125 smio_pat->Voltage = data->mvdd_voltage_table.entries[i].value;
1126 break;
1127 }
1128 }
1129 PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count,
1130 "MVDD Voltage is outside the supported range.",
1131 return -EINVAL);
1132 } else
1133 return -EINVAL;
1134
1135 return 0;
1136}
1137
1138static int vegam_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
1139 SMU75_Discrete_DpmTable *table)
1140{
1141 int result = 0;
1142 uint32_t sclk_frequency;
1143 const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1144 struct phm_ppt_v1_information *table_info =
1145 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1146 SMIO_Pattern vol_level;
1147 uint32_t mvdd;
1148 uint16_t us_mvdd;
1149
1150 table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC;
1151
1152 /* Get MinVoltage and Frequency from DPM0,
1153 * already converted to SMC_UL */
1154 sclk_frequency = data->vbios_boot_state.sclk_bootup_value;
1155 result = vegam_get_dependency_volt_by_clk(hwmgr,
1156 table_info->vdd_dep_on_sclk,
1157 sclk_frequency,
1158 &table->ACPILevel.MinVoltage, &mvdd);
1159 PP_ASSERT_WITH_CODE(!result,
1160 "Cannot find ACPI VDDC voltage value "
1161 "in Clock Dependency Table",
1162 );
1163
1164 result = vegam_calculate_sclk_params(hwmgr, sclk_frequency,
1165 &(table->ACPILevel.SclkSetting));
1166 PP_ASSERT_WITH_CODE(!result,
1167 "Error retrieving Engine Clock dividers from VBIOS.",
1168 return result);
1169
1170 table->ACPILevel.DeepSleepDivId = 0;
1171 table->ACPILevel.CcPwrDynRm = 0;
1172 table->ACPILevel.CcPwrDynRm1 = 0;
1173
1174 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags);
1175 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.MinVoltage);
1176 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm);
1177 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1);
1178
1179 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkSetting.SclkFrequency);
1180 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_int);
1181 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_frac);
1182 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_fcw_int);
1183 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_slew_rate);
1184 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_up_slew_rate);
1185 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_down_slew_rate);
1186 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_int);
1187 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_frac);
1188 CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate);
1189
1190
1191 /* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */
1192 table->MemoryACPILevel.MclkFrequency = data->vbios_boot_state.mclk_bootup_value;
1193 result = vegam_get_dependency_volt_by_clk(hwmgr,
1194 table_info->vdd_dep_on_mclk,
1195 table->MemoryACPILevel.MclkFrequency,
1196 &table->MemoryACPILevel.MinVoltage, &mvdd);
1197 PP_ASSERT_WITH_CODE((0 == result),
1198 "Cannot find ACPI VDDCI voltage value "
1199 "in Clock Dependency Table",
1200 );
1201
1202 us_mvdd = 0;
1203 if ((SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) ||
1204 (data->mclk_dpm_key_disabled))
1205 us_mvdd = data->vbios_boot_state.mvdd_bootup_value;
1206 else {
1207 if (!vegam_populate_mvdd_value(hwmgr,
1208 data->dpm_table.mclk_table.dpm_levels[0].value,
1209 &vol_level))
1210 us_mvdd = vol_level.Voltage;
1211 }
1212
1213 if (!vegam_populate_mvdd_value(hwmgr, 0, &vol_level))
1214 table->MemoryACPILevel.MinMvdd = PP_HOST_TO_SMC_UL(vol_level.Voltage);
1215 else
1216 table->MemoryACPILevel.MinMvdd = 0;
1217
1218 table->MemoryACPILevel.StutterEnable = false;
1219
1220 table->MemoryACPILevel.EnabledForThrottle = 0;
1221 table->MemoryACPILevel.EnabledForActivity = 0;
1222 table->MemoryACPILevel.UpHyst = 0;
1223 table->MemoryACPILevel.DownHyst = 100;
1224 table->MemoryACPILevel.VoltageDownHyst = 0;
1225 table->MemoryACPILevel.ActivityLevel =
1226 PP_HOST_TO_SMC_US(data->current_profile_setting.mclk_activity);
1227
1228 CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MclkFrequency);
1229 CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage);
1230
1231 return result;
1232}
1233
1234static int vegam_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
1235 SMU75_Discrete_DpmTable *table)
1236{
1237 int result = -EINVAL;
1238 uint8_t count;
1239 struct pp_atomctrl_clock_dividers_vi dividers;
1240 struct phm_ppt_v1_information *table_info =
1241 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1242 struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
1243 table_info->mm_dep_table;
1244 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1245 uint32_t vddci;
1246
1247 table->VceLevelCount = (uint8_t)(mm_table->count);
1248 table->VceBootLevel = 0;
1249
1250 for (count = 0; count < table->VceLevelCount; count++) {
1251 table->VceLevel[count].Frequency = mm_table->entries[count].eclk;
1252 table->VceLevel[count].MinVoltage = 0;
1253 table->VceLevel[count].MinVoltage |=
1254 (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
1255
1256 if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control)
1257 vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table),
1258 mm_table->entries[count].vddc - VDDC_VDDCI_DELTA);
1259 else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control)
1260 vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA;
1261 else
1262 vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT;
1263
1264
1265 table->VceLevel[count].MinVoltage |=
1266 (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
1267 table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
1268
1269 /*retrieve divider value for VBIOS */
1270 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1271 table->VceLevel[count].Frequency, &dividers);
1272 PP_ASSERT_WITH_CODE((0 == result),
1273 "can not find divide id for VCE engine clock",
1274 return result);
1275
1276 table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
1277
1278 CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency);
1279 CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].MinVoltage);
1280 }
1281 return result;
1282}
1283
1284static int vegam_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
1285 SMU75_Discrete_DpmTable *table)
1286{
1287 int result = -EINVAL;
1288 uint8_t count;
1289 struct pp_atomctrl_clock_dividers_vi dividers;
1290 struct phm_ppt_v1_information *table_info =
1291 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1292 struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
1293 table_info->mm_dep_table;
1294 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1295 uint32_t vddci;
1296
1297 table->SamuBootLevel = 0;
1298 table->SamuLevelCount = (uint8_t)(mm_table->count);
1299
1300 for (count = 0; count < table->SamuLevelCount; count++) {
1301 /* not sure whether we need evclk or not */
1302 table->SamuLevel[count].MinVoltage = 0;
1303 table->SamuLevel[count].Frequency = mm_table->entries[count].samclock;
1304 table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
1305 VOLTAGE_SCALE) << VDDC_SHIFT;
1306
1307 if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control)
1308 vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table),
1309 mm_table->entries[count].vddc - VDDC_VDDCI_DELTA);
1310 else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control)
1311 vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA;
1312 else
1313 vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT;
1314
1315 table->SamuLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
1316 table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
1317
1318 /* retrieve divider value for VBIOS */
1319 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1320 table->SamuLevel[count].Frequency, &dividers);
1321 PP_ASSERT_WITH_CODE((0 == result),
1322 "can not find divide id for samu clock", return result);
1323
1324 table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
1325
1326 CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency);
1327 CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].MinVoltage);
1328 }
1329 return result;
1330}
1331
1332static int vegam_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr,
1333 int32_t eng_clock, int32_t mem_clock,
1334 SMU75_Discrete_MCArbDramTimingTableEntry *arb_regs)
1335{
1336 uint32_t dram_timing;
1337 uint32_t dram_timing2;
1338 uint32_t burst_time;
1339 uint32_t rfsh_rate;
1340 uint32_t misc3;
1341
1342 int result;
1343
1344 result = atomctrl_set_engine_dram_timings_rv770(hwmgr,
1345 eng_clock, mem_clock);
1346 PP_ASSERT_WITH_CODE(result == 0,
1347 "Error calling VBIOS to set DRAM_TIMING.",
1348 return result);
1349
1350 dram_timing = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING);
1351 dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2);
1352 burst_time = cgs_read_register(hwmgr->device, mmMC_ARB_BURST_TIME);
1353 rfsh_rate = cgs_read_register(hwmgr->device, mmMC_ARB_RFSH_RATE);
1354 misc3 = cgs_read_register(hwmgr->device, mmMC_ARB_MISC3);
1355
1356 arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dram_timing);
1357 arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dram_timing2);
1358 arb_regs->McArbBurstTime = PP_HOST_TO_SMC_UL(burst_time);
1359 arb_regs->McArbRfshRate = PP_HOST_TO_SMC_UL(rfsh_rate);
1360 arb_regs->McArbMisc3 = PP_HOST_TO_SMC_UL(misc3);
1361
1362 return 0;
1363}
1364
1365static int vegam_program_memory_timing_parameters(struct pp_hwmgr *hwmgr)
1366{
1367 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
1368 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1369 struct SMU75_Discrete_MCArbDramTimingTable arb_regs;
1370 uint32_t i, j;
1371 int result = 0;
1372
1373 memset(&arb_regs, 0, sizeof(SMU75_Discrete_MCArbDramTimingTable));
1374
1375 for (i = 0; i < hw_data->dpm_table.sclk_table.count; i++) {
1376 for (j = 0; j < hw_data->dpm_table.mclk_table.count; j++) {
1377 result = vegam_populate_memory_timing_parameters(hwmgr,
1378 hw_data->dpm_table.sclk_table.dpm_levels[i].value,
1379 hw_data->dpm_table.mclk_table.dpm_levels[j].value,
1380 &arb_regs.entries[i][j]);
1381 if (result)
1382 return result;
1383 }
1384 }
1385
1386 result = smu7_copy_bytes_to_smc(
1387 hwmgr,
1388 smu_data->smu7_data.arb_table_start,
1389 (uint8_t *)&arb_regs,
1390 sizeof(SMU75_Discrete_MCArbDramTimingTable),
1391 SMC_RAM_END);
1392 return result;
1393}
1394
1395static int vegam_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
1396 struct SMU75_Discrete_DpmTable *table)
1397{
1398 int result = -EINVAL;
1399 uint8_t count;
1400 struct pp_atomctrl_clock_dividers_vi dividers;
1401 struct phm_ppt_v1_information *table_info =
1402 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1403 struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
1404 table_info->mm_dep_table;
1405 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1406 uint32_t vddci;
1407
1408 table->UvdLevelCount = (uint8_t)(mm_table->count);
1409 table->UvdBootLevel = 0;
1410
1411 for (count = 0; count < table->UvdLevelCount; count++) {
1412 table->UvdLevel[count].MinVoltage = 0;
1413 table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk;
1414 table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk;
1415 table->UvdLevel[count].MinVoltage |=
1416 (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
1417
1418 if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control)
1419 vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table),
1420 mm_table->entries[count].vddc - VDDC_VDDCI_DELTA);
1421 else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control)
1422 vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA;
1423 else
1424 vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT;
1425
1426 table->UvdLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
1427 table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
1428
1429 /* retrieve divider value for VBIOS */
1430 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1431 table->UvdLevel[count].VclkFrequency, &dividers);
1432 PP_ASSERT_WITH_CODE((0 == result),
1433 "can not find divide id for Vclk clock", return result);
1434
1435 table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider;
1436
1437 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
1438 table->UvdLevel[count].DclkFrequency, &dividers);
1439 PP_ASSERT_WITH_CODE((0 == result),
1440 "can not find divide id for Dclk clock", return result);
1441
1442 table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider;
1443
1444 CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency);
1445 CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency);
1446 CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].MinVoltage);
1447 }
1448
1449 return result;
1450}
1451
1452static int vegam_populate_smc_boot_level(struct pp_hwmgr *hwmgr,
1453 struct SMU75_Discrete_DpmTable *table)
1454{
1455 int result = 0;
1456 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1457
1458 table->GraphicsBootLevel = 0;
1459 table->MemoryBootLevel = 0;
1460
1461 /* find boot level from dpm table */
1462 result = phm_find_boot_level(&(data->dpm_table.sclk_table),
1463 data->vbios_boot_state.sclk_bootup_value,
1464 (uint32_t *)&(table->GraphicsBootLevel));
1465
1466 result = phm_find_boot_level(&(data->dpm_table.mclk_table),
1467 data->vbios_boot_state.mclk_bootup_value,
1468 (uint32_t *)&(table->MemoryBootLevel));
1469
1470 table->BootVddc = data->vbios_boot_state.vddc_bootup_value *
1471 VOLTAGE_SCALE;
1472 table->BootVddci = data->vbios_boot_state.vddci_bootup_value *
1473 VOLTAGE_SCALE;
1474 table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value *
1475 VOLTAGE_SCALE;
1476
1477 CONVERT_FROM_HOST_TO_SMC_US(table->BootVddc);
1478 CONVERT_FROM_HOST_TO_SMC_US(table->BootVddci);
1479 CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd);
1480
1481 return 0;
1482}
1483
1484static int vegam_populate_smc_initial_state(struct pp_hwmgr *hwmgr)
1485{
1486 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
1487 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1488 struct phm_ppt_v1_information *table_info =
1489 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1490 uint8_t count, level;
1491
1492 count = (uint8_t)(table_info->vdd_dep_on_sclk->count);
1493
1494 for (level = 0; level < count; level++) {
1495 if (table_info->vdd_dep_on_sclk->entries[level].clk >=
1496 hw_data->vbios_boot_state.sclk_bootup_value) {
1497 smu_data->smc_state_table.GraphicsBootLevel = level;
1498 break;
1499 }
1500 }
1501
1502 count = (uint8_t)(table_info->vdd_dep_on_mclk->count);
1503 for (level = 0; level < count; level++) {
1504 if (table_info->vdd_dep_on_mclk->entries[level].clk >=
1505 hw_data->vbios_boot_state.mclk_bootup_value) {
1506 smu_data->smc_state_table.MemoryBootLevel = level;
1507 break;
1508 }
1509 }
1510
1511 return 0;
1512}
1513
1514static uint16_t scale_fan_gain_settings(uint16_t raw_setting)
1515{
1516 uint32_t tmp;
1517 tmp = raw_setting * 4096 / 100;
1518 return (uint16_t)tmp;
1519}
1520
1521static int vegam_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr)
1522{
1523 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1524
1525 const struct vegam_pt_defaults *defaults = smu_data->power_tune_defaults;
1526 SMU75_Discrete_DpmTable *table = &(smu_data->smc_state_table);
1527 struct phm_ppt_v1_information *table_info =
1528 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1529 struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table;
1530 struct pp_advance_fan_control_parameters *fan_table =
1531 &hwmgr->thermal_controller.advanceFanControlParameters;
1532 int i, j, k;
1533 const uint16_t *pdef1;
1534 const uint16_t *pdef2;
1535
1536 table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128));
1537 table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128));
1538
1539 PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255,
1540 "Target Operating Temp is out of Range!",
1541 );
1542
1543 table->TemperatureLimitEdge = PP_HOST_TO_SMC_US(
1544 cac_dtp_table->usTargetOperatingTemp * 256);
1545 table->TemperatureLimitHotspot = PP_HOST_TO_SMC_US(
1546 cac_dtp_table->usTemperatureLimitHotspot * 256);
1547 table->FanGainEdge = PP_HOST_TO_SMC_US(
1548 scale_fan_gain_settings(fan_table->usFanGainEdge));
1549 table->FanGainHotspot = PP_HOST_TO_SMC_US(
1550 scale_fan_gain_settings(fan_table->usFanGainHotspot));
1551
1552 pdef1 = defaults->BAPMTI_R;
1553 pdef2 = defaults->BAPMTI_RC;
1554
1555 for (i = 0; i < SMU75_DTE_ITERATIONS; i++) {
1556 for (j = 0; j < SMU75_DTE_SOURCES; j++) {
1557 for (k = 0; k < SMU75_DTE_SINKS; k++) {
1558 table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*pdef1);
1559 table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*pdef2);
1560 pdef1++;
1561 pdef2++;
1562 }
1563 }
1564 }
1565
1566 return 0;
1567}
1568
1569static int vegam_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
1570{
1571 uint32_t ro, efuse, volt_without_cks, volt_with_cks, value, max, min;
1572 struct vegam_smumgr *smu_data =
1573 (struct vegam_smumgr *)(hwmgr->smu_backend);
1574
1575 uint8_t i, stretch_amount, stretch_amount2, volt_offset = 0;
1576 struct phm_ppt_v1_information *table_info =
1577 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1578 struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
1579 table_info->vdd_dep_on_sclk;
1580 uint32_t mask = (1 << ((STRAP_ASIC_RO_MSB - STRAP_ASIC_RO_LSB) + 1)) - 1;
1581
1582 stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount;
1583
1584 atomctrl_read_efuse(hwmgr, STRAP_ASIC_RO_LSB, STRAP_ASIC_RO_MSB,
1585 mask, &efuse);
1586
1587 min = 1200;
1588 max = 2500;
1589
1590 ro = efuse * (max - min) / 255 + min;
1591
1592 /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */
1593 for (i = 0; i < sclk_table->count; i++) {
1594 smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |=
1595 sclk_table->entries[i].cks_enable << i;
1596 volt_without_cks = (uint32_t)((2753594000U + (sclk_table->entries[i].clk/100) *
1597 136418 - (ro - 70) * 1000000) /
1598 (2424180 - (sclk_table->entries[i].clk/100) * 1132925/1000));
1599 volt_with_cks = (uint32_t)((2797202000U + sclk_table->entries[i].clk/100 *
1600 3232 - (ro - 65) * 1000000) /
1601 (2522480 - sclk_table->entries[i].clk/100 * 115764/100));
1602
1603 if (volt_without_cks >= volt_with_cks)
1604 volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks +
1605 sclk_table->entries[i].cks_voffset) * 100 + 624) / 625);
1606
1607 smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset;
1608 }
1609
1610 smu_data->smc_state_table.LdoRefSel =
1611 (table_info->cac_dtp_table->ucCKS_LDO_REFSEL != 0) ?
1612 table_info->cac_dtp_table->ucCKS_LDO_REFSEL : 5;
1613 /* Populate CKS Lookup Table */
1614 if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5)
1615 stretch_amount2 = 0;
1616 else if (stretch_amount == 3 || stretch_amount == 4)
1617 stretch_amount2 = 1;
1618 else {
1619 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
1620 PHM_PlatformCaps_ClockStretcher);
1621 PP_ASSERT_WITH_CODE(false,
1622 "Stretch Amount in PPTable not supported\n",
1623 return -EINVAL);
1624 }
1625
1626 value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL);
1627 value &= 0xFFFFFFFE;
1628 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value);
1629
1630 return 0;
1631}
1632
1633static bool vegam_is_hw_avfs_present(struct pp_hwmgr *hwmgr)
1634{
1635 uint32_t efuse;
1636
1637 efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1638 ixSMU_EFUSE_0 + (49 * 4));
1639 efuse &= 0x00000001;
1640
1641 if (efuse)
1642 return true;
1643
1644 return false;
1645}
1646
1647static int vegam_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
1648{
1649 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1650 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1651
1652 SMU75_Discrete_DpmTable *table = &(smu_data->smc_state_table);
1653 int result = 0;
1654 struct pp_atom_ctrl__avfs_parameters avfs_params = {0};
1655 AVFS_meanNsigma_t AVFS_meanNsigma = { {0} };
1656 AVFS_Sclk_Offset_t AVFS_SclkOffset = { {0} };
1657 uint32_t tmp, i;
1658
1659 struct phm_ppt_v1_information *table_info =
1660 (struct phm_ppt_v1_information *)hwmgr->pptable;
1661 struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
1662 table_info->vdd_dep_on_sclk;
1663
1664 if (!hwmgr->avfs_supported)
1665 return 0;
1666
1667 result = atomctrl_get_avfs_information(hwmgr, &avfs_params);
1668
1669 if (0 == result) {
1670 table->BTCGB_VDROOP_TABLE[0].a0 =
1671 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0);
1672 table->BTCGB_VDROOP_TABLE[0].a1 =
1673 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1);
1674 table->BTCGB_VDROOP_TABLE[0].a2 =
1675 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2);
1676 table->BTCGB_VDROOP_TABLE[1].a0 =
1677 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0);
1678 table->BTCGB_VDROOP_TABLE[1].a1 =
1679 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1);
1680 table->BTCGB_VDROOP_TABLE[1].a2 =
1681 PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2);
1682 table->AVFSGB_FUSE_TABLE[0].m1 =
1683 PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1);
1684 table->AVFSGB_FUSE_TABLE[0].m2 =
1685 PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2);
1686 table->AVFSGB_FUSE_TABLE[0].b =
1687 PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b);
1688 table->AVFSGB_FUSE_TABLE[0].m1_shift = 24;
1689 table->AVFSGB_FUSE_TABLE[0].m2_shift = 12;
1690 table->AVFSGB_FUSE_TABLE[1].m1 =
1691 PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1);
1692 table->AVFSGB_FUSE_TABLE[1].m2 =
1693 PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2);
1694 table->AVFSGB_FUSE_TABLE[1].b =
1695 PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b);
1696 table->AVFSGB_FUSE_TABLE[1].m1_shift = 24;
1697 table->AVFSGB_FUSE_TABLE[1].m2_shift = 12;
1698 table->MaxVoltage = PP_HOST_TO_SMC_US(avfs_params.usMaxVoltage_0_25mv);
1699 AVFS_meanNsigma.Aconstant[0] =
1700 PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant0);
1701 AVFS_meanNsigma.Aconstant[1] =
1702 PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant1);
1703 AVFS_meanNsigma.Aconstant[2] =
1704 PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant2);
1705 AVFS_meanNsigma.DC_tol_sigma =
1706 PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_DC_tol_sigma);
1707 AVFS_meanNsigma.Platform_mean =
1708 PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_mean);
1709 AVFS_meanNsigma.PSM_Age_CompFactor =
1710 PP_HOST_TO_SMC_US(avfs_params.usPSM_Age_ComFactor);
1711 AVFS_meanNsigma.Platform_sigma =
1712 PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_sigma);
1713
1714 for (i = 0; i < sclk_table->count; i++) {
1715 AVFS_meanNsigma.Static_Voltage_Offset[i] =
1716 (uint8_t)(sclk_table->entries[i].cks_voffset * 100 / 625);
1717 AVFS_SclkOffset.Sclk_Offset[i] =
1718 PP_HOST_TO_SMC_US((uint16_t)
1719 (sclk_table->entries[i].sclk_offset) / 100);
1720 }
1721
1722 result = smu7_read_smc_sram_dword(hwmgr,
1723 SMU7_FIRMWARE_HEADER_LOCATION +
1724 offsetof(SMU75_Firmware_Header, AvfsMeanNSigma),
1725 &tmp, SMC_RAM_END);
1726 smu7_copy_bytes_to_smc(hwmgr,
1727 tmp,
1728 (uint8_t *)&AVFS_meanNsigma,
1729 sizeof(AVFS_meanNsigma_t),
1730 SMC_RAM_END);
1731
1732 result = smu7_read_smc_sram_dword(hwmgr,
1733 SMU7_FIRMWARE_HEADER_LOCATION +
1734 offsetof(SMU75_Firmware_Header, AvfsSclkOffsetTable),
1735 &tmp, SMC_RAM_END);
1736 smu7_copy_bytes_to_smc(hwmgr,
1737 tmp,
1738 (uint8_t *)&AVFS_SclkOffset,
1739 sizeof(AVFS_Sclk_Offset_t),
1740 SMC_RAM_END);
1741
1742 data->avfs_vdroop_override_setting =
1743 (avfs_params.ucEnableGB_VDROOP_TABLE_CKSON << BTCGB0_Vdroop_Enable_SHIFT) |
1744 (avfs_params.ucEnableGB_VDROOP_TABLE_CKSOFF << BTCGB1_Vdroop_Enable_SHIFT) |
1745 (avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT) |
1746 (avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT);
1747 data->apply_avfs_cks_off_voltage =
1748 (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true : false;
1749 }
1750 return result;
1751}
1752
1753static int vegam_populate_vr_config(struct pp_hwmgr *hwmgr,
1754 struct SMU75_Discrete_DpmTable *table)
1755{
1756 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
1757 struct vegam_smumgr *smu_data =
1758 (struct vegam_smumgr *)(hwmgr->smu_backend);
1759 uint16_t config;
1760
1761 config = VR_MERGED_WITH_VDDC;
1762 table->VRConfig |= (config << VRCONF_VDDGFX_SHIFT);
1763
1764 /* Set Vddc Voltage Controller */
1765 if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) {
1766 config = VR_SVI2_PLANE_1;
1767 table->VRConfig |= config;
1768 } else {
1769 PP_ASSERT_WITH_CODE(false,
1770 "VDDC should be on SVI2 control in merged mode!",
1771 );
1772 }
1773 /* Set Vddci Voltage Controller */
1774 if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) {
1775 config = VR_SVI2_PLANE_2; /* only in merged mode */
1776 table->VRConfig |= (config << VRCONF_VDDCI_SHIFT);
1777 } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) {
1778 config = VR_SMIO_PATTERN_1;
1779 table->VRConfig |= (config << VRCONF_VDDCI_SHIFT);
1780 } else {
1781 config = VR_STATIC_VOLTAGE;
1782 table->VRConfig |= (config << VRCONF_VDDCI_SHIFT);
1783 }
1784 /* Set Mvdd Voltage Controller */
1785 if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) {
1786 if (config != VR_SVI2_PLANE_2) {
1787 config = VR_SVI2_PLANE_2;
1788 table->VRConfig |= (config << VRCONF_MVDD_SHIFT);
1789 cgs_write_ind_register(hwmgr->device,
1790 CGS_IND_REG__SMC,
1791 smu_data->smu7_data.soft_regs_start +
1792 offsetof(SMU75_SoftRegisters, AllowMvddSwitch),
1793 0x1);
1794 } else {
1795 PP_ASSERT_WITH_CODE(false,
1796 "SVI2 Plane 2 is already taken, set MVDD as Static",);
1797 config = VR_STATIC_VOLTAGE;
1798 table->VRConfig = (config << VRCONF_MVDD_SHIFT);
1799 }
1800 } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) {
1801 config = VR_SMIO_PATTERN_2;
1802 table->VRConfig = (config << VRCONF_MVDD_SHIFT);
1803 cgs_write_ind_register(hwmgr->device,
1804 CGS_IND_REG__SMC,
1805 smu_data->smu7_data.soft_regs_start +
1806 offsetof(SMU75_SoftRegisters, AllowMvddSwitch),
1807 0x1);
1808 } else {
1809 config = VR_STATIC_VOLTAGE;
1810 table->VRConfig |= (config << VRCONF_MVDD_SHIFT);
1811 }
1812
1813 return 0;
1814}
1815
1816static int vegam_populate_svi_load_line(struct pp_hwmgr *hwmgr)
1817{
1818 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1819 const struct vegam_pt_defaults *defaults = smu_data->power_tune_defaults;
1820
1821 smu_data->power_tune_table.SviLoadLineEn = defaults->SviLoadLineEn;
1822 smu_data->power_tune_table.SviLoadLineVddC = defaults->SviLoadLineVddC;
1823 smu_data->power_tune_table.SviLoadLineTrimVddC = 3;
1824 smu_data->power_tune_table.SviLoadLineOffsetVddC = 0;
1825
1826 return 0;
1827}
1828
1829static int vegam_populate_tdc_limit(struct pp_hwmgr *hwmgr)
1830{
1831 uint16_t tdc_limit;
1832 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1833 struct phm_ppt_v1_information *table_info =
1834 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1835 const struct vegam_pt_defaults *defaults = smu_data->power_tune_defaults;
1836
1837 tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 128);
1838 smu_data->power_tune_table.TDC_VDDC_PkgLimit =
1839 CONVERT_FROM_HOST_TO_SMC_US(tdc_limit);
1840 smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc =
1841 defaults->TDC_VDDC_ThrottleReleaseLimitPerc;
1842 smu_data->power_tune_table.TDC_MAWt = defaults->TDC_MAWt;
1843
1844 return 0;
1845}
1846
1847static int vegam_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset)
1848{
1849 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1850 const struct vegam_pt_defaults *defaults = smu_data->power_tune_defaults;
1851 uint32_t temp;
1852
1853 if (smu7_read_smc_sram_dword(hwmgr,
1854 fuse_table_offset +
1855 offsetof(SMU75_Discrete_PmFuses, TdcWaterfallCtl),
1856 (uint32_t *)&temp, SMC_RAM_END))
1857 PP_ASSERT_WITH_CODE(false,
1858 "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!",
1859 return -EINVAL);
1860 else {
1861 smu_data->power_tune_table.TdcWaterfallCtl = defaults->TdcWaterfallCtl;
1862 smu_data->power_tune_table.LPMLTemperatureMin =
1863 (uint8_t)((temp >> 16) & 0xff);
1864 smu_data->power_tune_table.LPMLTemperatureMax =
1865 (uint8_t)((temp >> 8) & 0xff);
1866 smu_data->power_tune_table.Reserved = (uint8_t)(temp & 0xff);
1867 }
1868 return 0;
1869}
1870
1871static int vegam_populate_temperature_scaler(struct pp_hwmgr *hwmgr)
1872{
1873 int i;
1874 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1875
1876 /* Currently not used. Set all to zero. */
1877 for (i = 0; i < 16; i++)
1878 smu_data->power_tune_table.LPMLTemperatureScaler[i] = 0;
1879
1880 return 0;
1881}
1882
1883static int vegam_populate_fuzzy_fan(struct pp_hwmgr *hwmgr)
1884{
1885 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1886
1887/* TO DO move to hwmgr */
1888 if ((hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity & (1 << 15))
1889 || 0 == hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity)
1890 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity =
1891 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity;
1892
1893 smu_data->power_tune_table.FuzzyFan_PwmSetDelta = PP_HOST_TO_SMC_US(
1894 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity);
1895 return 0;
1896}
1897
1898static int vegam_populate_gnb_lpml(struct pp_hwmgr *hwmgr)
1899{
1900 int i;
1901 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1902
1903 /* Currently not used. Set all to zero. */
1904 for (i = 0; i < 16; i++)
1905 smu_data->power_tune_table.GnbLPML[i] = 0;
1906
1907 return 0;
1908}
1909
1910static int vegam_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr)
1911{
1912 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1913 struct phm_ppt_v1_information *table_info =
1914 (struct phm_ppt_v1_information *)(hwmgr->pptable);
1915 uint16_t hi_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd;
1916 uint16_t lo_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd;
1917 struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table;
1918
1919 hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256);
1920 lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256);
1921
1922 smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd =
1923 CONVERT_FROM_HOST_TO_SMC_US(hi_sidd);
1924 smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd =
1925 CONVERT_FROM_HOST_TO_SMC_US(lo_sidd);
1926
1927 return 0;
1928}
1929
1930static int vegam_populate_pm_fuses(struct pp_hwmgr *hwmgr)
1931{
1932 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
1933 uint32_t pm_fuse_table_offset;
1934
1935 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1936 PHM_PlatformCaps_PowerContainment)) {
1937 if (smu7_read_smc_sram_dword(hwmgr,
1938 SMU7_FIRMWARE_HEADER_LOCATION +
1939 offsetof(SMU75_Firmware_Header, PmFuseTable),
1940 &pm_fuse_table_offset, SMC_RAM_END))
1941 PP_ASSERT_WITH_CODE(false,
1942 "Attempt to get pm_fuse_table_offset Failed!",
1943 return -EINVAL);
1944
1945 if (vegam_populate_svi_load_line(hwmgr))
1946 PP_ASSERT_WITH_CODE(false,
1947 "Attempt to populate SviLoadLine Failed!",
1948 return -EINVAL);
1949
1950 if (vegam_populate_tdc_limit(hwmgr))
1951 PP_ASSERT_WITH_CODE(false,
1952 "Attempt to populate TDCLimit Failed!", return -EINVAL);
1953
1954 if (vegam_populate_dw8(hwmgr, pm_fuse_table_offset))
1955 PP_ASSERT_WITH_CODE(false,
1956 "Attempt to populate TdcWaterfallCtl, "
1957 "LPMLTemperature Min and Max Failed!",
1958 return -EINVAL);
1959
1960 if (0 != vegam_populate_temperature_scaler(hwmgr))
1961 PP_ASSERT_WITH_CODE(false,
1962 "Attempt to populate LPMLTemperatureScaler Failed!",
1963 return -EINVAL);
1964
1965 if (vegam_populate_fuzzy_fan(hwmgr))
1966 PP_ASSERT_WITH_CODE(false,
1967 "Attempt to populate Fuzzy Fan Control parameters Failed!",
1968 return -EINVAL);
1969
1970 if (vegam_populate_gnb_lpml(hwmgr))
1971 PP_ASSERT_WITH_CODE(false,
1972 "Attempt to populate GnbLPML Failed!",
1973 return -EINVAL);
1974
1975 if (vegam_populate_bapm_vddc_base_leakage_sidd(hwmgr))
1976 PP_ASSERT_WITH_CODE(false,
1977 "Attempt to populate BapmVddCBaseLeakage Hi and Lo "
1978 "Sidd Failed!", return -EINVAL);
1979
1980 if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset,
1981 (uint8_t *)&smu_data->power_tune_table,
1982 (sizeof(struct SMU75_Discrete_PmFuses) - PMFUSES_AVFSSIZE),
1983 SMC_RAM_END))
1984 PP_ASSERT_WITH_CODE(false,
1985 "Attempt to download PmFuseTable Failed!",
1986 return -EINVAL);
1987 }
1988 return 0;
1989}
1990
1991static int vegam_enable_reconfig_cus(struct pp_hwmgr *hwmgr)
1992{
1993 struct amdgpu_device *adev = hwmgr->adev;
1994
1995 smum_send_msg_to_smc_with_parameter(hwmgr,
1996 PPSMC_MSG_EnableModeSwitchRLCNotification,
1997 adev->gfx.cu_info.number);
1998
1999 return 0;
2000}
2001
2002static int vegam_init_smc_table(struct pp_hwmgr *hwmgr)
2003{
2004 int result;
2005 struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend);
2006 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend);
2007
2008 struct phm_ppt_v1_information *table_info =
2009 (struct phm_ppt_v1_information *)(hwmgr->pptable);
2010 struct SMU75_Discrete_DpmTable *table = &(smu_data->smc_state_table);
2011 uint8_t i;
2012 struct pp_atomctrl_gpio_pin_assignment gpio_pin;
2013 struct phm_ppt_v1_gpio_table *gpio_table =
2014 (struct phm_ppt_v1_gpio_table *)table_info->gpio_table;
2015 pp_atomctrl_clock_dividers_vi dividers;
2016
2017 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
2018 PHM_PlatformCaps_AutomaticDCTransition);
2019
2020 vegam_initialize_power_tune_defaults(hwmgr);
2021
2022 if (SMU7_VOLTAGE_CONTROL_NONE != hw_data->voltage_control)
2023 vegam_populate_smc_voltage_tables(hwmgr, table);
2024
2025 table->SystemFlags = 0;
2026 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2027 PHM_PlatformCaps_AutomaticDCTransition))
2028 table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
2029
2030 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2031 PHM_PlatformCaps_StepVddc))
2032 table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
2033
2034 if (hw_data->is_memory_gddr5)
2035 table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
2036
2037 if (hw_data->ulv_supported && table_info->us_ulv_voltage_offset) {
2038 result = vegam_populate_ulv_state(hwmgr, table);
2039 PP_ASSERT_WITH_CODE(!result,
2040 "Failed to initialize ULV state!", return result);
2041 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
2042 ixCG_ULV_PARAMETER, SMU7_CGULVPARAMETER_DFLT);
2043 }
2044
2045 result = vegam_populate_smc_link_level(hwmgr, table);
2046 PP_ASSERT_WITH_CODE(!result,
2047 "Failed to initialize Link Level!", return result);
2048
2049 result = vegam_populate_all_graphic_levels(hwmgr);
2050 PP_ASSERT_WITH_CODE(!result,
2051 "Failed to initialize Graphics Level!", return result);
2052
2053 result = vegam_populate_all_memory_levels(hwmgr);
2054 PP_ASSERT_WITH_CODE(!result,
2055 "Failed to initialize Memory Level!", return result);
2056
2057 result = vegam_populate_smc_acpi_level(hwmgr, table);
2058 PP_ASSERT_WITH_CODE(!result,
2059 "Failed to initialize ACPI Level!", return result);
2060
2061 result = vegam_populate_smc_vce_level(hwmgr, table);
2062 PP_ASSERT_WITH_CODE(!result,
2063 "Failed to initialize VCE Level!", return result);
2064
2065 result = vegam_populate_smc_samu_level(hwmgr, table);
2066 PP_ASSERT_WITH_CODE(!result,
2067 "Failed to initialize SAMU Level!", return result);
2068
2069 /* Since only the initial state is completely set up at this point
2070 * (the other states are just copies of the boot state) we only
2071 * need to populate the ARB settings for the initial state.
2072 */
2073 result = vegam_program_memory_timing_parameters(hwmgr);
2074 PP_ASSERT_WITH_CODE(!result,
2075 "Failed to Write ARB settings for the initial state.", return result);
2076
2077 result = vegam_populate_smc_uvd_level(hwmgr, table);
2078 PP_ASSERT_WITH_CODE(!result,
2079 "Failed to initialize UVD Level!", return result);
2080
2081 result = vegam_populate_smc_boot_level(hwmgr, table);
2082 PP_ASSERT_WITH_CODE(!result,
2083 "Failed to initialize Boot Level!", return result);
2084
2085 result = vegam_populate_smc_initial_state(hwmgr);
2086 PP_ASSERT_WITH_CODE(!result,
2087 "Failed to initialize Boot State!", return result);
2088
2089 result = vegam_populate_bapm_parameters_in_dpm_table(hwmgr);
2090 PP_ASSERT_WITH_CODE(!result,
2091 "Failed to populate BAPM Parameters!", return result);
2092
2093 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2094 PHM_PlatformCaps_ClockStretcher)) {
2095 result = vegam_populate_clock_stretcher_data_table(hwmgr);
2096 PP_ASSERT_WITH_CODE(!result,
2097 "Failed to populate Clock Stretcher Data Table!",
2098 return result);
2099 }
2100
2101 result = vegam_populate_avfs_parameters(hwmgr);
2102 PP_ASSERT_WITH_CODE(!result,
2103 "Failed to populate AVFS Parameters!", return result;);
2104
2105 table->CurrSclkPllRange = 0xff;
2106 table->GraphicsVoltageChangeEnable = 1;
2107 table->GraphicsThermThrottleEnable = 1;
2108 table->GraphicsInterval = 1;
2109 table->VoltageInterval = 1;
2110 table->ThermalInterval = 1;
2111 table->TemperatureLimitHigh =
2112 table_info->cac_dtp_table->usTargetOperatingTemp *
2113 SMU7_Q88_FORMAT_CONVERSION_UNIT;
2114 table->TemperatureLimitLow =
2115 (table_info->cac_dtp_table->usTargetOperatingTemp - 1) *
2116 SMU7_Q88_FORMAT_CONVERSION_UNIT;
2117 table->MemoryVoltageChangeEnable = 1;
2118 table->MemoryInterval = 1;
2119 table->VoltageResponseTime = 0;
2120 table->PhaseResponseTime = 0;
2121 table->MemoryThermThrottleEnable = 1;
2122
2123 PP_ASSERT_WITH_CODE(hw_data->dpm_table.pcie_speed_table.count >= 1,
2124 "There must be 1 or more PCIE levels defined in PPTable.",
2125 return -EINVAL);
2126 table->PCIeBootLinkLevel =
2127 hw_data->dpm_table.pcie_speed_table.count;
2128 table->PCIeGenInterval = 1;
2129 table->VRConfig = 0;
2130
2131 result = vegam_populate_vr_config(hwmgr, table);
2132 PP_ASSERT_WITH_CODE(!result,
2133 "Failed to populate VRConfig setting!", return result);
2134
2135 table->ThermGpio = 17;
2136 table->SclkStepSize = 0x4000;
2137
2138 if (atomctrl_get_pp_assign_pin(hwmgr,
2139 VDDC_VRHOT_GPIO_PINID, &gpio_pin)) {
2140 table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift;
2141 if (gpio_table)
2142 table->VRHotLevel =
2143 table_info->gpio_table->vrhot_triggered_sclk_dpm_index;
2144 } else {
2145 table->VRHotGpio = SMU7_UNUSED_GPIO_PIN;
2146 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2147 PHM_PlatformCaps_RegulatorHot);
2148 }
2149
2150 if (atomctrl_get_pp_assign_pin(hwmgr,
2151 PP_AC_DC_SWITCH_GPIO_PINID, &gpio_pin)) {
2152 table->AcDcGpio = gpio_pin.uc_gpio_pin_bit_shift;
2153 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2154 PHM_PlatformCaps_AutomaticDCTransition) &&
2155 !smum_send_msg_to_smc(hwmgr, PPSMC_MSG_UseNewGPIOScheme))
2156 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
2157 PHM_PlatformCaps_SMCtoPPLIBAcdcGpioScheme);
2158 } else {
2159 table->AcDcGpio = SMU7_UNUSED_GPIO_PIN;
2160 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2161 PHM_PlatformCaps_AutomaticDCTransition);
2162 }
2163
2164 /* Thermal Output GPIO */
2165 if (atomctrl_get_pp_assign_pin(hwmgr,
2166 THERMAL_INT_OUTPUT_GPIO_PINID, &gpio_pin)) {
2167 table->ThermOutGpio = gpio_pin.uc_gpio_pin_bit_shift;
2168
2169 /* For porlarity read GPIOPAD_A with assigned Gpio pin
2170 * since VBIOS will program this register to set 'inactive state',
2171 * driver can then determine 'active state' from this and
2172 * program SMU with correct polarity
2173 */
2174 table->ThermOutPolarity =
2175 (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A) &
2176 (1 << gpio_pin.uc_gpio_pin_bit_shift))) ? 1:0;
2177 table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY;
2178
2179 /* if required, combine VRHot/PCC with thermal out GPIO */
2180 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2181 PHM_PlatformCaps_RegulatorHot) &&
2182 phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2183 PHM_PlatformCaps_CombinePCCWithThermalSignal))
2184 table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT;
2185 } else {
2186 table->ThermOutGpio = 17;
2187 table->ThermOutPolarity = 1;
2188 table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE;
2189 }
2190
2191 /* Populate BIF_SCLK levels into SMC DPM table */
2192 for (i = 0; i <= hw_data->dpm_table.pcie_speed_table.count; i++) {
2193 result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
2194 smu_data->bif_sclk_table[i], &dividers);
2195 PP_ASSERT_WITH_CODE(!result,
2196 "Can not find DFS divide id for Sclk",
2197 return result);
2198
2199 if (i == 0)
2200 table->Ulv.BifSclkDfs =
2201 PP_HOST_TO_SMC_US((uint16_t)(dividers.pll_post_divider));
2202 else
2203 table->LinkLevel[i - 1].BifSclkDfs =
2204 PP_HOST_TO_SMC_US((uint16_t)(dividers.pll_post_divider));
2205 }
2206
2207 for (i = 0; i < SMU75_MAX_ENTRIES_SMIO; i++)
2208 table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]);
2209
2210 CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags);
2211 CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig);
2212 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1);
2213 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2);
2214 CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize);
2215 CONVERT_FROM_HOST_TO_SMC_UL(table->CurrSclkPllRange);
2216 CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh);
2217 CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow);
2218 CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime);
2219 CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime);
2220
2221 /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */
2222 result = smu7_copy_bytes_to_smc(hwmgr,
2223 smu_data->smu7_data.dpm_table_start +
2224 offsetof(SMU75_Discrete_DpmTable, SystemFlags),
2225 (uint8_t *)&(table->SystemFlags),
2226 sizeof(SMU75_Discrete_DpmTable) - 3 * sizeof(SMU75_PIDController),
2227 SMC_RAM_END);
2228 PP_ASSERT_WITH_CODE(!result,
2229 "Failed to upload dpm data to SMC memory!", return result);
2230
2231 result = vegam_populate_pm_fuses(hwmgr);
2232 PP_ASSERT_WITH_CODE(!result,
2233 "Failed to populate PM fuses to SMC memory!", return result);
2234
2235 result = vegam_enable_reconfig_cus(hwmgr);
2236 PP_ASSERT_WITH_CODE(!result,
2237 "Failed to enable reconfigurable CUs!", return result);
2238
2239 return 0;
2240}
2241
2242static uint32_t vegam_get_offsetof(uint32_t type, uint32_t member)
2243{
2244 switch (type) {
2245 case SMU_SoftRegisters:
2246 switch (member) {
2247 case HandshakeDisables:
2248 return offsetof(SMU75_SoftRegisters, HandshakeDisables);
2249 case VoltageChangeTimeout:
2250 return offsetof(SMU75_SoftRegisters, VoltageChangeTimeout);
2251 case AverageGraphicsActivity:
2252 return offsetof(SMU75_SoftRegisters, AverageGraphicsActivity);
2253 case PreVBlankGap:
2254 return offsetof(SMU75_SoftRegisters, PreVBlankGap);
2255 case VBlankTimeout:
2256 return offsetof(SMU75_SoftRegisters, VBlankTimeout);
2257 case UcodeLoadStatus:
2258 return offsetof(SMU75_SoftRegisters, UcodeLoadStatus);
2259 case DRAM_LOG_ADDR_H:
2260 return offsetof(SMU75_SoftRegisters, DRAM_LOG_ADDR_H);
2261 case DRAM_LOG_ADDR_L:
2262 return offsetof(SMU75_SoftRegisters, DRAM_LOG_ADDR_L);
2263 case DRAM_LOG_PHY_ADDR_H:
2264 return offsetof(SMU75_SoftRegisters, DRAM_LOG_PHY_ADDR_H);
2265 case DRAM_LOG_PHY_ADDR_L:
2266 return offsetof(SMU75_SoftRegisters, DRAM_LOG_PHY_ADDR_L);
2267 case DRAM_LOG_BUFF_SIZE:
2268 return offsetof(SMU75_SoftRegisters, DRAM_LOG_BUFF_SIZE);
2269 }
2270 case SMU_Discrete_DpmTable:
2271 switch (member) {
2272 case UvdBootLevel:
2273 return offsetof(SMU75_Discrete_DpmTable, UvdBootLevel);
2274 case VceBootLevel:
2275 return offsetof(SMU75_Discrete_DpmTable, VceBootLevel);
2276 case SamuBootLevel:
2277 return offsetof(SMU75_Discrete_DpmTable, SamuBootLevel);
2278 case LowSclkInterruptThreshold:
2279 return offsetof(SMU75_Discrete_DpmTable, LowSclkInterruptThreshold);
2280 }
2281 }
2282 pr_warn("can't get the offset of type %x member %x\n", type, member);
2283 return 0;
2284}
2285
2286static int vegam_program_mem_timing_parameters(struct pp_hwmgr *hwmgr)
2287{
2288 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2289
2290 if (data->need_update_smu7_dpm_table &
2291 (DPMTABLE_OD_UPDATE_SCLK +
2292 DPMTABLE_UPDATE_SCLK +
2293 DPMTABLE_UPDATE_MCLK))
2294 return vegam_program_memory_timing_parameters(hwmgr);
2295
2296 return 0;
2297}
2298
2299static int vegam_update_sclk_threshold(struct pp_hwmgr *hwmgr)
2300{
2301 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2302 struct vegam_smumgr *smu_data =
2303 (struct vegam_smumgr *)(hwmgr->smu_backend);
2304 int result = 0;
2305 uint32_t low_sclk_interrupt_threshold = 0;
2306
2307 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2308 PHM_PlatformCaps_SclkThrottleLowNotification)
2309 && (data->low_sclk_interrupt_threshold != 0)) {
2310 low_sclk_interrupt_threshold =
2311 data->low_sclk_interrupt_threshold;
2312
2313 CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold);
2314
2315 result = smu7_copy_bytes_to_smc(
2316 hwmgr,
2317 smu_data->smu7_data.dpm_table_start +
2318 offsetof(SMU75_Discrete_DpmTable,
2319 LowSclkInterruptThreshold),
2320 (uint8_t *)&low_sclk_interrupt_threshold,
2321 sizeof(uint32_t),
2322 SMC_RAM_END);
2323 }
2324 PP_ASSERT_WITH_CODE((result == 0),
2325 "Failed to update SCLK threshold!", return result);
2326
2327 result = vegam_program_mem_timing_parameters(hwmgr);
2328 PP_ASSERT_WITH_CODE((result == 0),
2329 "Failed to program memory timing parameters!",
2330 );
2331
2332 return result;
2333}
2334
2335int vegam_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
2336{
2337 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
2338 int ret;
2339
2340 if (!hwmgr->avfs_supported)
2341 return 0;
2342
2343 ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs);
2344 if (!ret) {
2345 if (data->apply_avfs_cks_off_voltage)
2346 ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ApplyAvfsCksOffVoltage);
2347 }
2348
2349 return ret;
2350}
2351
2352static int vegam_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
2353{
2354 PP_ASSERT_WITH_CODE(hwmgr->thermal_controller.fanInfo.bNoFan,
2355 "VBIOS fan info is not correct!",
2356 );
2357 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2358 PHM_PlatformCaps_MicrocodeFanControl);
2359 return 0;
2360}
2361
2362const struct pp_smumgr_func vegam_smu_funcs = {
2363 .smu_init = vegam_smu_init,
2364 .smu_fini = smu7_smu_fini,
2365 .start_smu = vegam_start_smu,
2366 .check_fw_load_finish = smu7_check_fw_load_finish,
2367 .request_smu_load_fw = smu7_reload_firmware,
2368 .request_smu_load_specific_fw = NULL,
2369 .send_msg_to_smc = smu7_send_msg_to_smc,
2370 .send_msg_to_smc_with_parameter = smu7_send_msg_to_smc_with_parameter,
2371 .process_firmware_header = vegam_process_firmware_header,
2372 .is_dpm_running = vegam_is_dpm_running,
2373 .get_mac_definition = vegam_get_mac_definition,
2374 .update_smc_table = vegam_update_smc_table,
2375 .init_smc_table = vegam_init_smc_table,
2376 .get_offsetof = vegam_get_offsetof,
2377 .populate_all_graphic_levels = vegam_populate_all_graphic_levels,
2378 .populate_all_memory_levels = vegam_populate_all_memory_levels,
2379 .update_sclk_threshold = vegam_update_sclk_threshold,
2380 .is_hw_avfs_present = vegam_is_hw_avfs_present,
2381 .thermal_avfs_enable = vegam_thermal_avfs_enable,
2382 .thermal_setup_fan_table = vegam_thermal_setup_fan_table,
2383};
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.h
new file mode 100644
index 000000000000..2b6558238500
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.h
@@ -0,0 +1,75 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#ifndef _VEGAM_SMUMANAGER_H
25#define _VEGAM_SMUMANAGER_H
26
27
28#include <pp_endian.h>
29#include "smu75_discrete.h"
30#include "smu7_smumgr.h"
31
32#define SMC_RAM_END 0x40000
33
34#define DPMTuning_Uphyst_Shift 0
35#define DPMTuning_Downhyst_Shift 8
36#define DPMTuning_Activity_Shift 16
37
38#define GraphicsDPMTuning_VEGAM 0x001e6400
39#define MemoryDPMTuning_VEGAM 0x000f3c0a
40#define SclkDPMTuning_VEGAM 0x002d000a
41#define MclkDPMTuning_VEGAM 0x001f100a
42
43
44struct vegam_pt_defaults {
45 uint8_t SviLoadLineEn;
46 uint8_t SviLoadLineVddC;
47 uint8_t TDC_VDDC_ThrottleReleaseLimitPerc;
48 uint8_t TDC_MAWt;
49 uint8_t TdcWaterfallCtl;
50 uint8_t DTEAmbientTempBase;
51
52 uint32_t DisplayCac;
53 uint32_t BAPM_TEMP_GRADIENT;
54 uint16_t BAPMTI_R[SMU75_DTE_ITERATIONS * SMU75_DTE_SOURCES * SMU75_DTE_SINKS];
55 uint16_t BAPMTI_RC[SMU75_DTE_ITERATIONS * SMU75_DTE_SOURCES * SMU75_DTE_SINKS];
56};
57
58struct vegam_range_table {
59 uint32_t trans_lower_frequency; /* in 10khz */
60 uint32_t trans_upper_frequency;
61};
62
63struct vegam_smumgr {
64 struct smu7_smumgr smu7_data;
65 uint8_t protected_mode;
66 SMU75_Discrete_DpmTable smc_state_table;
67 struct SMU75_Discrete_Ulv ulv_setting;
68 struct SMU75_Discrete_PmFuses power_tune_table;
69 struct vegam_range_table range_table[NUM_SCLK_RANGE];
70 const struct vegam_pt_defaults *power_tune_defaults;
71 uint32_t bif_sclk_table[SMU75_MAX_LEVELS_LINK];
72};
73
74
75#endif
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 831b73392d82..036dff8a1f33 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -799,7 +799,7 @@ static int ast_get_modes(struct drm_connector *connector)
799 return 0; 799 return 0;
800} 800}
801 801
802static int ast_mode_valid(struct drm_connector *connector, 802static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
803 struct drm_display_mode *mode) 803 struct drm_display_mode *mode)
804{ 804{
805 struct ast_private *ast = connector->dev->dev_private; 805 struct ast_private *ast = connector->dev->dev_private;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index ab32d5b268d2..60c937f42114 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -299,7 +299,6 @@ struct atmel_hlcdc_layer {
299struct atmel_hlcdc_plane { 299struct atmel_hlcdc_plane {
300 struct drm_plane base; 300 struct drm_plane base;
301 struct atmel_hlcdc_layer layer; 301 struct atmel_hlcdc_layer layer;
302 struct atmel_hlcdc_plane_properties *properties;
303}; 302};
304 303
305static inline struct atmel_hlcdc_plane * 304static inline struct atmel_hlcdc_plane *
@@ -346,18 +345,6 @@ struct atmel_hlcdc_dc_desc {
346}; 345};
347 346
348/** 347/**
349 * Atmel HLCDC Plane properties.
350 *
351 * This structure stores plane property definitions.
352 *
353 * @alpha: alpha blending (or transparency) property
354 * @rotation: rotation property
355 */
356struct atmel_hlcdc_plane_properties {
357 struct drm_property *alpha;
358};
359
360/**
361 * Atmel HLCDC Display Controller. 348 * Atmel HLCDC Display Controller.
362 * 349 *
363 * @desc: HLCDC Display Controller description 350 * @desc: HLCDC Display Controller description
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index e18800ed7cd1..73c875db45f4 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -31,7 +31,6 @@
31 * @src_y: y buffer position 31 * @src_y: y buffer position
32 * @src_w: buffer width 32 * @src_w: buffer width
33 * @src_h: buffer height 33 * @src_h: buffer height
34 * @alpha: alpha blending of the plane
35 * @disc_x: x discard position 34 * @disc_x: x discard position
36 * @disc_y: y discard position 35 * @disc_y: y discard position
37 * @disc_w: discard width 36 * @disc_w: discard width
@@ -54,8 +53,6 @@ struct atmel_hlcdc_plane_state {
54 uint32_t src_w; 53 uint32_t src_w;
55 uint32_t src_h; 54 uint32_t src_h;
56 55
57 u8 alpha;
58
59 int disc_x; 56 int disc_x;
60 int disc_y; 57 int disc_y;
61 int disc_w; 58 int disc_w;
@@ -385,7 +382,7 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
385 cfg |= ATMEL_HLCDC_LAYER_LAEN; 382 cfg |= ATMEL_HLCDC_LAYER_LAEN;
386 else 383 else
387 cfg |= ATMEL_HLCDC_LAYER_GAEN | 384 cfg |= ATMEL_HLCDC_LAYER_GAEN |
388 ATMEL_HLCDC_LAYER_GA(state->alpha); 385 ATMEL_HLCDC_LAYER_GA(state->base.alpha >> 8);
389 } 386 }
390 387
391 if (state->disc_h && state->disc_w) 388 if (state->disc_h && state->disc_w)
@@ -553,7 +550,7 @@ atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state)
553 550
554 if (!ovl_s->fb || 551 if (!ovl_s->fb ||
555 ovl_s->fb->format->has_alpha || 552 ovl_s->fb->format->has_alpha ||
556 ovl_state->alpha != 255) 553 ovl_s->alpha != DRM_BLEND_ALPHA_OPAQUE)
557 continue; 554 continue;
558 555
559 /* TODO: implement a smarter hidden area detection */ 556 /* TODO: implement a smarter hidden area detection */
@@ -829,51 +826,18 @@ static void atmel_hlcdc_plane_destroy(struct drm_plane *p)
829 drm_plane_cleanup(p); 826 drm_plane_cleanup(p);
830} 827}
831 828
832static int atmel_hlcdc_plane_atomic_set_property(struct drm_plane *p, 829static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
833 struct drm_plane_state *s,
834 struct drm_property *property,
835 uint64_t val)
836{
837 struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
838 struct atmel_hlcdc_plane_properties *props = plane->properties;
839 struct atmel_hlcdc_plane_state *state =
840 drm_plane_state_to_atmel_hlcdc_plane_state(s);
841
842 if (property == props->alpha)
843 state->alpha = val;
844 else
845 return -EINVAL;
846
847 return 0;
848}
849
850static int atmel_hlcdc_plane_atomic_get_property(struct drm_plane *p,
851 const struct drm_plane_state *s,
852 struct drm_property *property,
853 uint64_t *val)
854{
855 struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
856 struct atmel_hlcdc_plane_properties *props = plane->properties;
857 const struct atmel_hlcdc_plane_state *state =
858 container_of(s, const struct atmel_hlcdc_plane_state, base);
859
860 if (property == props->alpha)
861 *val = state->alpha;
862 else
863 return -EINVAL;
864
865 return 0;
866}
867
868static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane,
869 struct atmel_hlcdc_plane_properties *props)
870{ 830{
871 const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; 831 const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
872 832
873 if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER || 833 if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
874 desc->type == ATMEL_HLCDC_CURSOR_LAYER) 834 desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
875 drm_object_attach_property(&plane->base.base, 835 int ret;
876 props->alpha, 255); 836
837 ret = drm_plane_create_alpha_property(&plane->base);
838 if (ret)
839 return ret;
840 }
877 841
878 if (desc->layout.xstride && desc->layout.pstride) { 842 if (desc->layout.xstride && desc->layout.pstride) {
879 int ret; 843 int ret;
@@ -988,8 +952,8 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
988 return; 952 return;
989 } 953 }
990 954
991 state->alpha = 255;
992 p->state = &state->base; 955 p->state = &state->base;
956 p->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
993 p->state->plane = p; 957 p->state->plane = p;
994 } 958 }
995} 959}
@@ -1042,13 +1006,10 @@ static const struct drm_plane_funcs layer_plane_funcs = {
1042 .reset = atmel_hlcdc_plane_reset, 1006 .reset = atmel_hlcdc_plane_reset,
1043 .atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state, 1007 .atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state,
1044 .atomic_destroy_state = atmel_hlcdc_plane_atomic_destroy_state, 1008 .atomic_destroy_state = atmel_hlcdc_plane_atomic_destroy_state,
1045 .atomic_set_property = atmel_hlcdc_plane_atomic_set_property,
1046 .atomic_get_property = atmel_hlcdc_plane_atomic_get_property,
1047}; 1009};
1048 1010
1049static int atmel_hlcdc_plane_create(struct drm_device *dev, 1011static int atmel_hlcdc_plane_create(struct drm_device *dev,
1050 const struct atmel_hlcdc_layer_desc *desc, 1012 const struct atmel_hlcdc_layer_desc *desc)
1051 struct atmel_hlcdc_plane_properties *props)
1052{ 1013{
1053 struct atmel_hlcdc_dc *dc = dev->dev_private; 1014 struct atmel_hlcdc_dc *dc = dev->dev_private;
1054 struct atmel_hlcdc_plane *plane; 1015 struct atmel_hlcdc_plane *plane;
@@ -1060,7 +1021,6 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
1060 return -ENOMEM; 1021 return -ENOMEM;
1061 1022
1062 atmel_hlcdc_layer_init(&plane->layer, desc, dc->hlcdc->regmap); 1023 atmel_hlcdc_layer_init(&plane->layer, desc, dc->hlcdc->regmap);
1063 plane->properties = props;
1064 1024
1065 if (desc->type == ATMEL_HLCDC_BASE_LAYER) 1025 if (desc->type == ATMEL_HLCDC_BASE_LAYER)
1066 type = DRM_PLANE_TYPE_PRIMARY; 1026 type = DRM_PLANE_TYPE_PRIMARY;
@@ -1081,7 +1041,7 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
1081 &atmel_hlcdc_layer_plane_helper_funcs); 1041 &atmel_hlcdc_layer_plane_helper_funcs);
1082 1042
1083 /* Set default property values*/ 1043 /* Set default property values*/
1084 ret = atmel_hlcdc_plane_init_properties(plane, props); 1044 ret = atmel_hlcdc_plane_init_properties(plane);
1085 if (ret) 1045 if (ret)
1086 return ret; 1046 return ret;
1087 1047
@@ -1090,34 +1050,13 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
1090 return 0; 1050 return 0;
1091} 1051}
1092 1052
1093static struct atmel_hlcdc_plane_properties *
1094atmel_hlcdc_plane_create_properties(struct drm_device *dev)
1095{
1096 struct atmel_hlcdc_plane_properties *props;
1097
1098 props = devm_kzalloc(dev->dev, sizeof(*props), GFP_KERNEL);
1099 if (!props)
1100 return ERR_PTR(-ENOMEM);
1101
1102 props->alpha = drm_property_create_range(dev, 0, "alpha", 0, 255);
1103 if (!props->alpha)
1104 return ERR_PTR(-ENOMEM);
1105
1106 return props;
1107}
1108
1109int atmel_hlcdc_create_planes(struct drm_device *dev) 1053int atmel_hlcdc_create_planes(struct drm_device *dev)
1110{ 1054{
1111 struct atmel_hlcdc_dc *dc = dev->dev_private; 1055 struct atmel_hlcdc_dc *dc = dev->dev_private;
1112 struct atmel_hlcdc_plane_properties *props;
1113 const struct atmel_hlcdc_layer_desc *descs = dc->desc->layers; 1056 const struct atmel_hlcdc_layer_desc *descs = dc->desc->layers;
1114 int nlayers = dc->desc->nlayers; 1057 int nlayers = dc->desc->nlayers;
1115 int i, ret; 1058 int i, ret;
1116 1059
1117 props = atmel_hlcdc_plane_create_properties(dev);
1118 if (IS_ERR(props))
1119 return PTR_ERR(props);
1120
1121 dc->dscrpool = dmam_pool_create("atmel-hlcdc-dscr", dev->dev, 1060 dc->dscrpool = dmam_pool_create("atmel-hlcdc-dscr", dev->dev,
1122 sizeof(struct atmel_hlcdc_dma_channel_dscr), 1061 sizeof(struct atmel_hlcdc_dma_channel_dscr),
1123 sizeof(u64), 0); 1062 sizeof(u64), 0);
@@ -1130,7 +1069,7 @@ int atmel_hlcdc_create_planes(struct drm_device *dev)
1130 descs[i].type != ATMEL_HLCDC_CURSOR_LAYER) 1069 descs[i].type != ATMEL_HLCDC_CURSOR_LAYER)
1131 continue; 1070 continue;
1132 1071
1133 ret = atmel_hlcdc_plane_create(dev, &descs[i], props); 1072 ret = atmel_hlcdc_plane_create(dev, &descs[i]);
1134 if (ret) 1073 if (ret)
1135 return ret; 1074 return ret;
1136 } 1075 }
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index a24a18fbd65a..233980a78591 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -188,7 +188,7 @@ static int bochs_connector_get_modes(struct drm_connector *connector)
188 return count; 188 return count;
189} 189}
190 190
191static int bochs_connector_mode_valid(struct drm_connector *connector, 191static enum drm_mode_status bochs_connector_mode_valid(struct drm_connector *connector,
192 struct drm_display_mode *mode) 192 struct drm_display_mode *mode)
193{ 193{
194 struct bochs_device *bochs = 194 struct bochs_device *bochs =
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 684ac626ac53..fa2c7997e2fd 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -25,6 +25,16 @@ config DRM_ANALOGIX_ANX78XX
25 the HDMI output of an application processor to MyDP 25 the HDMI output of an application processor to MyDP
26 or DisplayPort. 26 or DisplayPort.
27 27
28config DRM_CDNS_DSI
29 tristate "Cadence DPI/DSI bridge"
30 select DRM_KMS_HELPER
31 select DRM_MIPI_DSI
32 select DRM_PANEL_BRIDGE
33 depends on OF
34 help
35 Support Cadence DPI to DSI bridge. This is an internal
36 bridge and is meant to be directly embedded in a SoC.
37
28config DRM_DUMB_VGA_DAC 38config DRM_DUMB_VGA_DAC
29 tristate "Dumb VGA DAC Bridge support" 39 tristate "Dumb VGA DAC Bridge support"
30 depends on OF 40 depends on OF
@@ -94,6 +104,12 @@ config DRM_SII9234
94 It is an I2C driver, that detects connection of MHL bridge 104 It is an I2C driver, that detects connection of MHL bridge
95 and starts encapsulation of HDMI signal. 105 and starts encapsulation of HDMI signal.
96 106
107config DRM_THINE_THC63LVD1024
108 tristate "Thine THC63LVD1024 LVDS decoder bridge"
109 depends on OF
110 ---help---
111 Thine THC63LVD1024 LVDS/parallel converter driver.
112
97config DRM_TOSHIBA_TC358767 113config DRM_TOSHIBA_TC358767
98 tristate "Toshiba TC358767 eDP bridge" 114 tristate "Toshiba TC358767 eDP bridge"
99 depends on OF 115 depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 373eb28f31ed..35f88d48ec20 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,5 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o 2obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
3obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
3obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o 4obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
4obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o 5obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o
5obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o 6obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
@@ -8,6 +9,7 @@ obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
8obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o 9obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
9obj-$(CONFIG_DRM_SII902X) += sii902x.o 10obj-$(CONFIG_DRM_SII902X) += sii902x.o
10obj-$(CONFIG_DRM_SII9234) += sii9234.o 11obj-$(CONFIG_DRM_SII9234) += sii9234.o
12obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o
11obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o 13obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
12obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ 14obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
13obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ 15obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
diff --git a/drivers/gpu/drm/bridge/adv7511/Kconfig b/drivers/gpu/drm/bridge/adv7511/Kconfig
index 592b9d2ec034..944e440c4fde 100644
--- a/drivers/gpu/drm/bridge/adv7511/Kconfig
+++ b/drivers/gpu/drm/bridge/adv7511/Kconfig
@@ -1,5 +1,5 @@
1config DRM_I2C_ADV7511 1config DRM_I2C_ADV7511
2 tristate "AV7511 encoder" 2 tristate "ADV7511 encoder"
3 depends on OF 3 depends on OF
4 select DRM_KMS_HELPER 4 select DRM_KMS_HELPER
5 select REGMAP_I2C 5 select REGMAP_I2C
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index d034b2cb5eee..73d8ccb97742 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -93,6 +93,11 @@
93#define ADV7511_REG_CHIP_ID_HIGH 0xf5 93#define ADV7511_REG_CHIP_ID_HIGH 0xf5
94#define ADV7511_REG_CHIP_ID_LOW 0xf6 94#define ADV7511_REG_CHIP_ID_LOW 0xf6
95 95
96/* Hardware defined default addresses for I2C register maps */
97#define ADV7511_CEC_I2C_ADDR_DEFAULT 0x3c
98#define ADV7511_EDID_I2C_ADDR_DEFAULT 0x3f
99#define ADV7511_PACKET_I2C_ADDR_DEFAULT 0x38
100
96#define ADV7511_CSC_ENABLE BIT(7) 101#define ADV7511_CSC_ENABLE BIT(7)
97#define ADV7511_CSC_UPDATE_MODE BIT(5) 102#define ADV7511_CSC_UPDATE_MODE BIT(5)
98 103
@@ -321,6 +326,7 @@ enum adv7511_type {
321struct adv7511 { 326struct adv7511 {
322 struct i2c_client *i2c_main; 327 struct i2c_client *i2c_main;
323 struct i2c_client *i2c_edid; 328 struct i2c_client *i2c_edid;
329 struct i2c_client *i2c_packet;
324 struct i2c_client *i2c_cec; 330 struct i2c_client *i2c_cec;
325 331
326 struct regmap *regmap; 332 struct regmap *regmap;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index efa29db5fc2b..73021b388e12 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -586,7 +586,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
586 /* Reading the EDID only works if the device is powered */ 586 /* Reading the EDID only works if the device is powered */
587 if (!adv7511->powered) { 587 if (!adv7511->powered) {
588 unsigned int edid_i2c_addr = 588 unsigned int edid_i2c_addr =
589 (adv7511->i2c_main->addr << 1) + 4; 589 (adv7511->i2c_edid->addr << 1);
590 590
591 __adv7511_power_on(adv7511); 591 __adv7511_power_on(adv7511);
592 592
@@ -654,7 +654,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
654 return status; 654 return status;
655} 655}
656 656
657static int adv7511_mode_valid(struct adv7511 *adv7511, 657static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511,
658 struct drm_display_mode *mode) 658 struct drm_display_mode *mode)
659{ 659{
660 if (mode->clock > 165000) 660 if (mode->clock > 165000)
@@ -969,10 +969,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
969{ 969{
970 int ret; 970 int ret;
971 971
972 adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter, 972 adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
973 adv->i2c_main->addr - 1); 973 ADV7511_CEC_I2C_ADDR_DEFAULT);
974 if (!adv->i2c_cec) 974 if (!adv->i2c_cec)
975 return -ENOMEM; 975 return -EINVAL;
976 i2c_set_clientdata(adv->i2c_cec, adv); 976 i2c_set_clientdata(adv->i2c_cec, adv);
977 977
978 adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec, 978 adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
@@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
1082 struct adv7511_link_config link_config; 1082 struct adv7511_link_config link_config;
1083 struct adv7511 *adv7511; 1083 struct adv7511 *adv7511;
1084 struct device *dev = &i2c->dev; 1084 struct device *dev = &i2c->dev;
1085 unsigned int main_i2c_addr = i2c->addr << 1;
1086 unsigned int edid_i2c_addr = main_i2c_addr + 4;
1087 unsigned int val; 1085 unsigned int val;
1088 int ret; 1086 int ret;
1089 1087
@@ -1129,7 +1127,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
1129 } 1127 }
1130 1128
1131 if (adv7511->gpio_pd) { 1129 if (adv7511->gpio_pd) {
1132 mdelay(5); 1130 usleep_range(5000, 6000);
1133 gpiod_set_value_cansleep(adv7511->gpio_pd, 0); 1131 gpiod_set_value_cansleep(adv7511->gpio_pd, 0);
1134 } 1132 }
1135 1133
@@ -1153,23 +1151,34 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
1153 if (ret) 1151 if (ret)
1154 goto uninit_regulators; 1152 goto uninit_regulators;
1155 1153
1156 regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr);
1157 regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
1158 main_i2c_addr - 0xa);
1159 regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
1160 main_i2c_addr - 2);
1161
1162 adv7511_packet_disable(adv7511, 0xffff); 1154 adv7511_packet_disable(adv7511, 0xffff);
1163 1155
1164 adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); 1156 adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid",
1157 ADV7511_EDID_I2C_ADDR_DEFAULT);
1165 if (!adv7511->i2c_edid) { 1158 if (!adv7511->i2c_edid) {
1166 ret = -ENOMEM; 1159 ret = -EINVAL;
1167 goto uninit_regulators; 1160 goto uninit_regulators;
1168 } 1161 }
1169 1162
1163 regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
1164 adv7511->i2c_edid->addr << 1);
1165
1166 adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet",
1167 ADV7511_PACKET_I2C_ADDR_DEFAULT);
1168 if (!adv7511->i2c_packet) {
1169 ret = -EINVAL;
1170 goto err_i2c_unregister_edid;
1171 }
1172
1173 regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
1174 adv7511->i2c_packet->addr << 1);
1175
1170 ret = adv7511_init_cec_regmap(adv7511); 1176 ret = adv7511_init_cec_regmap(adv7511);
1171 if (ret) 1177 if (ret)
1172 goto err_i2c_unregister_edid; 1178 goto err_i2c_unregister_packet;
1179
1180 regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
1181 adv7511->i2c_cec->addr << 1);
1173 1182
1174 INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work); 1183 INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
1175 1184
@@ -1207,6 +1216,8 @@ err_unregister_cec:
1207 i2c_unregister_device(adv7511->i2c_cec); 1216 i2c_unregister_device(adv7511->i2c_cec);
1208 if (adv7511->cec_clk) 1217 if (adv7511->cec_clk)
1209 clk_disable_unprepare(adv7511->cec_clk); 1218 clk_disable_unprepare(adv7511->cec_clk);
1219err_i2c_unregister_packet:
1220 i2c_unregister_device(adv7511->i2c_packet);
1210err_i2c_unregister_edid: 1221err_i2c_unregister_edid:
1211 i2c_unregister_device(adv7511->i2c_edid); 1222 i2c_unregister_device(adv7511->i2c_edid);
1212uninit_regulators: 1223uninit_regulators:
@@ -1233,6 +1244,7 @@ static int adv7511_remove(struct i2c_client *i2c)
1233 1244
1234 cec_unregister_adapter(adv7511->cec_adap); 1245 cec_unregister_adapter(adv7511->cec_adap);
1235 1246
1247 i2c_unregister_device(adv7511->i2c_packet);
1236 i2c_unregister_device(adv7511->i2c_edid); 1248 i2c_unregister_device(adv7511->i2c_edid);
1237 1249
1238 return 0; 1250 return 0;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5c52307146c7..2bcbfadb6ac5 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -43,8 +43,10 @@ struct bridge_init {
43 struct device_node *node; 43 struct device_node *node;
44}; 44};
45 45
46static void analogix_dp_init_dp(struct analogix_dp_device *dp) 46static int analogix_dp_init_dp(struct analogix_dp_device *dp)
47{ 47{
48 int ret;
49
48 analogix_dp_reset(dp); 50 analogix_dp_reset(dp);
49 51
50 analogix_dp_swreset(dp); 52 analogix_dp_swreset(dp);
@@ -56,10 +58,13 @@ static void analogix_dp_init_dp(struct analogix_dp_device *dp)
56 analogix_dp_enable_sw_function(dp); 58 analogix_dp_enable_sw_function(dp);
57 59
58 analogix_dp_config_interrupt(dp); 60 analogix_dp_config_interrupt(dp);
59 analogix_dp_init_analog_func(dp); 61 ret = analogix_dp_init_analog_func(dp);
62 if (ret)
63 return ret;
60 64
61 analogix_dp_init_hpd(dp); 65 analogix_dp_init_hpd(dp);
62 analogix_dp_init_aux(dp); 66 analogix_dp_init_aux(dp);
67 return 0;
63} 68}
64 69
65static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) 70static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
@@ -71,7 +76,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
71 return 0; 76 return 0;
72 77
73 timeout_loop++; 78 timeout_loop++;
74 usleep_range(10, 11); 79 usleep_range(1000, 1100);
75 } 80 }
76 81
77 /* 82 /*
@@ -148,87 +153,146 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
148 psr_vsc.DB1 = 0; 153 psr_vsc.DB1 = 0;
149 154
150 ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D0); 155 ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
151 if (ret != 1) 156 if (ret != 1) {
152 dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret); 157 dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
158 return ret;
159 }
153 160
154 return analogix_dp_send_psr_spd(dp, &psr_vsc, false); 161 return analogix_dp_send_psr_spd(dp, &psr_vsc, false);
155} 162}
156EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); 163EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
157 164
158static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) 165static int analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
159{ 166{
160 unsigned char psr_version; 167 unsigned char psr_version;
168 int ret;
169
170 ret = drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version);
171 if (ret != 1) {
172 dev_err(dp->dev, "failed to get PSR version, disable it\n");
173 return ret;
174 }
161 175
162 drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version);
163 dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version); 176 dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version);
164 177
165 return (psr_version & DP_PSR_IS_SUPPORTED) ? true : false; 178 dp->psr_enable = (psr_version & DP_PSR_IS_SUPPORTED) ? true : false;
179
180 return 0;
166} 181}
167 182
168static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) 183static int analogix_dp_enable_sink_psr(struct analogix_dp_device *dp)
169{ 184{
170 unsigned char psr_en; 185 unsigned char psr_en;
186 int ret;
171 187
172 /* Disable psr function */ 188 /* Disable psr function */
173 drm_dp_dpcd_readb(&dp->aux, DP_PSR_EN_CFG, &psr_en); 189 ret = drm_dp_dpcd_readb(&dp->aux, DP_PSR_EN_CFG, &psr_en);
190 if (ret != 1) {
191 dev_err(dp->dev, "failed to get psr config\n");
192 goto end;
193 }
194
174 psr_en &= ~DP_PSR_ENABLE; 195 psr_en &= ~DP_PSR_ENABLE;
175 drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); 196 ret = drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en);
197 if (ret != 1) {
198 dev_err(dp->dev, "failed to disable panel psr\n");
199 goto end;
200 }
176 201
177 /* Main-Link transmitter remains active during PSR active states */ 202 /* Main-Link transmitter remains active during PSR active states */
178 psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; 203 psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION;
179 drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); 204 ret = drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en);
205 if (ret != 1) {
206 dev_err(dp->dev, "failed to set panel psr\n");
207 goto end;
208 }
180 209
181 /* Enable psr function */ 210 /* Enable psr function */
182 psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | 211 psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE |
183 DP_PSR_CRC_VERIFICATION; 212 DP_PSR_CRC_VERIFICATION;
184 drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); 213 ret = drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en);
214 if (ret != 1) {
215 dev_err(dp->dev, "failed to set panel psr\n");
216 goto end;
217 }
185 218
186 analogix_dp_enable_psr_crc(dp); 219 analogix_dp_enable_psr_crc(dp);
220
221 return 0;
222end:
223 dev_err(dp->dev, "enable psr fail, force to disable psr\n");
224 dp->psr_enable = false;
225
226 return ret;
187} 227}
188 228
189static void 229static int
190analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp, 230analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp,
191 bool enable) 231 bool enable)
192{ 232{
193 u8 data; 233 u8 data;
234 int ret;
194 235
195 drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data); 236 ret = drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data);
237 if (ret != 1)
238 return ret;
196 239
197 if (enable) 240 if (enable)
198 drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, 241 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET,
199 DP_LANE_COUNT_ENHANCED_FRAME_EN | 242 DP_LANE_COUNT_ENHANCED_FRAME_EN |
200 DPCD_LANE_COUNT_SET(data)); 243 DPCD_LANE_COUNT_SET(data));
201 else 244 else
202 drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, 245 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET,
203 DPCD_LANE_COUNT_SET(data)); 246 DPCD_LANE_COUNT_SET(data));
247
248 return ret < 0 ? ret : 0;
204} 249}
205 250
206static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp) 251static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp,
252 u8 *enhanced_mode_support)
207{ 253{
208 u8 data; 254 u8 data;
209 int retval; 255 int ret;
210 256
211 drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data); 257 ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data);
212 retval = DPCD_ENHANCED_FRAME_CAP(data); 258 if (ret != 1) {
259 *enhanced_mode_support = 0;
260 return ret;
261 }
213 262
214 return retval; 263 *enhanced_mode_support = DPCD_ENHANCED_FRAME_CAP(data);
264
265 return 0;
215} 266}
216 267
217static void analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp) 268static int analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp)
218{ 269{
219 u8 data; 270 u8 data;
271 int ret;
272
273 ret = analogix_dp_is_enhanced_mode_available(dp, &data);
274 if (ret < 0)
275 return ret;
276
277 ret = analogix_dp_enable_rx_to_enhanced_mode(dp, data);
278 if (ret < 0)
279 return ret;
220 280
221 data = analogix_dp_is_enhanced_mode_available(dp);
222 analogix_dp_enable_rx_to_enhanced_mode(dp, data);
223 analogix_dp_enable_enhanced_mode(dp, data); 281 analogix_dp_enable_enhanced_mode(dp, data);
282
283 return 0;
224} 284}
225 285
226static void analogix_dp_training_pattern_dis(struct analogix_dp_device *dp) 286static int analogix_dp_training_pattern_dis(struct analogix_dp_device *dp)
227{ 287{
288 int ret;
289
228 analogix_dp_set_training_pattern(dp, DP_NONE); 290 analogix_dp_set_training_pattern(dp, DP_NONE);
229 291
230 drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, 292 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET,
231 DP_TRAINING_PATTERN_DISABLE); 293 DP_TRAINING_PATTERN_DISABLE);
294
295 return ret < 0 ? ret : 0;
232} 296}
233 297
234static void 298static void
@@ -276,6 +340,12 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp)
276 retval = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, 2); 340 retval = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, 2);
277 if (retval < 0) 341 if (retval < 0)
278 return retval; 342 return retval;
343 /* set enhanced mode if available */
344 retval = analogix_dp_set_enhanced_mode(dp);
345 if (retval < 0) {
346 dev_err(dp->dev, "failed to set enhance mode\n");
347 return retval;
348 }
279 349
280 /* Set TX pre-emphasis to minimum */ 350 /* Set TX pre-emphasis to minimum */
281 for (lane = 0; lane < lane_count; lane++) 351 for (lane = 0; lane < lane_count; lane++)
@@ -531,7 +601,7 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
531{ 601{
532 int lane, lane_count, retval; 602 int lane, lane_count, retval;
533 u32 reg; 603 u32 reg;
534 u8 link_align, link_status[2], adjust_request[2], spread; 604 u8 link_align, link_status[2], adjust_request[2];
535 605
536 usleep_range(400, 401); 606 usleep_range(400, 401);
537 607
@@ -560,10 +630,11 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
560 630
561 if (!analogix_dp_channel_eq_ok(link_status, link_align, lane_count)) { 631 if (!analogix_dp_channel_eq_ok(link_status, link_align, lane_count)) {
562 /* traing pattern Set to Normal */ 632 /* traing pattern Set to Normal */
563 analogix_dp_training_pattern_dis(dp); 633 retval = analogix_dp_training_pattern_dis(dp);
634 if (retval < 0)
635 return retval;
564 636
565 dev_info(dp->dev, "Link Training success!\n"); 637 dev_info(dp->dev, "Link Training success!\n");
566
567 analogix_dp_get_link_bandwidth(dp, &reg); 638 analogix_dp_get_link_bandwidth(dp, &reg);
568 dp->link_train.link_rate = reg; 639 dp->link_train.link_rate = reg;
569 dev_dbg(dp->dev, "final bandwidth = %.2x\n", 640 dev_dbg(dp->dev, "final bandwidth = %.2x\n",
@@ -574,22 +645,6 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
574 dev_dbg(dp->dev, "final lane count = %.2x\n", 645 dev_dbg(dp->dev, "final lane count = %.2x\n",
575 dp->link_train.lane_count); 646 dp->link_train.lane_count);
576 647
577 retval = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD,
578 &spread);
579 if (retval != 1) {
580 dev_err(dp->dev, "failed to read downspread %d\n",
581 retval);
582 dp->fast_train_support = false;
583 } else {
584 dp->fast_train_support =
585 (spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
586 true : false;
587 }
588 dev_dbg(dp->dev, "fast link training %s\n",
589 dp->fast_train_support ? "supported" : "unsupported");
590
591 /* set enhanced mode if available */
592 analogix_dp_set_enhanced_mode(dp);
593 dp->link_train.lt_state = FINISHED; 648 dp->link_train.lt_state = FINISHED;
594 649
595 return 0; 650 return 0;
@@ -793,7 +848,7 @@ static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
793 848
794static int analogix_dp_train_link(struct analogix_dp_device *dp) 849static int analogix_dp_train_link(struct analogix_dp_device *dp)
795{ 850{
796 if (dp->fast_train_support) 851 if (dp->fast_train_enable)
797 return analogix_dp_fast_link_train(dp); 852 return analogix_dp_fast_link_train(dp);
798 853
799 return analogix_dp_full_link_train(dp, dp->video_info.max_lane_count, 854 return analogix_dp_full_link_train(dp, dp->video_info.max_lane_count,
@@ -819,11 +874,10 @@ static int analogix_dp_config_video(struct analogix_dp_device *dp)
819 if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0) 874 if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0)
820 break; 875 break;
821 if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) { 876 if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
822 dev_err(dp->dev, "Timeout of video streamclk ok\n"); 877 dev_err(dp->dev, "Timeout of slave video streamclk ok\n");
823 return -ETIMEDOUT; 878 return -ETIMEDOUT;
824 } 879 }
825 880 usleep_range(1000, 1001);
826 usleep_range(1, 2);
827 } 881 }
828 882
829 /* Set to use the register calculated M/N video */ 883 /* Set to use the register calculated M/N video */
@@ -838,6 +892,9 @@ static int analogix_dp_config_video(struct analogix_dp_device *dp)
838 /* Configure video slave mode */ 892 /* Configure video slave mode */
839 analogix_dp_enable_video_master(dp, 0); 893 analogix_dp_enable_video_master(dp, 0);
840 894
895 /* Enable video */
896 analogix_dp_start_video(dp);
897
841 timeout_loop = 0; 898 timeout_loop = 0;
842 899
843 for (;;) { 900 for (;;) {
@@ -850,8 +907,9 @@ static int analogix_dp_config_video(struct analogix_dp_device *dp)
850 done_count = 0; 907 done_count = 0;
851 } 908 }
852 if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) { 909 if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
853 dev_err(dp->dev, "Timeout of video streamclk ok\n"); 910 dev_warn(dp->dev,
854 return -ETIMEDOUT; 911 "Ignoring timeout of video streamclk ok\n");
912 break;
855 } 913 }
856 914
857 usleep_range(1000, 1001); 915 usleep_range(1000, 1001);
@@ -860,24 +918,32 @@ static int analogix_dp_config_video(struct analogix_dp_device *dp)
860 return 0; 918 return 0;
861} 919}
862 920
863static void analogix_dp_enable_scramble(struct analogix_dp_device *dp, 921static int analogix_dp_enable_scramble(struct analogix_dp_device *dp,
864 bool enable) 922 bool enable)
865{ 923{
866 u8 data; 924 u8 data;
925 int ret;
867 926
868 if (enable) { 927 if (enable) {
869 analogix_dp_enable_scrambling(dp); 928 analogix_dp_enable_scrambling(dp);
870 929
871 drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET, &data); 930 ret = drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET,
872 drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, 931 &data);
932 if (ret != 1)
933 return ret;
934 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET,
873 (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE)); 935 (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
874 } else { 936 } else {
875 analogix_dp_disable_scrambling(dp); 937 analogix_dp_disable_scrambling(dp);
876 938
877 drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET, &data); 939 ret = drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET,
878 drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, 940 &data);
941 if (ret != 1)
942 return ret;
943 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET,
879 (u8)(data | DP_LINK_SCRAMBLING_DISABLE)); 944 (u8)(data | DP_LINK_SCRAMBLING_DISABLE));
880 } 945 }
946 return ret < 0 ? ret : 0;
881} 947}
882 948
883static irqreturn_t analogix_dp_hardirq(int irq, void *arg) 949static irqreturn_t analogix_dp_hardirq(int irq, void *arg)
@@ -916,7 +982,23 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void *arg)
916 return IRQ_HANDLED; 982 return IRQ_HANDLED;
917} 983}
918 984
919static void analogix_dp_commit(struct analogix_dp_device *dp) 985static int analogix_dp_fast_link_train_detection(struct analogix_dp_device *dp)
986{
987 int ret;
988 u8 spread;
989
990 ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD, &spread);
991 if (ret != 1) {
992 dev_err(dp->dev, "failed to read downspread %d\n", ret);
993 return ret;
994 }
995 dp->fast_train_enable = !!(spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
996 dev_dbg(dp->dev, "fast link training %s\n",
997 dp->fast_train_enable ? "supported" : "unsupported");
998 return 0;
999}
1000
1001static int analogix_dp_commit(struct analogix_dp_device *dp)
920{ 1002{
921 int ret; 1003 int ret;
922 1004
@@ -926,34 +1008,50 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
926 DRM_ERROR("failed to disable the panel\n"); 1008 DRM_ERROR("failed to disable the panel\n");
927 } 1009 }
928 1010
929 ret = readx_poll_timeout(analogix_dp_train_link, dp, ret, !ret, 100, 1011 ret = analogix_dp_train_link(dp);
930 DP_TIMEOUT_TRAINING_US * 5);
931 if (ret) { 1012 if (ret) {
932 dev_err(dp->dev, "unable to do link train, ret=%d\n", ret); 1013 dev_err(dp->dev, "unable to do link train, ret=%d\n", ret);
933 return; 1014 return ret;
934 } 1015 }
935 1016
936 analogix_dp_enable_scramble(dp, 1); 1017 ret = analogix_dp_enable_scramble(dp, 1);
937 analogix_dp_enable_rx_to_enhanced_mode(dp, 1); 1018 if (ret < 0) {
938 analogix_dp_enable_enhanced_mode(dp, 1); 1019 dev_err(dp->dev, "can not enable scramble\n");
1020 return ret;
1021 }
939 1022
940 analogix_dp_init_video(dp); 1023 analogix_dp_init_video(dp);
941 ret = analogix_dp_config_video(dp); 1024 ret = analogix_dp_config_video(dp);
942 if (ret) 1025 if (ret) {
943 dev_err(dp->dev, "unable to config video\n"); 1026 dev_err(dp->dev, "unable to config video\n");
1027 return ret;
1028 }
944 1029
945 /* Safe to enable the panel now */ 1030 /* Safe to enable the panel now */
946 if (dp->plat_data->panel) { 1031 if (dp->plat_data->panel) {
947 if (drm_panel_enable(dp->plat_data->panel)) 1032 ret = drm_panel_enable(dp->plat_data->panel);
1033 if (ret) {
948 DRM_ERROR("failed to enable the panel\n"); 1034 DRM_ERROR("failed to enable the panel\n");
1035 return ret;
1036 }
949 } 1037 }
950 1038
951 /* Enable video */ 1039 ret = analogix_dp_detect_sink_psr(dp);
952 analogix_dp_start_video(dp); 1040 if (ret)
1041 return ret;
953 1042
954 dp->psr_enable = analogix_dp_detect_sink_psr(dp); 1043 if (dp->psr_enable) {
955 if (dp->psr_enable) 1044 ret = analogix_dp_enable_sink_psr(dp);
956 analogix_dp_enable_sink_psr(dp); 1045 if (ret)
1046 return ret;
1047 }
1048
1049 /* Check whether panel supports fast training */
1050 ret = analogix_dp_fast_link_train_detection(dp);
1051 if (ret)
1052 dp->psr_enable = false;
1053
1054 return ret;
957} 1055}
958 1056
959/* 1057/*
@@ -1150,24 +1248,80 @@ static void analogix_dp_bridge_pre_enable(struct drm_bridge *bridge)
1150 DRM_ERROR("failed to setup the panel ret = %d\n", ret); 1248 DRM_ERROR("failed to setup the panel ret = %d\n", ret);
1151} 1249}
1152 1250
1153static void analogix_dp_bridge_enable(struct drm_bridge *bridge) 1251static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
1154{ 1252{
1155 struct analogix_dp_device *dp = bridge->driver_private; 1253 int ret;
1156
1157 if (dp->dpms_mode == DRM_MODE_DPMS_ON)
1158 return;
1159 1254
1160 pm_runtime_get_sync(dp->dev); 1255 pm_runtime_get_sync(dp->dev);
1161 1256
1162 if (dp->plat_data->power_on) 1257 ret = clk_prepare_enable(dp->clock);
1163 dp->plat_data->power_on(dp->plat_data); 1258 if (ret < 0) {
1259 DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
1260 goto out_dp_clk_pre;
1261 }
1262
1263 if (dp->plat_data->power_on_start)
1264 dp->plat_data->power_on_start(dp->plat_data);
1164 1265
1165 phy_power_on(dp->phy); 1266 phy_power_on(dp->phy);
1166 analogix_dp_init_dp(dp); 1267
1268 ret = analogix_dp_init_dp(dp);
1269 if (ret)
1270 goto out_dp_init;
1271
1272 /*
1273 * According to DP spec v1.3 chap 3.5.1.2 Link Training,
1274 * We should first make sure the HPD signal is asserted high by device
1275 * when we want to establish a link with it.
1276 */
1277 ret = analogix_dp_detect_hpd(dp);
1278 if (ret) {
1279 DRM_ERROR("failed to get hpd single ret = %d\n", ret);
1280 goto out_dp_init;
1281 }
1282
1283 ret = analogix_dp_commit(dp);
1284 if (ret) {
1285 DRM_ERROR("dp commit error, ret = %d\n", ret);
1286 goto out_dp_init;
1287 }
1288
1289 if (dp->plat_data->power_on_end)
1290 dp->plat_data->power_on_end(dp->plat_data);
1291
1167 enable_irq(dp->irq); 1292 enable_irq(dp->irq);
1168 analogix_dp_commit(dp); 1293 return 0;
1169 1294
1170 dp->dpms_mode = DRM_MODE_DPMS_ON; 1295out_dp_init:
1296 phy_power_off(dp->phy);
1297 if (dp->plat_data->power_off)
1298 dp->plat_data->power_off(dp->plat_data);
1299 clk_disable_unprepare(dp->clock);
1300out_dp_clk_pre:
1301 pm_runtime_put_sync(dp->dev);
1302
1303 return ret;
1304}
1305
1306static void analogix_dp_bridge_enable(struct drm_bridge *bridge)
1307{
1308 struct analogix_dp_device *dp = bridge->driver_private;
1309 int timeout_loop = 0;
1310
1311 if (dp->dpms_mode == DRM_MODE_DPMS_ON)
1312 return;
1313
1314 while (timeout_loop < MAX_PLL_LOCK_LOOP) {
1315 if (analogix_dp_set_bridge(dp) == 0) {
1316 dp->dpms_mode = DRM_MODE_DPMS_ON;
1317 return;
1318 }
1319 dev_err(dp->dev, "failed to set bridge, retry: %d\n",
1320 timeout_loop);
1321 timeout_loop++;
1322 usleep_range(10, 11);
1323 }
1324 dev_err(dp->dev, "too many times retry set bridge, give it up\n");
1171} 1325}
1172 1326
1173static void analogix_dp_bridge_disable(struct drm_bridge *bridge) 1327static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
@@ -1186,11 +1340,15 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
1186 } 1340 }
1187 1341
1188 disable_irq(dp->irq); 1342 disable_irq(dp->irq);
1189 phy_power_off(dp->phy);
1190 1343
1191 if (dp->plat_data->power_off) 1344 if (dp->plat_data->power_off)
1192 dp->plat_data->power_off(dp->plat_data); 1345 dp->plat_data->power_off(dp->plat_data);
1193 1346
1347 analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);
1348 phy_power_off(dp->phy);
1349
1350 clk_disable_unprepare(dp->clock);
1351
1194 pm_runtime_put_sync(dp->dev); 1352 pm_runtime_put_sync(dp->dev);
1195 1353
1196 ret = analogix_dp_prepare_panel(dp, false, true); 1354 ret = analogix_dp_prepare_panel(dp, false, true);
@@ -1198,6 +1356,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
1198 DRM_ERROR("failed to setup the panel ret = %d\n", ret); 1356 DRM_ERROR("failed to setup the panel ret = %d\n", ret);
1199 1357
1200 dp->psr_enable = false; 1358 dp->psr_enable = false;
1359 dp->fast_train_enable = false;
1201 dp->dpms_mode = DRM_MODE_DPMS_OFF; 1360 dp->dpms_mode = DRM_MODE_DPMS_OFF;
1202} 1361}
1203 1362
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 6a96ef7e6934..769255dc6e99 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -19,6 +19,7 @@
19#define DP_TIMEOUT_LOOP_COUNT 100 19#define DP_TIMEOUT_LOOP_COUNT 100
20#define MAX_CR_LOOP 5 20#define MAX_CR_LOOP 5
21#define MAX_EQ_LOOP 5 21#define MAX_EQ_LOOP 5
22#define MAX_PLL_LOCK_LOOP 5
22 23
23/* Training takes 22ms if AUX channel comm fails. Use this as retry interval */ 24/* Training takes 22ms if AUX channel comm fails. Use this as retry interval */
24#define DP_TIMEOUT_TRAINING_US 22000 25#define DP_TIMEOUT_TRAINING_US 22000
@@ -173,7 +174,7 @@ struct analogix_dp_device {
173 int hpd_gpio; 174 int hpd_gpio;
174 bool force_hpd; 175 bool force_hpd;
175 bool psr_enable; 176 bool psr_enable;
176 bool fast_train_support; 177 bool fast_train_enable;
177 178
178 struct mutex panel_lock; 179 struct mutex panel_lock;
179 bool panel_is_modeset; 180 bool panel_is_modeset;
@@ -197,7 +198,7 @@ void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable);
197void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp, 198void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
198 enum analog_power_block block, 199 enum analog_power_block block,
199 bool enable); 200 bool enable);
200void analogix_dp_init_analog_func(struct analogix_dp_device *dp); 201int analogix_dp_init_analog_func(struct analogix_dp_device *dp);
201void analogix_dp_init_hpd(struct analogix_dp_device *dp); 202void analogix_dp_init_hpd(struct analogix_dp_device *dp);
202void analogix_dp_force_hpd(struct analogix_dp_device *dp); 203void analogix_dp_force_hpd(struct analogix_dp_device *dp);
203enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp); 204enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 9df2f3ef000c..a5f2763d72e4 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -126,9 +126,14 @@ void analogix_dp_reset(struct analogix_dp_device *dp)
126 analogix_dp_stop_video(dp); 126 analogix_dp_stop_video(dp);
127 analogix_dp_enable_video_mute(dp, 0); 127 analogix_dp_enable_video_mute(dp, 0);
128 128
129 reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | 129 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
130 AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | 130 reg = RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N |
131 HDCP_FUNC_EN_N | SW_FUNC_EN_N; 131 SW_FUNC_EN_N;
132 else
133 reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
134 AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
135 HDCP_FUNC_EN_N | SW_FUNC_EN_N;
136
132 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1); 137 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
133 138
134 reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N | 139 reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
@@ -230,16 +235,20 @@ enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp)
230void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable) 235void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable)
231{ 236{
232 u32 reg; 237 u32 reg;
238 u32 mask = DP_PLL_PD;
239 u32 pd_addr = ANALOGIX_DP_PLL_CTL;
233 240
234 if (enable) { 241 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
235 reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL); 242 pd_addr = ANALOGIX_DP_PD;
236 reg |= DP_PLL_PD; 243 mask = RK_PLL_PD;
237 writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
238 } else {
239 reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
240 reg &= ~DP_PLL_PD;
241 writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
242 } 244 }
245
246 reg = readl(dp->reg_base + pd_addr);
247 if (enable)
248 reg |= mask;
249 else
250 reg &= ~mask;
251 writel(reg, dp->reg_base + pd_addr);
243} 252}
244 253
245void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp, 254void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
@@ -248,83 +257,98 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
248{ 257{
249 u32 reg; 258 u32 reg;
250 u32 phy_pd_addr = ANALOGIX_DP_PHY_PD; 259 u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
260 u32 mask;
251 261
252 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) 262 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
253 phy_pd_addr = ANALOGIX_DP_PD; 263 phy_pd_addr = ANALOGIX_DP_PD;
254 264
255 switch (block) { 265 switch (block) {
256 case AUX_BLOCK: 266 case AUX_BLOCK:
257 if (enable) { 267 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
258 reg = readl(dp->reg_base + phy_pd_addr); 268 mask = RK_AUX_PD;
259 reg |= AUX_PD; 269 else
260 writel(reg, dp->reg_base + phy_pd_addr); 270 mask = AUX_PD;
261 } else { 271
262 reg = readl(dp->reg_base + phy_pd_addr); 272 reg = readl(dp->reg_base + phy_pd_addr);
263 reg &= ~AUX_PD; 273 if (enable)
264 writel(reg, dp->reg_base + phy_pd_addr); 274 reg |= mask;
265 } 275 else
276 reg &= ~mask;
277 writel(reg, dp->reg_base + phy_pd_addr);
266 break; 278 break;
267 case CH0_BLOCK: 279 case CH0_BLOCK:
268 if (enable) { 280 mask = CH0_PD;
269 reg = readl(dp->reg_base + phy_pd_addr); 281 reg = readl(dp->reg_base + phy_pd_addr);
270 reg |= CH0_PD; 282
271 writel(reg, dp->reg_base + phy_pd_addr); 283 if (enable)
272 } else { 284 reg |= mask;
273 reg = readl(dp->reg_base + phy_pd_addr); 285 else
274 reg &= ~CH0_PD; 286 reg &= ~mask;
275 writel(reg, dp->reg_base + phy_pd_addr); 287 writel(reg, dp->reg_base + phy_pd_addr);
276 }
277 break; 288 break;
278 case CH1_BLOCK: 289 case CH1_BLOCK:
279 if (enable) { 290 mask = CH1_PD;
280 reg = readl(dp->reg_base + phy_pd_addr); 291 reg = readl(dp->reg_base + phy_pd_addr);
281 reg |= CH1_PD; 292
282 writel(reg, dp->reg_base + phy_pd_addr); 293 if (enable)
283 } else { 294 reg |= mask;
284 reg = readl(dp->reg_base + phy_pd_addr); 295 else
285 reg &= ~CH1_PD; 296 reg &= ~mask;
286 writel(reg, dp->reg_base + phy_pd_addr); 297 writel(reg, dp->reg_base + phy_pd_addr);
287 }
288 break; 298 break;
289 case CH2_BLOCK: 299 case CH2_BLOCK:
290 if (enable) { 300 mask = CH2_PD;
291 reg = readl(dp->reg_base + phy_pd_addr); 301 reg = readl(dp->reg_base + phy_pd_addr);
292 reg |= CH2_PD; 302
293 writel(reg, dp->reg_base + phy_pd_addr); 303 if (enable)
294 } else { 304 reg |= mask;
295 reg = readl(dp->reg_base + phy_pd_addr); 305 else
296 reg &= ~CH2_PD; 306 reg &= ~mask;
297 writel(reg, dp->reg_base + phy_pd_addr); 307 writel(reg, dp->reg_base + phy_pd_addr);
298 }
299 break; 308 break;
300 case CH3_BLOCK: 309 case CH3_BLOCK:
301 if (enable) { 310 mask = CH3_PD;
302 reg = readl(dp->reg_base + phy_pd_addr); 311 reg = readl(dp->reg_base + phy_pd_addr);
303 reg |= CH3_PD; 312
304 writel(reg, dp->reg_base + phy_pd_addr); 313 if (enable)
305 } else { 314 reg |= mask;
306 reg = readl(dp->reg_base + phy_pd_addr); 315 else
307 reg &= ~CH3_PD; 316 reg &= ~mask;
308 writel(reg, dp->reg_base + phy_pd_addr); 317 writel(reg, dp->reg_base + phy_pd_addr);
309 }
310 break; 318 break;
311 case ANALOG_TOTAL: 319 case ANALOG_TOTAL:
312 if (enable) { 320 /*
313 reg = readl(dp->reg_base + phy_pd_addr); 321 * There is no bit named DP_PHY_PD, so We used DP_INC_BG
314 reg |= DP_PHY_PD; 322 * to power off everything instead of DP_PHY_PD in
315 writel(reg, dp->reg_base + phy_pd_addr); 323 * Rockchip
316 } else { 324 */
317 reg = readl(dp->reg_base + phy_pd_addr); 325 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
318 reg &= ~DP_PHY_PD; 326 mask = DP_INC_BG;
319 writel(reg, dp->reg_base + phy_pd_addr); 327 else
320 } 328 mask = DP_PHY_PD;
329
330 reg = readl(dp->reg_base + phy_pd_addr);
331 if (enable)
332 reg |= mask;
333 else
334 reg &= ~mask;
335
336 writel(reg, dp->reg_base + phy_pd_addr);
337 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
338 usleep_range(10, 15);
321 break; 339 break;
322 case POWER_ALL: 340 case POWER_ALL:
323 if (enable) { 341 if (enable) {
324 reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD | 342 reg = DP_ALL_PD;
325 CH1_PD | CH0_PD;
326 writel(reg, dp->reg_base + phy_pd_addr); 343 writel(reg, dp->reg_base + phy_pd_addr);
327 } else { 344 } else {
345 reg = DP_ALL_PD;
346 writel(reg, dp->reg_base + phy_pd_addr);
347 usleep_range(10, 15);
348 reg &= ~DP_INC_BG;
349 writel(reg, dp->reg_base + phy_pd_addr);
350 usleep_range(10, 15);
351
328 writel(0x00, dp->reg_base + phy_pd_addr); 352 writel(0x00, dp->reg_base + phy_pd_addr);
329 } 353 }
330 break; 354 break;
@@ -333,7 +357,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
333 } 357 }
334} 358}
335 359
336void analogix_dp_init_analog_func(struct analogix_dp_device *dp) 360int analogix_dp_init_analog_func(struct analogix_dp_device *dp)
337{ 361{
338 u32 reg; 362 u32 reg;
339 int timeout_loop = 0; 363 int timeout_loop = 0;
@@ -355,7 +379,7 @@ void analogix_dp_init_analog_func(struct analogix_dp_device *dp)
355 timeout_loop++; 379 timeout_loop++;
356 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 380 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
357 dev_err(dp->dev, "failed to get pll lock status\n"); 381 dev_err(dp->dev, "failed to get pll lock status\n");
358 return; 382 return -ETIMEDOUT;
359 } 383 }
360 usleep_range(10, 20); 384 usleep_range(10, 20);
361 } 385 }
@@ -366,6 +390,7 @@ void analogix_dp_init_analog_func(struct analogix_dp_device *dp)
366 reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N 390 reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
367 | AUX_FUNC_EN_N); 391 | AUX_FUNC_EN_N);
368 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2); 392 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
393 return 0;
369} 394}
370 395
371void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp) 396void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp)
@@ -450,17 +475,22 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
450 reg = RPLY_RECEIV | AUX_ERR; 475 reg = RPLY_RECEIV | AUX_ERR;
451 writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA); 476 writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
452 477
478 analogix_dp_set_analog_power_down(dp, AUX_BLOCK, true);
479 usleep_range(10, 11);
480 analogix_dp_set_analog_power_down(dp, AUX_BLOCK, false);
481
453 analogix_dp_reset_aux(dp); 482 analogix_dp_reset_aux(dp);
454 483
455 /* Disable AUX transaction H/W retry */ 484 /* AUX_BIT_PERIOD_EXPECTED_DELAY doesn't apply to Rockchip IP */
456 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) 485 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
457 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) | 486 reg = 0;
458 AUX_HW_RETRY_COUNT_SEL(3) |
459 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
460 else 487 else
461 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | 488 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3);
462 AUX_HW_RETRY_COUNT_SEL(0) | 489
463 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; 490 /* Disable AUX transaction H/W retry */
491 reg |= AUX_HW_RETRY_COUNT_SEL(0) |
492 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
493
464 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL); 494 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
465 495
466 /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ 496 /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
@@ -947,8 +977,12 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
947 u32 reg; 977 u32 reg;
948 978
949 reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1); 979 reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
950 reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N); 980 if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
951 reg |= MASTER_VID_FUNC_EN_N; 981 reg &= ~(RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N);
982 } else {
983 reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
984 reg |= MASTER_VID_FUNC_EN_N;
985 }
952 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1); 986 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
953 987
954 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 988 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
@@ -1072,10 +1106,11 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
1072 struct drm_dp_aux_msg *msg) 1106 struct drm_dp_aux_msg *msg)
1073{ 1107{
1074 u32 reg; 1108 u32 reg;
1109 u32 status_reg;
1075 u8 *buffer = msg->buffer; 1110 u8 *buffer = msg->buffer;
1076 int timeout_loop = 0;
1077 unsigned int i; 1111 unsigned int i;
1078 int num_transferred = 0; 1112 int num_transferred = 0;
1113 int ret;
1079 1114
1080 /* Buffer size of AUX CH is 16 bytes */ 1115 /* Buffer size of AUX CH is 16 bytes */
1081 if (WARN_ON(msg->size > 16)) 1116 if (WARN_ON(msg->size > 16))
@@ -1139,17 +1174,20 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
1139 1174
1140 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2); 1175 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
1141 1176
1142 /* Is AUX CH command reply received? */ 1177 ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2,
1178 reg, !(reg & AUX_EN), 25, 500 * 1000);
1179 if (ret) {
1180 dev_err(dp->dev, "AUX CH enable timeout!\n");
1181 goto aux_error;
1182 }
1183
1143 /* TODO: Wait for an interrupt instead of looping? */ 1184 /* TODO: Wait for an interrupt instead of looping? */
1144 reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA); 1185 /* Is AUX CH command reply received? */
1145 while (!(reg & RPLY_RECEIV)) { 1186 ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_INT_STA,
1146 timeout_loop++; 1187 reg, reg & RPLY_RECEIV, 10, 20 * 1000);
1147 if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) { 1188 if (ret) {
1148 dev_err(dp->dev, "AUX CH command reply failed!\n"); 1189 dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
1149 return -ETIMEDOUT; 1190 goto aux_error;
1150 }
1151 reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
1152 usleep_range(10, 11);
1153 } 1191 }
1154 1192
1155 /* Clear interrupt source for AUX CH command reply */ 1193 /* Clear interrupt source for AUX CH command reply */
@@ -1157,17 +1195,13 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
1157 1195
1158 /* Clear interrupt source for AUX CH access error */ 1196 /* Clear interrupt source for AUX CH access error */
1159 reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA); 1197 reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
1160 if (reg & AUX_ERR) { 1198 status_reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
1199 if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) {
1161 writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA); 1200 writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
1162 return -EREMOTEIO;
1163 }
1164 1201
1165 /* Check AUX CH error access status */ 1202 dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n",
1166 reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA); 1203 status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR));
1167 if ((reg & AUX_STATUS_MASK)) { 1204 goto aux_error;
1168 dev_err(dp->dev, "AUX CH error happened: %d\n\n",
1169 reg & AUX_STATUS_MASK);
1170 return -EREMOTEIO;
1171 } 1205 }
1172 1206
1173 if (msg->request & DP_AUX_I2C_READ) { 1207 if (msg->request & DP_AUX_I2C_READ) {
@@ -1193,4 +1227,10 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
1193 msg->reply = DP_AUX_NATIVE_REPLY_ACK; 1227 msg->reply = DP_AUX_NATIVE_REPLY_ACK;
1194 1228
1195 return num_transferred > 0 ? num_transferred : -EBUSY; 1229 return num_transferred > 0 ? num_transferred : -EBUSY;
1230
1231aux_error:
1232 /* if aux err happen, reset aux */
1233 analogix_dp_init_aux(dp);
1234
1235 return -EREMOTEIO;
1196} 1236}
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
index 40200c652533..0cf27c731727 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
@@ -127,7 +127,9 @@
127 127
128/* ANALOGIX_DP_FUNC_EN_1 */ 128/* ANALOGIX_DP_FUNC_EN_1 */
129#define MASTER_VID_FUNC_EN_N (0x1 << 7) 129#define MASTER_VID_FUNC_EN_N (0x1 << 7)
130#define RK_VID_CAP_FUNC_EN_N (0x1 << 6)
130#define SLAVE_VID_FUNC_EN_N (0x1 << 5) 131#define SLAVE_VID_FUNC_EN_N (0x1 << 5)
132#define RK_VID_FIFO_FUNC_EN_N (0x1 << 5)
131#define AUD_FIFO_FUNC_EN_N (0x1 << 4) 133#define AUD_FIFO_FUNC_EN_N (0x1 << 4)
132#define AUD_FUNC_EN_N (0x1 << 3) 134#define AUD_FUNC_EN_N (0x1 << 3)
133#define HDCP_FUNC_EN_N (0x1 << 2) 135#define HDCP_FUNC_EN_N (0x1 << 2)
@@ -342,12 +344,17 @@
342#define DP_PLL_REF_BIT_1_2500V (0x7 << 0) 344#define DP_PLL_REF_BIT_1_2500V (0x7 << 0)
343 345
344/* ANALOGIX_DP_PHY_PD */ 346/* ANALOGIX_DP_PHY_PD */
347#define DP_INC_BG (0x1 << 7)
348#define DP_EXP_BG (0x1 << 6)
345#define DP_PHY_PD (0x1 << 5) 349#define DP_PHY_PD (0x1 << 5)
350#define RK_AUX_PD (0x1 << 5)
346#define AUX_PD (0x1 << 4) 351#define AUX_PD (0x1 << 4)
352#define RK_PLL_PD (0x1 << 4)
347#define CH3_PD (0x1 << 3) 353#define CH3_PD (0x1 << 3)
348#define CH2_PD (0x1 << 2) 354#define CH2_PD (0x1 << 2)
349#define CH1_PD (0x1 << 1) 355#define CH1_PD (0x1 << 1)
350#define CH0_PD (0x1 << 0) 356#define CH0_PD (0x1 << 0)
357#define DP_ALL_PD (0xff)
351 358
352/* ANALOGIX_DP_PHY_TEST */ 359/* ANALOGIX_DP_PHY_TEST */
353#define MACRO_RST (0x1 << 5) 360#define MACRO_RST (0x1 << 5)
diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c
new file mode 100644
index 000000000000..c255fc3e1be5
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cdns-dsi.c
@@ -0,0 +1,1623 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright: 2017 Cadence Design Systems, Inc.
4 *
5 * Author: Boris Brezillon <boris.brezillon@bootlin.com>
6 */
7
8#include <drm/drm_atomic_helper.h>
9#include <drm/drm_bridge.h>
10#include <drm/drm_crtc_helper.h>
11#include <drm/drm_mipi_dsi.h>
12#include <drm/drm_panel.h>
13#include <video/mipi_display.h>
14
15#include <linux/clk.h>
16#include <linux/iopoll.h>
17#include <linux/module.h>
18#include <linux/of_address.h>
19#include <linux/of_graph.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/reset.h>
23
24#define IP_CONF 0x0
25#define SP_HS_FIFO_DEPTH(x) (((x) & GENMASK(30, 26)) >> 26)
26#define SP_LP_FIFO_DEPTH(x) (((x) & GENMASK(25, 21)) >> 21)
27#define VRS_FIFO_DEPTH(x) (((x) & GENMASK(20, 16)) >> 16)
28#define DIRCMD_FIFO_DEPTH(x) (((x) & GENMASK(15, 13)) >> 13)
29#define SDI_IFACE_32 BIT(12)
30#define INTERNAL_DATAPATH_32 (0 << 10)
31#define INTERNAL_DATAPATH_16 (1 << 10)
32#define INTERNAL_DATAPATH_8 (3 << 10)
33#define INTERNAL_DATAPATH_SIZE ((x) & GENMASK(11, 10))
34#define NUM_IFACE(x) ((((x) & GENMASK(9, 8)) >> 8) + 1)
35#define MAX_LANE_NB(x) (((x) & GENMASK(7, 6)) >> 6)
36#define RX_FIFO_DEPTH(x) ((x) & GENMASK(5, 0))
37
38#define MCTL_MAIN_DATA_CTL 0x4
39#define TE_MIPI_POLLING_EN BIT(25)
40#define TE_HW_POLLING_EN BIT(24)
41#define DISP_EOT_GEN BIT(18)
42#define HOST_EOT_GEN BIT(17)
43#define DISP_GEN_CHECKSUM BIT(16)
44#define DISP_GEN_ECC BIT(15)
45#define BTA_EN BIT(14)
46#define READ_EN BIT(13)
47#define REG_TE_EN BIT(12)
48#define IF_TE_EN(x) BIT(8 + (x))
49#define TVG_SEL BIT(6)
50#define VID_EN BIT(5)
51#define IF_VID_SELECT(x) ((x) << 2)
52#define IF_VID_SELECT_MASK GENMASK(3, 2)
53#define IF_VID_MODE BIT(1)
54#define LINK_EN BIT(0)
55
56#define MCTL_MAIN_PHY_CTL 0x8
57#define HS_INVERT_DAT(x) BIT(19 + ((x) * 2))
58#define SWAP_PINS_DAT(x) BIT(18 + ((x) * 2))
59#define HS_INVERT_CLK BIT(17)
60#define SWAP_PINS_CLK BIT(16)
61#define HS_SKEWCAL_EN BIT(15)
62#define WAIT_BURST_TIME(x) ((x) << 10)
63#define DATA_ULPM_EN(x) BIT(6 + (x))
64#define CLK_ULPM_EN BIT(5)
65#define CLK_CONTINUOUS BIT(4)
66#define DATA_LANE_EN(x) BIT((x) - 1)
67
68#define MCTL_MAIN_EN 0xc
69#define DATA_FORCE_STOP BIT(17)
70#define CLK_FORCE_STOP BIT(16)
71#define IF_EN(x) BIT(13 + (x))
72#define DATA_LANE_ULPM_REQ(l) BIT(9 + (l))
73#define CLK_LANE_ULPM_REQ BIT(8)
74#define DATA_LANE_START(x) BIT(4 + (x))
75#define CLK_LANE_EN BIT(3)
76#define PLL_START BIT(0)
77
78#define MCTL_DPHY_CFG0 0x10
79#define DPHY_C_RSTB BIT(20)
80#define DPHY_D_RSTB(x) GENMASK(15 + (x), 16)
81#define DPHY_PLL_PDN BIT(10)
82#define DPHY_CMN_PDN BIT(9)
83#define DPHY_C_PDN BIT(8)
84#define DPHY_D_PDN(x) GENMASK(3 + (x), 4)
85#define DPHY_ALL_D_PDN GENMASK(7, 4)
86#define DPHY_PLL_PSO BIT(1)
87#define DPHY_CMN_PSO BIT(0)
88
89#define MCTL_DPHY_TIMEOUT1 0x14
90#define HSTX_TIMEOUT(x) ((x) << 4)
91#define HSTX_TIMEOUT_MAX GENMASK(17, 0)
92#define CLK_DIV(x) (x)
93#define CLK_DIV_MAX GENMASK(3, 0)
94
95#define MCTL_DPHY_TIMEOUT2 0x18
96#define LPRX_TIMEOUT(x) (x)
97
98#define MCTL_ULPOUT_TIME 0x1c
99#define DATA_LANE_ULPOUT_TIME(x) ((x) << 9)
100#define CLK_LANE_ULPOUT_TIME(x) (x)
101
102#define MCTL_3DVIDEO_CTL 0x20
103#define VID_VSYNC_3D_EN BIT(7)
104#define VID_VSYNC_3D_LR BIT(5)
105#define VID_VSYNC_3D_SECOND_EN BIT(4)
106#define VID_VSYNC_3DFORMAT_LINE (0 << 2)
107#define VID_VSYNC_3DFORMAT_FRAME (1 << 2)
108#define VID_VSYNC_3DFORMAT_PIXEL (2 << 2)
109#define VID_VSYNC_3DMODE_OFF 0
110#define VID_VSYNC_3DMODE_PORTRAIT 1
111#define VID_VSYNC_3DMODE_LANDSCAPE 2
112
113#define MCTL_MAIN_STS 0x24
114#define MCTL_MAIN_STS_CTL 0x130
115#define MCTL_MAIN_STS_CLR 0x150
116#define MCTL_MAIN_STS_FLAG 0x170
117#define HS_SKEWCAL_DONE BIT(11)
118#define IF_UNTERM_PKT_ERR(x) BIT(8 + (x))
119#define LPRX_TIMEOUT_ERR BIT(7)
120#define HSTX_TIMEOUT_ERR BIT(6)
121#define DATA_LANE_RDY(l) BIT(2 + (l))
122#define CLK_LANE_RDY BIT(1)
123#define PLL_LOCKED BIT(0)
124
125#define MCTL_DPHY_ERR 0x28
126#define MCTL_DPHY_ERR_CTL1 0x148
127#define MCTL_DPHY_ERR_CLR 0x168
128#define MCTL_DPHY_ERR_FLAG 0x188
129#define ERR_CONT_LP(x, l) BIT(18 + ((x) * 4) + (l))
130#define ERR_CONTROL(l) BIT(14 + (l))
131#define ERR_SYNESC(l) BIT(10 + (l))
132#define ERR_ESC(l) BIT(6 + (l))
133
134#define MCTL_DPHY_ERR_CTL2 0x14c
135#define ERR_CONT_LP_EDGE(x, l) BIT(12 + ((x) * 4) + (l))
136#define ERR_CONTROL_EDGE(l) BIT(8 + (l))
137#define ERR_SYN_ESC_EDGE(l) BIT(4 + (l))
138#define ERR_ESC_EDGE(l) BIT(0 + (l))
139
140#define MCTL_LANE_STS 0x2c
141#define PPI_C_TX_READY_HS BIT(18)
142#define DPHY_PLL_LOCK BIT(17)
143#define PPI_D_RX_ULPS_ESC(x) (((x) & GENMASK(15, 12)) >> 12)
144#define LANE_STATE_START 0
145#define LANE_STATE_IDLE 1
146#define LANE_STATE_WRITE 2
147#define LANE_STATE_ULPM 3
148#define LANE_STATE_READ 4
149#define DATA_LANE_STATE(l, val) \
150 (((val) >> (2 + 2 * (l) + ((l) ? 1 : 0))) & GENMASK((l) ? 1 : 2, 0))
151#define CLK_LANE_STATE_HS 2
152#define CLK_LANE_STATE(val) ((val) & GENMASK(1, 0))
153
154#define DSC_MODE_CTL 0x30
155#define DSC_MODE_EN BIT(0)
156
157#define DSC_CMD_SEND 0x34
158#define DSC_SEND_PPS BIT(0)
159#define DSC_EXECUTE_QUEUE BIT(1)
160
161#define DSC_PPS_WRDAT 0x38
162
163#define DSC_MODE_STS 0x3c
164#define DSC_PPS_DONE BIT(1)
165#define DSC_EXEC_DONE BIT(2)
166
167#define CMD_MODE_CTL 0x70
168#define IF_LP_EN(x) BIT(9 + (x))
169#define IF_VCHAN_ID(x, c) ((c) << ((x) * 2))
170
171#define CMD_MODE_CTL2 0x74
172#define TE_TIMEOUT(x) ((x) << 11)
173#define FILL_VALUE(x) ((x) << 3)
174#define ARB_IF_WITH_HIGHEST_PRIORITY(x) ((x) << 1)
175#define ARB_ROUND_ROBIN_MODE BIT(0)
176
177#define CMD_MODE_STS 0x78
178#define CMD_MODE_STS_CTL 0x134
179#define CMD_MODE_STS_CLR 0x154
180#define CMD_MODE_STS_FLAG 0x174
181#define ERR_IF_UNDERRUN(x) BIT(4 + (x))
182#define ERR_UNWANTED_READ BIT(3)
183#define ERR_TE_MISS BIT(2)
184#define ERR_NO_TE BIT(1)
185#define CSM_RUNNING BIT(0)
186
187#define DIRECT_CMD_SEND 0x80
188
189#define DIRECT_CMD_MAIN_SETTINGS 0x84
190#define TRIGGER_VAL(x) ((x) << 25)
191#define CMD_LP_EN BIT(24)
192#define CMD_SIZE(x) ((x) << 16)
193#define CMD_VCHAN_ID(x) ((x) << 14)
194#define CMD_DATATYPE(x) ((x) << 8)
195#define CMD_LONG BIT(3)
196#define WRITE_CMD 0
197#define READ_CMD 1
198#define TE_REQ 4
199#define TRIGGER_REQ 5
200#define BTA_REQ 6
201
202#define DIRECT_CMD_STS 0x88
203#define DIRECT_CMD_STS_CTL 0x138
204#define DIRECT_CMD_STS_CLR 0x158
205#define DIRECT_CMD_STS_FLAG 0x178
206#define RCVD_ACK_VAL(val) ((val) >> 16)
207#define RCVD_TRIGGER_VAL(val) (((val) & GENMASK(14, 11)) >> 11)
208#define READ_COMPLETED_WITH_ERR BIT(10)
209#define BTA_FINISHED BIT(9)
210#define BTA_COMPLETED BIT(8)
211#define TE_RCVD BIT(7)
212#define TRIGGER_RCVD BIT(6)
213#define ACK_WITH_ERR_RCVD BIT(5)
214#define ACK_RCVD BIT(4)
215#define READ_COMPLETED BIT(3)
216#define TRIGGER_COMPLETED BIT(2)
217#define WRITE_COMPLETED BIT(1)
218#define SENDING_CMD BIT(0)
219
220#define DIRECT_CMD_STOP_READ 0x8c
221
222#define DIRECT_CMD_WRDATA 0x90
223
224#define DIRECT_CMD_FIFO_RST 0x94
225
226#define DIRECT_CMD_RDDATA 0xa0
227
228#define DIRECT_CMD_RD_PROPS 0xa4
229#define RD_DCS BIT(18)
230#define RD_VCHAN_ID(val) (((val) >> 16) & GENMASK(1, 0))
231#define RD_SIZE(val) ((val) & GENMASK(15, 0))
232
233#define DIRECT_CMD_RD_STS 0xa8
234#define DIRECT_CMD_RD_STS_CTL 0x13c
235#define DIRECT_CMD_RD_STS_CLR 0x15c
236#define DIRECT_CMD_RD_STS_FLAG 0x17c
237#define ERR_EOT_WITH_ERR BIT(8)
238#define ERR_MISSING_EOT BIT(7)
239#define ERR_WRONG_LENGTH BIT(6)
240#define ERR_OVERSIZE BIT(5)
241#define ERR_RECEIVE BIT(4)
242#define ERR_UNDECODABLE BIT(3)
243#define ERR_CHECKSUM BIT(2)
244#define ERR_UNCORRECTABLE BIT(1)
245#define ERR_FIXED BIT(0)
246
247#define VID_MAIN_CTL 0xb0
248#define VID_IGNORE_MISS_VSYNC BIT(31)
249#define VID_FIELD_SW BIT(28)
250#define VID_INTERLACED_EN BIT(27)
251#define RECOVERY_MODE(x) ((x) << 25)
252#define RECOVERY_MODE_NEXT_HSYNC 0
253#define RECOVERY_MODE_NEXT_STOP_POINT 2
254#define RECOVERY_MODE_NEXT_VSYNC 3
255#define REG_BLKEOL_MODE(x) ((x) << 23)
256#define REG_BLKLINE_MODE(x) ((x) << 21)
257#define REG_BLK_MODE_NULL_PKT 0
258#define REG_BLK_MODE_BLANKING_PKT 1
259#define REG_BLK_MODE_LP 2
260#define SYNC_PULSE_HORIZONTAL BIT(20)
261#define SYNC_PULSE_ACTIVE BIT(19)
262#define BURST_MODE BIT(18)
263#define VID_PIXEL_MODE_MASK GENMASK(17, 14)
264#define VID_PIXEL_MODE_RGB565 (0 << 14)
265#define VID_PIXEL_MODE_RGB666_PACKED (1 << 14)
266#define VID_PIXEL_MODE_RGB666 (2 << 14)
267#define VID_PIXEL_MODE_RGB888 (3 << 14)
268#define VID_PIXEL_MODE_RGB101010 (4 << 14)
269#define VID_PIXEL_MODE_RGB121212 (5 << 14)
270#define VID_PIXEL_MODE_YUV420 (8 << 14)
271#define VID_PIXEL_MODE_YUV422_PACKED (9 << 14)
272#define VID_PIXEL_MODE_YUV422 (10 << 14)
273#define VID_PIXEL_MODE_YUV422_24B (11 << 14)
274#define VID_PIXEL_MODE_DSC_COMP (12 << 14)
275#define VID_DATATYPE(x) ((x) << 8)
276#define VID_VIRTCHAN_ID(iface, x) ((x) << (4 + (iface) * 2))
277#define STOP_MODE(x) ((x) << 2)
278#define START_MODE(x) (x)
279
280#define VID_VSIZE1 0xb4
281#define VFP_LEN(x) ((x) << 12)
282#define VBP_LEN(x) ((x) << 6)
283#define VSA_LEN(x) (x)
284
285#define VID_VSIZE2 0xb8
286#define VACT_LEN(x) (x)
287
288#define VID_HSIZE1 0xc0
289#define HBP_LEN(x) ((x) << 16)
290#define HSA_LEN(x) (x)
291
292#define VID_HSIZE2 0xc4
293#define HFP_LEN(x) ((x) << 16)
294#define HACT_LEN(x) (x)
295
296#define VID_BLKSIZE1 0xcc
297#define BLK_EOL_PKT_LEN(x) ((x) << 15)
298#define BLK_LINE_EVENT_PKT_LEN(x) (x)
299
300#define VID_BLKSIZE2 0xd0
301#define BLK_LINE_PULSE_PKT_LEN(x) (x)
302
303#define VID_PKT_TIME 0xd8
304#define BLK_EOL_DURATION(x) (x)
305
306#define VID_DPHY_TIME 0xdc
307#define REG_WAKEUP_TIME(x) ((x) << 17)
308#define REG_LINE_DURATION(x) (x)
309
310#define VID_ERR_COLOR1 0xe0
311#define COL_GREEN(x) ((x) << 12)
312#define COL_RED(x) (x)
313
314#define VID_ERR_COLOR2 0xe4
315#define PAD_VAL(x) ((x) << 12)
316#define COL_BLUE(x) (x)
317
318#define VID_VPOS 0xe8
319#define LINE_VAL(val) (((val) & GENMASK(14, 2)) >> 2)
320#define LINE_POS(val) ((val) & GENMASK(1, 0))
321
322#define VID_HPOS 0xec
323#define HORIZ_VAL(val) (((val) & GENMASK(17, 3)) >> 3)
324#define HORIZ_POS(val) ((val) & GENMASK(2, 0))
325
326#define VID_MODE_STS 0xf0
327#define VID_MODE_STS_CTL 0x140
328#define VID_MODE_STS_CLR 0x160
329#define VID_MODE_STS_FLAG 0x180
330#define VSG_RECOVERY BIT(10)
331#define ERR_VRS_WRONG_LEN BIT(9)
332#define ERR_LONG_READ BIT(8)
333#define ERR_LINE_WRITE BIT(7)
334#define ERR_BURST_WRITE BIT(6)
335#define ERR_SMALL_HEIGHT BIT(5)
336#define ERR_SMALL_LEN BIT(4)
337#define ERR_MISSING_VSYNC BIT(3)
338#define ERR_MISSING_HSYNC BIT(2)
339#define ERR_MISSING_DATA BIT(1)
340#define VSG_RUNNING BIT(0)
341
342#define VID_VCA_SETTING1 0xf4
343#define BURST_LP BIT(16)
344#define MAX_BURST_LIMIT(x) (x)
345
346#define VID_VCA_SETTING2 0xf8
347#define MAX_LINE_LIMIT(x) ((x) << 16)
348#define EXACT_BURST_LIMIT(x) (x)
349
350#define TVG_CTL 0xfc
351#define TVG_STRIPE_SIZE(x) ((x) << 5)
352#define TVG_MODE_MASK GENMASK(4, 3)
353#define TVG_MODE_SINGLE_COLOR (0 << 3)
354#define TVG_MODE_VSTRIPES (2 << 3)
355#define TVG_MODE_HSTRIPES (3 << 3)
356#define TVG_STOPMODE_MASK GENMASK(2, 1)
357#define TVG_STOPMODE_EOF (0 << 1)
358#define TVG_STOPMODE_EOL (1 << 1)
359#define TVG_STOPMODE_NOW (2 << 1)
360#define TVG_RUN BIT(0)
361
362#define TVG_IMG_SIZE 0x100
363#define TVG_NBLINES(x) ((x) << 16)
364#define TVG_LINE_SIZE(x) (x)
365
366#define TVG_COLOR1 0x104
367#define TVG_COL1_GREEN(x) ((x) << 12)
368#define TVG_COL1_RED(x) (x)
369
370#define TVG_COLOR1_BIS 0x108
371#define TVG_COL1_BLUE(x) (x)
372
373#define TVG_COLOR2 0x10c
374#define TVG_COL2_GREEN(x) ((x) << 12)
375#define TVG_COL2_RED(x) (x)
376
377#define TVG_COLOR2_BIS 0x110
378#define TVG_COL2_BLUE(x) (x)
379
380#define TVG_STS 0x114
381#define TVG_STS_CTL 0x144
382#define TVG_STS_CLR 0x164
383#define TVG_STS_FLAG 0x184
384#define TVG_STS_RUNNING BIT(0)
385
386#define STS_CTL_EDGE(e) ((e) << 16)
387
388#define DPHY_LANES_MAP 0x198
389#define DAT_REMAP_CFG(b, l) ((l) << ((b) * 8))
390
391#define DPI_IRQ_EN 0x1a0
392#define DPI_IRQ_CLR 0x1a4
393#define DPI_IRQ_STS 0x1a8
394#define PIXEL_BUF_OVERFLOW BIT(0)
395
396#define DPI_CFG 0x1ac
397#define DPI_CFG_FIFO_DEPTH(x) ((x) >> 16)
398#define DPI_CFG_FIFO_LEVEL(x) ((x) & GENMASK(15, 0))
399
400#define TEST_GENERIC 0x1f0
401#define TEST_STATUS(x) ((x) >> 16)
402#define TEST_CTRL(x) (x)
403
404#define ID_REG 0x1fc
405#define REV_VENDOR_ID(x) (((x) & GENMASK(31, 20)) >> 20)
406#define REV_PRODUCT_ID(x) (((x) & GENMASK(19, 12)) >> 12)
407#define REV_HW(x) (((x) & GENMASK(11, 8)) >> 8)
408#define REV_MAJOR(x) (((x) & GENMASK(7, 4)) >> 4)
409#define REV_MINOR(x) ((x) & GENMASK(3, 0))
410
411#define DSI_OUTPUT_PORT 0
412#define DSI_INPUT_PORT(inputid) (1 + (inputid))
413
414#define DSI_HBP_FRAME_OVERHEAD 12
415#define DSI_HSA_FRAME_OVERHEAD 14
416#define DSI_HFP_FRAME_OVERHEAD 6
417#define DSI_HSS_VSS_VSE_FRAME_OVERHEAD 4
418#define DSI_BLANKING_FRAME_OVERHEAD 6
419#define DSI_NULL_FRAME_OVERHEAD 6
420#define DSI_EOT_PKT_SIZE 4
421
422#define REG_WAKEUP_TIME_NS 800
423#define DPHY_PLL_RATE_HZ 108000000
424
425/* DPHY registers */
426#define DPHY_PMA_CMN(reg) (reg)
427#define DPHY_PMA_LCLK(reg) (0x100 + (reg))
428#define DPHY_PMA_LDATA(lane, reg) (0x200 + ((lane) * 0x100) + (reg))
429#define DPHY_PMA_RCLK(reg) (0x600 + (reg))
430#define DPHY_PMA_RDATA(lane, reg) (0x700 + ((lane) * 0x100) + (reg))
431#define DPHY_PCS(reg) (0xb00 + (reg))
432
433#define DPHY_CMN_SSM DPHY_PMA_CMN(0x20)
434#define DPHY_CMN_SSM_EN BIT(0)
435#define DPHY_CMN_TX_MODE_EN BIT(9)
436
437#define DPHY_CMN_PWM DPHY_PMA_CMN(0x40)
438#define DPHY_CMN_PWM_DIV(x) ((x) << 20)
439#define DPHY_CMN_PWM_LOW(x) ((x) << 10)
440#define DPHY_CMN_PWM_HIGH(x) (x)
441
442#define DPHY_CMN_FBDIV DPHY_PMA_CMN(0x4c)
443#define DPHY_CMN_FBDIV_VAL(low, high) (((high) << 11) | ((low) << 22))
444#define DPHY_CMN_FBDIV_FROM_REG (BIT(10) | BIT(21))
445
446#define DPHY_CMN_OPIPDIV DPHY_PMA_CMN(0x50)
447#define DPHY_CMN_IPDIV_FROM_REG BIT(0)
448#define DPHY_CMN_IPDIV(x) ((x) << 1)
449#define DPHY_CMN_OPDIV_FROM_REG BIT(6)
450#define DPHY_CMN_OPDIV(x) ((x) << 7)
451
452#define DPHY_PSM_CFG DPHY_PCS(0x4)
453#define DPHY_PSM_CFG_FROM_REG BIT(0)
454#define DPHY_PSM_CLK_DIV(x) ((x) << 1)
455
456struct cdns_dsi_output {
457 struct mipi_dsi_device *dev;
458 struct drm_panel *panel;
459 struct drm_bridge *bridge;
460};
461
462enum cdns_dsi_input_id {
463 CDNS_SDI_INPUT,
464 CDNS_DPI_INPUT,
465 CDNS_DSC_INPUT,
466};
467
468struct cdns_dphy_cfg {
469 u8 pll_ipdiv;
470 u8 pll_opdiv;
471 u16 pll_fbdiv;
472 unsigned long lane_bps;
473 unsigned int nlanes;
474};
475
476struct cdns_dsi_cfg {
477 unsigned int hfp;
478 unsigned int hsa;
479 unsigned int hbp;
480 unsigned int hact;
481 unsigned int htotal;
482};
483
484struct cdns_dphy;
485
486enum cdns_dphy_clk_lane_cfg {
487 DPHY_CLK_CFG_LEFT_DRIVES_ALL = 0,
488 DPHY_CLK_CFG_LEFT_DRIVES_RIGHT = 1,
489 DPHY_CLK_CFG_LEFT_DRIVES_LEFT = 2,
490 DPHY_CLK_CFG_RIGHT_DRIVES_ALL = 3,
491};
492
493struct cdns_dphy_ops {
494 int (*probe)(struct cdns_dphy *dphy);
495 void (*remove)(struct cdns_dphy *dphy);
496 void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
497 void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
498 enum cdns_dphy_clk_lane_cfg cfg);
499 void (*set_pll_cfg)(struct cdns_dphy *dphy,
500 const struct cdns_dphy_cfg *cfg);
501 unsigned long (*get_wakeup_time_ns)(struct cdns_dphy *dphy);
502};
503
504struct cdns_dphy {
505 struct cdns_dphy_cfg cfg;
506 void __iomem *regs;
507 struct clk *psm_clk;
508 struct clk *pll_ref_clk;
509 const struct cdns_dphy_ops *ops;
510};
511
512struct cdns_dsi_input {
513 enum cdns_dsi_input_id id;
514 struct drm_bridge bridge;
515};
516
517struct cdns_dsi {
518 struct mipi_dsi_host base;
519 void __iomem *regs;
520 struct cdns_dsi_input input;
521 struct cdns_dsi_output output;
522 unsigned int direct_cmd_fifo_depth;
523 unsigned int rx_fifo_depth;
524 struct completion direct_cmd_comp;
525 struct clk *dsi_p_clk;
526 struct reset_control *dsi_p_rst;
527 struct clk *dsi_sys_clk;
528 bool link_initialized;
529 struct cdns_dphy *dphy;
530};
531
532static inline struct cdns_dsi *input_to_dsi(struct cdns_dsi_input *input)
533{
534 return container_of(input, struct cdns_dsi, input);
535}
536
537static inline struct cdns_dsi *to_cdns_dsi(struct mipi_dsi_host *host)
538{
539 return container_of(host, struct cdns_dsi, base);
540}
541
542static inline struct cdns_dsi_input *
543bridge_to_cdns_dsi_input(struct drm_bridge *bridge)
544{
545 return container_of(bridge, struct cdns_dsi_input, bridge);
546}
547
548static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
549 struct cdns_dphy_cfg *cfg,
550 unsigned int dpi_htotal,
551 unsigned int dpi_bpp,
552 unsigned int dpi_hz,
553 unsigned int dsi_htotal,
554 unsigned int dsi_nlanes,
555 unsigned int *dsi_hfp_ext)
556{
557 u64 dlane_bps, dlane_bps_max, fbdiv, fbdiv_max, adj_dsi_htotal;
558 unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk);
559
560 memset(cfg, 0, sizeof(*cfg));
561
562 cfg->nlanes = dsi_nlanes;
563
564 if (pll_ref_hz < 9600000 || pll_ref_hz >= 150000000)
565 return -EINVAL;
566 else if (pll_ref_hz < 19200000)
567 cfg->pll_ipdiv = 1;
568 else if (pll_ref_hz < 38400000)
569 cfg->pll_ipdiv = 2;
570 else if (pll_ref_hz < 76800000)
571 cfg->pll_ipdiv = 4;
572 else
573 cfg->pll_ipdiv = 8;
574
575 /*
576 * Make sure DSI htotal is aligned on a lane boundary when calculating
577 * the expected data rate. This is done by extending HFP in case of
578 * misalignment.
579 */
580 adj_dsi_htotal = dsi_htotal;
581 if (dsi_htotal % dsi_nlanes)
582 adj_dsi_htotal += dsi_nlanes - (dsi_htotal % dsi_nlanes);
583
584 dlane_bps = (u64)dpi_hz * adj_dsi_htotal;
585
586 /* data rate in bytes/sec is not an integer, refuse the mode. */
587 if (do_div(dlane_bps, dsi_nlanes * dpi_htotal))
588 return -EINVAL;
589
590 /* data rate was in bytes/sec, convert to bits/sec. */
591 dlane_bps *= 8;
592
593 if (dlane_bps > 2500000000UL || dlane_bps < 160000000UL)
594 return -EINVAL;
595 else if (dlane_bps >= 1250000000)
596 cfg->pll_opdiv = 1;
597 else if (dlane_bps >= 630000000)
598 cfg->pll_opdiv = 2;
599 else if (dlane_bps >= 320000000)
600 cfg->pll_opdiv = 4;
601 else if (dlane_bps >= 160000000)
602 cfg->pll_opdiv = 8;
603
604 /*
605 * Allow a deviation of 0.2% on the per-lane data rate to try to
606 * recover a potential mismatch between DPI and PPI clks.
607 */
608 dlane_bps_max = dlane_bps + DIV_ROUND_DOWN_ULL(dlane_bps, 500);
609 fbdiv_max = DIV_ROUND_DOWN_ULL(dlane_bps_max * 2 *
610 cfg->pll_opdiv * cfg->pll_ipdiv,
611 pll_ref_hz);
612 fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv *
613 cfg->pll_ipdiv,
614 pll_ref_hz);
615
616 /*
617 * Iterate over all acceptable fbdiv and try to find an adjusted DSI
618 * htotal length providing an exact match.
619 *
620 * Note that we could do something even trickier by relying on the fact
621 * that a new line is not necessarily aligned on a lane boundary, so,
622 * by making adj_dsi_htotal non aligned on a dsi_lanes we can improve a
623 * bit the precision. With this, the step would be
624 *
625 * pll_ref_hz / (2 * opdiv * ipdiv * nlanes)
626 *
627 * instead of
628 *
629 * pll_ref_hz / (2 * opdiv * ipdiv)
630 *
631 * The drawback of this approach is that we would need to make sure the
632 * number or lines is a multiple of the realignment periodicity which is
633 * a function of the number of lanes and the original misalignment. For
634 * example, for NLANES = 4 and HTOTAL % NLANES = 3, it takes 4 lines
635 * to realign on a lane:
636 * LINE 0: expected number of bytes, starts emitting first byte of
637 * LINE 1 on LANE 3
638 * LINE 1: expected number of bytes, starts emitting first 2 bytes of
639 * LINE 2 on LANES 2 and 3
640 * LINE 2: expected number of bytes, starts emitting first 3 bytes of
641 * of LINE 3 on LANES 1, 2 and 3
642 * LINE 3: one byte less, now things are realigned on LANE 0 for LINE 4
643 *
644 * I figured this extra complexity was not worth the benefit, but if
645 * someone really has unfixable mismatch, that would be something to
646 * investigate.
647 */
648 for (; fbdiv <= fbdiv_max; fbdiv++) {
649 u32 rem;
650
651 adj_dsi_htotal = (u64)fbdiv * pll_ref_hz * dsi_nlanes *
652 dpi_htotal;
653
654 /*
655 * Do the division in 2 steps to avoid an overflow on the
656 * divider.
657 */
658 rem = do_div(adj_dsi_htotal, dpi_hz);
659 if (rem)
660 continue;
661
662 rem = do_div(adj_dsi_htotal,
663 cfg->pll_opdiv * cfg->pll_ipdiv * 2 * 8);
664 if (rem)
665 continue;
666
667 cfg->pll_fbdiv = fbdiv;
668 *dsi_hfp_ext = adj_dsi_htotal - dsi_htotal;
669 break;
670 }
671
672 /* No match, let's just reject the display mode. */
673 if (!cfg->pll_fbdiv)
674 return -EINVAL;
675
676 dlane_bps = DIV_ROUND_DOWN_ULL((u64)dpi_hz * adj_dsi_htotal * 8,
677 dsi_nlanes * dpi_htotal);
678 cfg->lane_bps = dlane_bps;
679
680 return 0;
681}
682
683static int cdns_dphy_setup_psm(struct cdns_dphy *dphy)
684{
685 unsigned long psm_clk_hz = clk_get_rate(dphy->psm_clk);
686 unsigned long psm_div;
687
688 if (!psm_clk_hz || psm_clk_hz > 100000000)
689 return -EINVAL;
690
691 psm_div = DIV_ROUND_CLOSEST(psm_clk_hz, 1000000);
692 if (dphy->ops->set_psm_div)
693 dphy->ops->set_psm_div(dphy, psm_div);
694
695 return 0;
696}
697
698static void cdns_dphy_set_clk_lane_cfg(struct cdns_dphy *dphy,
699 enum cdns_dphy_clk_lane_cfg cfg)
700{
701 if (dphy->ops->set_clk_lane_cfg)
702 dphy->ops->set_clk_lane_cfg(dphy, cfg);
703}
704
705static void cdns_dphy_set_pll_cfg(struct cdns_dphy *dphy,
706 const struct cdns_dphy_cfg *cfg)
707{
708 if (dphy->ops->set_pll_cfg)
709 dphy->ops->set_pll_cfg(dphy, cfg);
710}
711
712static unsigned long cdns_dphy_get_wakeup_time_ns(struct cdns_dphy *dphy)
713{
714 return dphy->ops->get_wakeup_time_ns(dphy);
715}
716
717static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing,
718 unsigned int dpi_bpp,
719 unsigned int dsi_pkt_overhead)
720{
721 unsigned int dsi_timing = DIV_ROUND_UP(dpi_timing * dpi_bpp, 8);
722
723 if (dsi_timing < dsi_pkt_overhead)
724 dsi_timing = 0;
725 else
726 dsi_timing -= dsi_pkt_overhead;
727
728 return dsi_timing;
729}
730
731static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi,
732 const struct drm_display_mode *mode,
733 struct cdns_dsi_cfg *dsi_cfg,
734 struct cdns_dphy_cfg *dphy_cfg,
735 bool mode_valid_check)
736{
737 unsigned long dsi_htotal = 0, dsi_hss_hsa_hse_hbp = 0;
738 struct cdns_dsi_output *output = &dsi->output;
739 unsigned int dsi_hfp_ext = 0, dpi_hfp, tmp;
740 bool sync_pulse = false;
741 int bpp, nlanes, ret;
742
743 memset(dsi_cfg, 0, sizeof(*dsi_cfg));
744
745 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
746 sync_pulse = true;
747
748 bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format);
749 nlanes = output->dev->lanes;
750
751 if (mode_valid_check)
752 tmp = mode->htotal -
753 (sync_pulse ? mode->hsync_end : mode->hsync_start);
754 else
755 tmp = mode->crtc_htotal -
756 (sync_pulse ?
757 mode->crtc_hsync_end : mode->crtc_hsync_start);
758
759 dsi_cfg->hbp = dpi_to_dsi_timing(tmp, bpp, DSI_HBP_FRAME_OVERHEAD);
760 dsi_htotal += dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
761 dsi_hss_hsa_hse_hbp += dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
762
763 if (sync_pulse) {
764 if (mode_valid_check)
765 tmp = mode->hsync_end - mode->hsync_start;
766 else
767 tmp = mode->crtc_hsync_end - mode->crtc_hsync_start;
768
769 dsi_cfg->hsa = dpi_to_dsi_timing(tmp, bpp,
770 DSI_HSA_FRAME_OVERHEAD);
771 dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
772 dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
773 }
774
775 dsi_cfg->hact = dpi_to_dsi_timing(mode_valid_check ?
776 mode->hdisplay : mode->crtc_hdisplay,
777 bpp, 0);
778 dsi_htotal += dsi_cfg->hact;
779
780 if (mode_valid_check)
781 dpi_hfp = mode->hsync_start - mode->hdisplay;
782 else
783 dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay;
784
785 dsi_cfg->hfp = dpi_to_dsi_timing(dpi_hfp, bpp, DSI_HFP_FRAME_OVERHEAD);
786 dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD;
787
788 if (mode_valid_check)
789 ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg,
790 mode->htotal, bpp,
791 mode->clock * 1000,
792 dsi_htotal, nlanes,
793 &dsi_hfp_ext);
794 else
795 ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg,
796 mode->crtc_htotal, bpp,
797 mode->crtc_clock * 1000,
798 dsi_htotal, nlanes,
799 &dsi_hfp_ext);
800
801 if (ret)
802 return ret;
803
804 dsi_cfg->hfp += dsi_hfp_ext;
805 dsi_htotal += dsi_hfp_ext;
806 dsi_cfg->htotal = dsi_htotal;
807
808 /*
809 * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO
810 * is empty before we start a receiving a new line on the DPI
811 * interface.
812 */
813 if ((u64)dphy_cfg->lane_bps * dpi_hfp * nlanes <
814 (u64)dsi_hss_hsa_hse_hbp *
815 (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000)
816 return -EINVAL;
817
818 return 0;
819}
820
821static int cdns_dsi_bridge_attach(struct drm_bridge *bridge)
822{
823 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
824 struct cdns_dsi *dsi = input_to_dsi(input);
825 struct cdns_dsi_output *output = &dsi->output;
826
827 if (!drm_core_check_feature(bridge->dev, DRIVER_ATOMIC)) {
828 dev_err(dsi->base.dev,
829 "cdns-dsi driver is only compatible with DRM devices supporting atomic updates");
830 return -ENOTSUPP;
831 }
832
833 return drm_bridge_attach(bridge->encoder, output->bridge, bridge);
834}
835
836static enum drm_mode_status
837cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
838 const struct drm_display_mode *mode)
839{
840 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
841 struct cdns_dsi *dsi = input_to_dsi(input);
842 struct cdns_dsi_output *output = &dsi->output;
843 struct cdns_dphy_cfg dphy_cfg;
844 struct cdns_dsi_cfg dsi_cfg;
845 int bpp, nlanes, ret;
846
847 /*
848 * VFP_DSI should be less than VFP_DPI and VFP_DSI should be at
849 * least 1.
850 */
851 if (mode->vtotal - mode->vsync_end < 2)
852 return MODE_V_ILLEGAL;
853
854 /* VSA_DSI = VSA_DPI and must be at least 2. */
855 if (mode->vsync_end - mode->vsync_start < 2)
856 return MODE_V_ILLEGAL;
857
858 /* HACT must be 32-bits aligned. */
859 bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format);
860 if ((mode->hdisplay * bpp) % 32)
861 return MODE_H_ILLEGAL;
862
863 nlanes = output->dev->lanes;
864
865 ret = cdns_dsi_mode2cfg(dsi, mode, &dsi_cfg, &dphy_cfg, true);
866 if (ret)
867 return MODE_CLOCK_RANGE;
868
869 return MODE_OK;
870}
871
872static void cdns_dsi_bridge_disable(struct drm_bridge *bridge)
873{
874 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
875 struct cdns_dsi *dsi = input_to_dsi(input);
876 u32 val;
877
878 val = readl(dsi->regs + MCTL_MAIN_DATA_CTL);
879 val &= ~(IF_VID_SELECT_MASK | IF_VID_MODE | VID_EN | HOST_EOT_GEN |
880 DISP_EOT_GEN);
881 writel(val, dsi->regs + MCTL_MAIN_DATA_CTL);
882
883 val = readl(dsi->regs + MCTL_MAIN_EN) & ~IF_EN(input->id);
884 writel(val, dsi->regs + MCTL_MAIN_EN);
885 pm_runtime_put(dsi->base.dev);
886}
887
888static void cdns_dsi_hs_init(struct cdns_dsi *dsi,
889 const struct cdns_dphy_cfg *dphy_cfg)
890{
891 u32 status;
892
893 /*
894 * Power all internal DPHY blocks down and maintain their reset line
895 * asserted before changing the DPHY config.
896 */
897 writel(DPHY_CMN_PSO | DPHY_PLL_PSO | DPHY_ALL_D_PDN | DPHY_C_PDN |
898 DPHY_CMN_PDN | DPHY_PLL_PDN,
899 dsi->regs + MCTL_DPHY_CFG0);
900
901 /*
902 * Configure the internal PSM clk divider so that the DPHY has a
903 * 1MHz clk (or something close).
904 */
905 WARN_ON_ONCE(cdns_dphy_setup_psm(dsi->dphy));
906
907 /*
908 * Configure attach clk lanes to data lanes: the DPHY has 2 clk lanes
909 * and 8 data lanes, each clk lane can be attache different set of
910 * data lanes. The 2 groups are named 'left' and 'right', so here we
911 * just say that we want the 'left' clk lane to drive the 'left' data
912 * lanes.
913 */
914 cdns_dphy_set_clk_lane_cfg(dsi->dphy, DPHY_CLK_CFG_LEFT_DRIVES_LEFT);
915
916 /*
917 * Configure the DPHY PLL that will be used to generate the TX byte
918 * clk.
919 */
920 cdns_dphy_set_pll_cfg(dsi->dphy, dphy_cfg);
921
922 /* Start TX state machine. */
923 writel(DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN,
924 dsi->dphy->regs + DPHY_CMN_SSM);
925
926 /* Activate the PLL and wait until it's locked. */
927 writel(PLL_LOCKED, dsi->regs + MCTL_MAIN_STS_CLR);
928 writel(DPHY_CMN_PSO | DPHY_ALL_D_PDN | DPHY_C_PDN | DPHY_CMN_PDN,
929 dsi->regs + MCTL_DPHY_CFG0);
930 WARN_ON_ONCE(readl_poll_timeout(dsi->regs + MCTL_MAIN_STS, status,
931 status & PLL_LOCKED, 100, 100));
932 /* De-assert data and clock reset lines. */
933 writel(DPHY_CMN_PSO | DPHY_ALL_D_PDN | DPHY_C_PDN | DPHY_CMN_PDN |
934 DPHY_D_RSTB(dphy_cfg->nlanes) | DPHY_C_RSTB,
935 dsi->regs + MCTL_DPHY_CFG0);
936}
937
938static void cdns_dsi_init_link(struct cdns_dsi *dsi)
939{
940 struct cdns_dsi_output *output = &dsi->output;
941 unsigned long sysclk_period, ulpout;
942 u32 val;
943 int i;
944
945 if (dsi->link_initialized)
946 return;
947
948 val = 0;
949 for (i = 1; i < output->dev->lanes; i++)
950 val |= DATA_LANE_EN(i);
951
952 if (!(output->dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
953 val |= CLK_CONTINUOUS;
954
955 writel(val, dsi->regs + MCTL_MAIN_PHY_CTL);
956
957 /* ULPOUT should be set to 1ms and is expressed in sysclk cycles. */
958 sysclk_period = NSEC_PER_SEC / clk_get_rate(dsi->dsi_sys_clk);
959 ulpout = DIV_ROUND_UP(NSEC_PER_MSEC, sysclk_period);
960 writel(CLK_LANE_ULPOUT_TIME(ulpout) | DATA_LANE_ULPOUT_TIME(ulpout),
961 dsi->regs + MCTL_ULPOUT_TIME);
962
963 writel(LINK_EN, dsi->regs + MCTL_MAIN_DATA_CTL);
964
965 val = CLK_LANE_EN | PLL_START;
966 for (i = 0; i < output->dev->lanes; i++)
967 val |= DATA_LANE_START(i);
968
969 writel(val, dsi->regs + MCTL_MAIN_EN);
970
971 dsi->link_initialized = true;
972}
973
974static void cdns_dsi_bridge_enable(struct drm_bridge *bridge)
975{
976 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
977 struct cdns_dsi *dsi = input_to_dsi(input);
978 struct cdns_dsi_output *output = &dsi->output;
979 struct drm_display_mode *mode;
980 struct cdns_dphy_cfg dphy_cfg;
981 unsigned long tx_byte_period;
982 struct cdns_dsi_cfg dsi_cfg;
983 u32 tmp, reg_wakeup, div;
984 int bpp, nlanes;
985
986 if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0))
987 return;
988
989 mode = &bridge->encoder->crtc->state->adjusted_mode;
990 bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format);
991 nlanes = output->dev->lanes;
992
993 WARN_ON_ONCE(cdns_dsi_mode2cfg(dsi, mode, &dsi_cfg, &dphy_cfg, false));
994
995 cdns_dsi_hs_init(dsi, &dphy_cfg);
996 cdns_dsi_init_link(dsi);
997
998 writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa),
999 dsi->regs + VID_HSIZE1);
1000 writel(HFP_LEN(dsi_cfg.hfp) | HACT_LEN(dsi_cfg.hact),
1001 dsi->regs + VID_HSIZE2);
1002
1003 writel(VBP_LEN(mode->crtc_vtotal - mode->crtc_vsync_end - 1) |
1004 VFP_LEN(mode->crtc_vsync_start - mode->crtc_vdisplay) |
1005 VSA_LEN(mode->crtc_vsync_end - mode->crtc_vsync_start + 1),
1006 dsi->regs + VID_VSIZE1);
1007 writel(mode->crtc_vdisplay, dsi->regs + VID_VSIZE2);
1008
1009 tmp = dsi_cfg.htotal -
1010 (dsi_cfg.hsa + DSI_BLANKING_FRAME_OVERHEAD +
1011 DSI_HSA_FRAME_OVERHEAD);
1012 writel(BLK_LINE_PULSE_PKT_LEN(tmp), dsi->regs + VID_BLKSIZE2);
1013 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
1014 writel(MAX_LINE_LIMIT(tmp - DSI_NULL_FRAME_OVERHEAD),
1015 dsi->regs + VID_VCA_SETTING2);
1016
1017 tmp = dsi_cfg.htotal -
1018 (DSI_HSS_VSS_VSE_FRAME_OVERHEAD + DSI_BLANKING_FRAME_OVERHEAD);
1019 writel(BLK_LINE_EVENT_PKT_LEN(tmp), dsi->regs + VID_BLKSIZE1);
1020 if (!(output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
1021 writel(MAX_LINE_LIMIT(tmp - DSI_NULL_FRAME_OVERHEAD),
1022 dsi->regs + VID_VCA_SETTING2);
1023
1024 tmp = DIV_ROUND_UP(dsi_cfg.htotal, nlanes) -
1025 DIV_ROUND_UP(dsi_cfg.hsa, nlanes);
1026
1027 if (!(output->dev->mode_flags & MIPI_DSI_MODE_EOT_PACKET))
1028 tmp -= DIV_ROUND_UP(DSI_EOT_PKT_SIZE, nlanes);
1029
1030 tx_byte_period = DIV_ROUND_DOWN_ULL((u64)NSEC_PER_SEC * 8,
1031 dphy_cfg.lane_bps);
1032 reg_wakeup = cdns_dphy_get_wakeup_time_ns(dsi->dphy) /
1033 tx_byte_period;
1034 writel(REG_WAKEUP_TIME(reg_wakeup) | REG_LINE_DURATION(tmp),
1035 dsi->regs + VID_DPHY_TIME);
1036
1037 /*
1038 * HSTX and LPRX timeouts are both expressed in TX byte clk cycles and
1039 * both should be set to at least the time it takes to transmit a
1040 * frame.
1041 */
1042 tmp = NSEC_PER_SEC / drm_mode_vrefresh(mode);
1043 tmp /= tx_byte_period;
1044
1045 for (div = 0; div <= CLK_DIV_MAX; div++) {
1046 if (tmp <= HSTX_TIMEOUT_MAX)
1047 break;
1048
1049 tmp >>= 1;
1050 }
1051
1052 if (tmp > HSTX_TIMEOUT_MAX)
1053 tmp = HSTX_TIMEOUT_MAX;
1054
1055 writel(CLK_DIV(div) | HSTX_TIMEOUT(tmp),
1056 dsi->regs + MCTL_DPHY_TIMEOUT1);
1057
1058 writel(LPRX_TIMEOUT(tmp), dsi->regs + MCTL_DPHY_TIMEOUT2);
1059
1060 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO) {
1061 switch (output->dev->format) {
1062 case MIPI_DSI_FMT_RGB888:
1063 tmp = VID_PIXEL_MODE_RGB888 |
1064 VID_DATATYPE(MIPI_DSI_PACKED_PIXEL_STREAM_24);
1065 break;
1066
1067 case MIPI_DSI_FMT_RGB666:
1068 tmp = VID_PIXEL_MODE_RGB666 |
1069 VID_DATATYPE(MIPI_DSI_PIXEL_STREAM_3BYTE_18);
1070 break;
1071
1072 case MIPI_DSI_FMT_RGB666_PACKED:
1073 tmp = VID_PIXEL_MODE_RGB666_PACKED |
1074 VID_DATATYPE(MIPI_DSI_PACKED_PIXEL_STREAM_18);
1075 break;
1076
1077 case MIPI_DSI_FMT_RGB565:
1078 tmp = VID_PIXEL_MODE_RGB565 |
1079 VID_DATATYPE(MIPI_DSI_PACKED_PIXEL_STREAM_16);
1080 break;
1081
1082 default:
1083 dev_err(dsi->base.dev, "Unsupported DSI format\n");
1084 return;
1085 }
1086
1087 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
1088 tmp |= SYNC_PULSE_ACTIVE | SYNC_PULSE_HORIZONTAL;
1089
1090 tmp |= REG_BLKLINE_MODE(REG_BLK_MODE_BLANKING_PKT) |
1091 REG_BLKEOL_MODE(REG_BLK_MODE_BLANKING_PKT) |
1092 RECOVERY_MODE(RECOVERY_MODE_NEXT_HSYNC) |
1093 VID_IGNORE_MISS_VSYNC;
1094
1095 writel(tmp, dsi->regs + VID_MAIN_CTL);
1096 }
1097
1098 tmp = readl(dsi->regs + MCTL_MAIN_DATA_CTL);
1099 tmp &= ~(IF_VID_SELECT_MASK | HOST_EOT_GEN | IF_VID_MODE);
1100
1101 if (!(output->dev->mode_flags & MIPI_DSI_MODE_EOT_PACKET))
1102 tmp |= HOST_EOT_GEN;
1103
1104 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO)
1105 tmp |= IF_VID_MODE | IF_VID_SELECT(input->id) | VID_EN;
1106
1107 writel(tmp, dsi->regs + MCTL_MAIN_DATA_CTL);
1108
1109 tmp = readl(dsi->regs + MCTL_MAIN_EN) | IF_EN(input->id);
1110 writel(tmp, dsi->regs + MCTL_MAIN_EN);
1111}
1112
1113static const struct drm_bridge_funcs cdns_dsi_bridge_funcs = {
1114 .attach = cdns_dsi_bridge_attach,
1115 .mode_valid = cdns_dsi_bridge_mode_valid,
1116 .disable = cdns_dsi_bridge_disable,
1117 .enable = cdns_dsi_bridge_enable,
1118};
1119
1120static int cdns_dsi_attach(struct mipi_dsi_host *host,
1121 struct mipi_dsi_device *dev)
1122{
1123 struct cdns_dsi *dsi = to_cdns_dsi(host);
1124 struct cdns_dsi_output *output = &dsi->output;
1125 struct cdns_dsi_input *input = &dsi->input;
1126 struct drm_bridge *bridge;
1127 struct drm_panel *panel;
1128 struct device_node *np;
1129 int ret;
1130
1131 /*
1132 * We currently do not support connecting several DSI devices to the
1133 * same host. In order to support that we'd need the DRM bridge
1134 * framework to allow dynamic reconfiguration of the bridge chain.
1135 */
1136 if (output->dev)
1137 return -EBUSY;
1138
1139 /* We do not support burst mode yet. */
1140 if (dev->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
1141 return -ENOTSUPP;
1142
1143 /*
1144 * The host <-> device link might be described using an OF-graph
1145 * representation, in this case we extract the device of_node from
1146 * this representation, otherwise we use dsidev->dev.of_node which
1147 * should have been filled by the core.
1148 */
1149 np = of_graph_get_remote_node(dsi->base.dev->of_node, DSI_OUTPUT_PORT,
1150 dev->channel);
1151 if (!np)
1152 np = of_node_get(dev->dev.of_node);
1153
1154 panel = of_drm_find_panel(np);
1155 if (panel) {
1156 bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
1157 } else {
1158 bridge = of_drm_find_bridge(dev->dev.of_node);
1159 if (!bridge)
1160 bridge = ERR_PTR(-EINVAL);
1161 }
1162
1163 of_node_put(np);
1164
1165 if (IS_ERR(bridge)) {
1166 ret = PTR_ERR(bridge);
1167 dev_err(host->dev, "failed to add DSI device %s (err = %d)",
1168 dev->name, ret);
1169 return ret;
1170 }
1171
1172 output->dev = dev;
1173 output->bridge = bridge;
1174 output->panel = panel;
1175
1176 /*
1177 * The DSI output has been properly configured, we can now safely
1178 * register the input to the bridge framework so that it can take place
1179 * in a display pipeline.
1180 */
1181 drm_bridge_add(&input->bridge);
1182
1183 return 0;
1184}
1185
1186static int cdns_dsi_detach(struct mipi_dsi_host *host,
1187 struct mipi_dsi_device *dev)
1188{
1189 struct cdns_dsi *dsi = to_cdns_dsi(host);
1190 struct cdns_dsi_output *output = &dsi->output;
1191 struct cdns_dsi_input *input = &dsi->input;
1192
1193 drm_bridge_remove(&input->bridge);
1194 if (output->panel)
1195 drm_panel_bridge_remove(output->bridge);
1196
1197 return 0;
1198}
1199
1200static irqreturn_t cdns_dsi_interrupt(int irq, void *data)
1201{
1202 struct cdns_dsi *dsi = data;
1203 irqreturn_t ret = IRQ_NONE;
1204 u32 flag, ctl;
1205
1206 flag = readl(dsi->regs + DIRECT_CMD_STS_FLAG);
1207 if (flag) {
1208 ctl = readl(dsi->regs + DIRECT_CMD_STS_CTL);
1209 ctl &= ~flag;
1210 writel(ctl, dsi->regs + DIRECT_CMD_STS_CTL);
1211 complete(&dsi->direct_cmd_comp);
1212 ret = IRQ_HANDLED;
1213 }
1214
1215 return ret;
1216}
1217
1218static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host,
1219 const struct mipi_dsi_msg *msg)
1220{
1221 struct cdns_dsi *dsi = to_cdns_dsi(host);
1222 u32 cmd, sts, val, wait = WRITE_COMPLETED, ctl = 0;
1223 struct mipi_dsi_packet packet;
1224 int ret, i, tx_len, rx_len;
1225
1226 ret = pm_runtime_get_sync(host->dev);
1227 if (ret < 0)
1228 return ret;
1229
1230 cdns_dsi_init_link(dsi);
1231
1232 ret = mipi_dsi_create_packet(&packet, msg);
1233 if (ret)
1234 goto out;
1235
1236 tx_len = msg->tx_buf ? msg->tx_len : 0;
1237 rx_len = msg->rx_buf ? msg->rx_len : 0;
1238
1239 /* For read operations, the maximum TX len is 2. */
1240 if (rx_len && tx_len > 2) {
1241 ret = -ENOTSUPP;
1242 goto out;
1243 }
1244
1245 /* TX len is limited by the CMD FIFO depth. */
1246 if (tx_len > dsi->direct_cmd_fifo_depth) {
1247 ret = -ENOTSUPP;
1248 goto out;
1249 }
1250
1251 /* RX len is limited by the RX FIFO depth. */
1252 if (rx_len > dsi->rx_fifo_depth) {
1253 ret = -ENOTSUPP;
1254 goto out;
1255 }
1256
1257 cmd = CMD_SIZE(tx_len) | CMD_VCHAN_ID(msg->channel) |
1258 CMD_DATATYPE(msg->type);
1259
1260 if (msg->flags & MIPI_DSI_MSG_USE_LPM)
1261 cmd |= CMD_LP_EN;
1262
1263 if (mipi_dsi_packet_format_is_long(msg->type))
1264 cmd |= CMD_LONG;
1265
1266 if (rx_len) {
1267 cmd |= READ_CMD;
1268 wait = READ_COMPLETED_WITH_ERR | READ_COMPLETED;
1269 ctl = READ_EN | BTA_EN;
1270 } else if (msg->flags & MIPI_DSI_MSG_REQ_ACK) {
1271 cmd |= BTA_REQ;
1272 wait = ACK_WITH_ERR_RCVD | ACK_RCVD;
1273 ctl = BTA_EN;
1274 }
1275
1276 writel(readl(dsi->regs + MCTL_MAIN_DATA_CTL) | ctl,
1277 dsi->regs + MCTL_MAIN_DATA_CTL);
1278
1279 writel(cmd, dsi->regs + DIRECT_CMD_MAIN_SETTINGS);
1280
1281 for (i = 0; i < tx_len; i += 4) {
1282 const u8 *buf = msg->tx_buf;
1283 int j;
1284
1285 val = 0;
1286 for (j = 0; j < 4 && j + i < tx_len; j++)
1287 val |= (u32)buf[i + j] << (8 * j);
1288
1289 writel(val, dsi->regs + DIRECT_CMD_WRDATA);
1290 }
1291
1292 /* Clear status flags before sending the command. */
1293 writel(wait, dsi->regs + DIRECT_CMD_STS_CLR);
1294 writel(wait, dsi->regs + DIRECT_CMD_STS_CTL);
1295 reinit_completion(&dsi->direct_cmd_comp);
1296 writel(0, dsi->regs + DIRECT_CMD_SEND);
1297
1298 wait_for_completion_timeout(&dsi->direct_cmd_comp,
1299 msecs_to_jiffies(1000));
1300
1301 sts = readl(dsi->regs + DIRECT_CMD_STS);
1302 writel(wait, dsi->regs + DIRECT_CMD_STS_CLR);
1303 writel(0, dsi->regs + DIRECT_CMD_STS_CTL);
1304
1305 writel(readl(dsi->regs + MCTL_MAIN_DATA_CTL) & ~ctl,
1306 dsi->regs + MCTL_MAIN_DATA_CTL);
1307
1308 /* We did not receive the events we were waiting for. */
1309 if (!(sts & wait)) {
1310 ret = -ETIMEDOUT;
1311 goto out;
1312 }
1313
1314 /* 'READ' or 'WRITE with ACK' failed. */
1315 if (sts & (READ_COMPLETED_WITH_ERR | ACK_WITH_ERR_RCVD)) {
1316 ret = -EIO;
1317 goto out;
1318 }
1319
1320 for (i = 0; i < rx_len; i += 4) {
1321 u8 *buf = msg->rx_buf;
1322 int j;
1323
1324 val = readl(dsi->regs + DIRECT_CMD_RDDATA);
1325 for (j = 0; j < 4 && j + i < rx_len; j++)
1326 buf[i + j] = val >> (8 * j);
1327 }
1328
1329out:
1330 pm_runtime_put(host->dev);
1331 return ret;
1332}
1333
1334static const struct mipi_dsi_host_ops cdns_dsi_ops = {
1335 .attach = cdns_dsi_attach,
1336 .detach = cdns_dsi_detach,
1337 .transfer = cdns_dsi_transfer,
1338};
1339
1340static int cdns_dsi_resume(struct device *dev)
1341{
1342 struct cdns_dsi *dsi = dev_get_drvdata(dev);
1343
1344 reset_control_deassert(dsi->dsi_p_rst);
1345 clk_prepare_enable(dsi->dsi_p_clk);
1346 clk_prepare_enable(dsi->dsi_sys_clk);
1347 clk_prepare_enable(dsi->dphy->psm_clk);
1348 clk_prepare_enable(dsi->dphy->pll_ref_clk);
1349
1350 return 0;
1351}
1352
1353static int cdns_dsi_suspend(struct device *dev)
1354{
1355 struct cdns_dsi *dsi = dev_get_drvdata(dev);
1356
1357 clk_disable_unprepare(dsi->dphy->pll_ref_clk);
1358 clk_disable_unprepare(dsi->dphy->psm_clk);
1359 clk_disable_unprepare(dsi->dsi_sys_clk);
1360 clk_disable_unprepare(dsi->dsi_p_clk);
1361 reset_control_assert(dsi->dsi_p_rst);
1362 dsi->link_initialized = false;
1363 return 0;
1364}
1365
1366static UNIVERSAL_DEV_PM_OPS(cdns_dsi_pm_ops, cdns_dsi_suspend, cdns_dsi_resume,
1367 NULL);
1368
1369static unsigned long cdns_dphy_ref_get_wakeup_time_ns(struct cdns_dphy *dphy)
1370{
1371 /* Default wakeup time is 800 ns (in a simulated environment). */
1372 return 800;
1373}
1374
1375static void cdns_dphy_ref_set_pll_cfg(struct cdns_dphy *dphy,
1376 const struct cdns_dphy_cfg *cfg)
1377{
1378 u32 fbdiv_low, fbdiv_high;
1379
1380 fbdiv_low = (cfg->pll_fbdiv / 4) - 2;
1381 fbdiv_high = cfg->pll_fbdiv - fbdiv_low - 2;
1382
1383 writel(DPHY_CMN_IPDIV_FROM_REG | DPHY_CMN_OPDIV_FROM_REG |
1384 DPHY_CMN_IPDIV(cfg->pll_ipdiv) |
1385 DPHY_CMN_OPDIV(cfg->pll_opdiv),
1386 dphy->regs + DPHY_CMN_OPIPDIV);
1387 writel(DPHY_CMN_FBDIV_FROM_REG |
1388 DPHY_CMN_FBDIV_VAL(fbdiv_low, fbdiv_high),
1389 dphy->regs + DPHY_CMN_FBDIV);
1390 writel(DPHY_CMN_PWM_HIGH(6) | DPHY_CMN_PWM_LOW(0x101) |
1391 DPHY_CMN_PWM_DIV(0x8),
1392 dphy->regs + DPHY_CMN_PWM);
1393}
1394
1395static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div)
1396{
1397 writel(DPHY_PSM_CFG_FROM_REG | DPHY_PSM_CLK_DIV(div),
1398 dphy->regs + DPHY_PSM_CFG);
1399}
1400
1401/*
1402 * This is the reference implementation of DPHY hooks. Specific integration of
1403 * this IP may have to re-implement some of them depending on how they decided
1404 * to wire things in the SoC.
1405 */
1406static const struct cdns_dphy_ops ref_dphy_ops = {
1407 .get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
1408 .set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
1409 .set_psm_div = cdns_dphy_ref_set_psm_div,
1410};
1411
1412static const struct of_device_id cdns_dphy_of_match[] = {
1413 { .compatible = "cdns,dphy", .data = &ref_dphy_ops },
1414 { /* sentinel */ },
1415};
1416
1417static struct cdns_dphy *cdns_dphy_probe(struct platform_device *pdev)
1418{
1419 const struct of_device_id *match;
1420 struct cdns_dphy *dphy;
1421 struct of_phandle_args args;
1422 struct resource res;
1423 int ret;
1424
1425 ret = of_parse_phandle_with_args(pdev->dev.of_node, "phys",
1426 "#phy-cells", 0, &args);
1427 if (ret)
1428 return ERR_PTR(-ENOENT);
1429
1430 match = of_match_node(cdns_dphy_of_match, args.np);
1431 if (!match || !match->data)
1432 return ERR_PTR(-EINVAL);
1433
1434 dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
1435 if (!dphy)
1436 return ERR_PTR(-ENOMEM);
1437
1438 dphy->ops = match->data;
1439
1440 ret = of_address_to_resource(args.np, 0, &res);
1441 if (ret)
1442 return ERR_PTR(ret);
1443
1444 dphy->regs = devm_ioremap_resource(&pdev->dev, &res);
1445 if (IS_ERR(dphy->regs))
1446 return ERR_CAST(dphy->regs);
1447
1448 dphy->psm_clk = of_clk_get_by_name(args.np, "psm");
1449 if (IS_ERR(dphy->psm_clk))
1450 return ERR_CAST(dphy->psm_clk);
1451
1452 dphy->pll_ref_clk = of_clk_get_by_name(args.np, "pll_ref");
1453 if (IS_ERR(dphy->pll_ref_clk)) {
1454 ret = PTR_ERR(dphy->pll_ref_clk);
1455 goto err_put_psm_clk;
1456 }
1457
1458 if (dphy->ops->probe) {
1459 ret = dphy->ops->probe(dphy);
1460 if (ret)
1461 goto err_put_pll_ref_clk;
1462 }
1463
1464 return dphy;
1465
1466err_put_pll_ref_clk:
1467 clk_put(dphy->pll_ref_clk);
1468
1469err_put_psm_clk:
1470 clk_put(dphy->psm_clk);
1471
1472 return ERR_PTR(ret);
1473}
1474
1475static void cdns_dphy_remove(struct cdns_dphy *dphy)
1476{
1477 if (dphy->ops->remove)
1478 dphy->ops->remove(dphy);
1479
1480 clk_put(dphy->pll_ref_clk);
1481 clk_put(dphy->psm_clk);
1482}
1483
1484static int cdns_dsi_drm_probe(struct platform_device *pdev)
1485{
1486 struct cdns_dsi *dsi;
1487 struct cdns_dsi_input *input;
1488 struct resource *res;
1489 int ret, irq;
1490 u32 val;
1491
1492 dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
1493 if (!dsi)
1494 return -ENOMEM;
1495
1496 platform_set_drvdata(pdev, dsi);
1497
1498 input = &dsi->input;
1499
1500 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1501 dsi->regs = devm_ioremap_resource(&pdev->dev, res);
1502 if (IS_ERR(dsi->regs))
1503 return PTR_ERR(dsi->regs);
1504
1505 dsi->dsi_p_clk = devm_clk_get(&pdev->dev, "dsi_p_clk");
1506 if (IS_ERR(dsi->dsi_p_clk))
1507 return PTR_ERR(dsi->dsi_p_clk);
1508
1509 dsi->dsi_p_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
1510 "dsi_p_rst");
1511 if (IS_ERR(dsi->dsi_p_rst))
1512 return PTR_ERR(dsi->dsi_p_rst);
1513
1514 dsi->dsi_sys_clk = devm_clk_get(&pdev->dev, "dsi_sys_clk");
1515 if (IS_ERR(dsi->dsi_sys_clk))
1516 return PTR_ERR(dsi->dsi_sys_clk);
1517
1518 irq = platform_get_irq(pdev, 0);
1519 if (irq < 0)
1520 return irq;
1521
1522 dsi->dphy = cdns_dphy_probe(pdev);
1523 if (IS_ERR(dsi->dphy))
1524 return PTR_ERR(dsi->dphy);
1525
1526 ret = clk_prepare_enable(dsi->dsi_p_clk);
1527 if (ret)
1528 goto err_remove_dphy;
1529
1530 val = readl(dsi->regs + ID_REG);
1531 if (REV_VENDOR_ID(val) != 0xcad) {
1532 dev_err(&pdev->dev, "invalid vendor id\n");
1533 ret = -EINVAL;
1534 goto err_disable_pclk;
1535 }
1536
1537 val = readl(dsi->regs + IP_CONF);
1538 dsi->direct_cmd_fifo_depth = 1 << (DIRCMD_FIFO_DEPTH(val) + 2);
1539 dsi->rx_fifo_depth = RX_FIFO_DEPTH(val);
1540 init_completion(&dsi->direct_cmd_comp);
1541
1542 writel(0, dsi->regs + MCTL_MAIN_DATA_CTL);
1543 writel(0, dsi->regs + MCTL_MAIN_EN);
1544 writel(0, dsi->regs + MCTL_MAIN_PHY_CTL);
1545
1546 /*
1547 * We only support the DPI input, so force input->id to
1548 * CDNS_DPI_INPUT.
1549 */
1550 input->id = CDNS_DPI_INPUT;
1551 input->bridge.funcs = &cdns_dsi_bridge_funcs;
1552 input->bridge.of_node = pdev->dev.of_node;
1553
1554 /* Mask all interrupts before registering the IRQ handler. */
1555 writel(0, dsi->regs + MCTL_MAIN_STS_CTL);
1556 writel(0, dsi->regs + MCTL_DPHY_ERR_CTL1);
1557 writel(0, dsi->regs + CMD_MODE_STS_CTL);
1558 writel(0, dsi->regs + DIRECT_CMD_STS_CTL);
1559 writel(0, dsi->regs + DIRECT_CMD_RD_STS_CTL);
1560 writel(0, dsi->regs + VID_MODE_STS_CTL);
1561 writel(0, dsi->regs + TVG_STS_CTL);
1562 writel(0, dsi->regs + DPI_IRQ_EN);
1563 ret = devm_request_irq(&pdev->dev, irq, cdns_dsi_interrupt, 0,
1564 dev_name(&pdev->dev), dsi);
1565 if (ret)
1566 goto err_disable_pclk;
1567
1568 pm_runtime_enable(&pdev->dev);
1569 dsi->base.dev = &pdev->dev;
1570 dsi->base.ops = &cdns_dsi_ops;
1571
1572 ret = mipi_dsi_host_register(&dsi->base);
1573 if (ret)
1574 goto err_disable_runtime_pm;
1575
1576 clk_disable_unprepare(dsi->dsi_p_clk);
1577
1578 return 0;
1579
1580err_disable_runtime_pm:
1581 pm_runtime_disable(&pdev->dev);
1582
1583err_disable_pclk:
1584 clk_disable_unprepare(dsi->dsi_p_clk);
1585
1586err_remove_dphy:
1587 cdns_dphy_remove(dsi->dphy);
1588
1589 return ret;
1590}
1591
1592static int cdns_dsi_drm_remove(struct platform_device *pdev)
1593{
1594 struct cdns_dsi *dsi = platform_get_drvdata(pdev);
1595
1596 mipi_dsi_host_unregister(&dsi->base);
1597 pm_runtime_disable(&pdev->dev);
1598 cdns_dphy_remove(dsi->dphy);
1599
1600 return 0;
1601}
1602
1603static const struct of_device_id cdns_dsi_of_match[] = {
1604 { .compatible = "cdns,dsi" },
1605 { },
1606};
1607
1608static struct platform_driver cdns_dsi_platform_driver = {
1609 .probe = cdns_dsi_drm_probe,
1610 .remove = cdns_dsi_drm_remove,
1611 .driver = {
1612 .name = "cdns-dsi",
1613 .of_match_table = cdns_dsi_of_match,
1614 .pm = &cdns_dsi_pm_ops,
1615 },
1616};
1617module_platform_driver(cdns_dsi_platform_driver);
1618
1619MODULE_AUTHOR("Boris Brezillon <boris.brezillon@bootlin.com>");
1620MODULE_DESCRIPTION("Cadence DSI driver");
1621MODULE_LICENSE("GPL");
1622MODULE_ALIAS("platform:cdns-dsi");
1623
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index 3b7e5c59a5e9..8f9c8a6b46de 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -152,7 +152,6 @@ static struct platform_driver snd_dw_hdmi_driver = {
152 .remove = snd_dw_hdmi_remove, 152 .remove = snd_dw_hdmi_remove,
153 .driver = { 153 .driver = {
154 .name = DRIVER_NAME, 154 .name = DRIVER_NAME,
155 .owner = THIS_MODULE,
156 }, 155 },
157}; 156};
158module_platform_driver(snd_dw_hdmi_driver); 157module_platform_driver(snd_dw_hdmi_driver);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 226171a3ece1..fd7999642cf8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -1,12 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0+
1/* 2/*
2 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd 3 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
3 * Copyright (C) STMicroelectronics SA 2017 4 * Copyright (C) STMicroelectronics SA 2017
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Modified by Philippe Cornu <philippe.cornu@st.com> 6 * Modified by Philippe Cornu <philippe.cornu@st.com>
11 * This generic Synopsys DesignWare MIPI DSI host driver is based on the 7 * This generic Synopsys DesignWare MIPI DSI host driver is based on the
12 * Rockchip version from rockchip/dw-mipi-dsi.c with phy & bridge APIs. 8 * Rockchip version from rockchip/dw-mipi-dsi.c with phy & bridge APIs.
@@ -775,20 +771,20 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
775 771
776 clk_prepare_enable(dsi->pclk); 772 clk_prepare_enable(dsi->pclk);
777 773
778 ret = phy_ops->get_lane_mbps(priv_data, mode, dsi->mode_flags, 774 ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi->mode_flags,
779 dsi->lanes, dsi->format, &dsi->lane_mbps); 775 dsi->lanes, dsi->format, &dsi->lane_mbps);
780 if (ret) 776 if (ret)
781 DRM_DEBUG_DRIVER("Phy get_lane_mbps() failed\n"); 777 DRM_DEBUG_DRIVER("Phy get_lane_mbps() failed\n");
782 778
783 pm_runtime_get_sync(dsi->dev); 779 pm_runtime_get_sync(dsi->dev);
784 dw_mipi_dsi_init(dsi); 780 dw_mipi_dsi_init(dsi);
785 dw_mipi_dsi_dpi_config(dsi, mode); 781 dw_mipi_dsi_dpi_config(dsi, adjusted_mode);
786 dw_mipi_dsi_packet_handler_config(dsi); 782 dw_mipi_dsi_packet_handler_config(dsi);
787 dw_mipi_dsi_video_mode_config(dsi); 783 dw_mipi_dsi_video_mode_config(dsi);
788 dw_mipi_dsi_video_packet_config(dsi, mode); 784 dw_mipi_dsi_video_packet_config(dsi, adjusted_mode);
789 dw_mipi_dsi_command_mode_config(dsi); 785 dw_mipi_dsi_command_mode_config(dsi);
790 dw_mipi_dsi_line_timer_config(dsi, mode); 786 dw_mipi_dsi_line_timer_config(dsi, adjusted_mode);
791 dw_mipi_dsi_vertical_timing_config(dsi, mode); 787 dw_mipi_dsi_vertical_timing_config(dsi, adjusted_mode);
792 788
793 dw_mipi_dsi_dphy_init(dsi); 789 dw_mipi_dsi_dphy_init(dsi);
794 dw_mipi_dsi_dphy_timing_config(dsi); 790 dw_mipi_dsi_dphy_timing_config(dsi);
@@ -802,7 +798,7 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
802 798
803 dw_mipi_dsi_dphy_enable(dsi); 799 dw_mipi_dsi_dphy_enable(dsi);
804 800
805 dw_mipi_dsi_wait_for_two_frames(mode); 801 dw_mipi_dsi_wait_for_two_frames(adjusted_mode);
806 802
807 /* Switch to cmd mode for panel-bridge pre_enable & panel prepare */ 803 /* Switch to cmd mode for panel-bridge pre_enable & panel prepare */
808 dw_mipi_dsi_set_mode(dsi, 0); 804 dw_mipi_dsi_set_mode(dsi, 0);
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 08ab7d6aea65..0fd9cf27542c 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1102,7 +1102,7 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
1102 return true; 1102 return true;
1103} 1103}
1104 1104
1105static int tc_connector_mode_valid(struct drm_connector *connector, 1105static enum drm_mode_status tc_connector_mode_valid(struct drm_connector *connector,
1106 struct drm_display_mode *mode) 1106 struct drm_display_mode *mode)
1107{ 1107{
1108 /* DPI interface clock limitation: upto 154 MHz */ 1108 /* DPI interface clock limitation: upto 154 MHz */
diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c
new file mode 100644
index 000000000000..c8b9edd5a7f4
--- /dev/null
+++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
@@ -0,0 +1,206 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * THC63LVD1024 LVDS to parallel data DRM bridge driver.
4 *
5 * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
6 */
7
8#include <drm/drmP.h>
9#include <drm/drm_bridge.h>
10#include <drm/drm_panel.h>
11
12#include <linux/gpio/consumer.h>
13#include <linux/of_graph.h>
14#include <linux/regulator/consumer.h>
15#include <linux/slab.h>
16
17enum thc63_ports {
18 THC63_LVDS_IN0,
19 THC63_LVDS_IN1,
20 THC63_RGB_OUT0,
21 THC63_RGB_OUT1,
22};
23
24struct thc63_dev {
25 struct device *dev;
26
27 struct regulator *vcc;
28
29 struct gpio_desc *pdwn;
30 struct gpio_desc *oe;
31
32 struct drm_bridge bridge;
33 struct drm_bridge *next;
34};
35
36static inline struct thc63_dev *to_thc63(struct drm_bridge *bridge)
37{
38 return container_of(bridge, struct thc63_dev, bridge);
39}
40
41static int thc63_attach(struct drm_bridge *bridge)
42{
43 struct thc63_dev *thc63 = to_thc63(bridge);
44
45 return drm_bridge_attach(bridge->encoder, thc63->next, bridge);
46}
47
48static void thc63_enable(struct drm_bridge *bridge)
49{
50 struct thc63_dev *thc63 = to_thc63(bridge);
51 int ret;
52
53 ret = regulator_enable(thc63->vcc);
54 if (ret) {
55 dev_err(thc63->dev,
56 "Failed to enable regulator \"vcc\": %d\n", ret);
57 return;
58 }
59
60 gpiod_set_value(thc63->pdwn, 0);
61 gpiod_set_value(thc63->oe, 1);
62}
63
64static void thc63_disable(struct drm_bridge *bridge)
65{
66 struct thc63_dev *thc63 = to_thc63(bridge);
67 int ret;
68
69 gpiod_set_value(thc63->oe, 0);
70 gpiod_set_value(thc63->pdwn, 1);
71
72 ret = regulator_disable(thc63->vcc);
73 if (ret)
74 dev_err(thc63->dev,
75 "Failed to disable regulator \"vcc\": %d\n", ret);
76}
77
78static const struct drm_bridge_funcs thc63_bridge_func = {
79 .attach = thc63_attach,
80 .enable = thc63_enable,
81 .disable = thc63_disable,
82};
83
84static int thc63_parse_dt(struct thc63_dev *thc63)
85{
86 struct device_node *thc63_out;
87 struct device_node *remote;
88
89 thc63_out = of_graph_get_endpoint_by_regs(thc63->dev->of_node,
90 THC63_RGB_OUT0, -1);
91 if (!thc63_out) {
92 dev_err(thc63->dev, "Missing endpoint in port@%u\n",
93 THC63_RGB_OUT0);
94 return -ENODEV;
95 }
96
97 remote = of_graph_get_remote_port_parent(thc63_out);
98 of_node_put(thc63_out);
99 if (!remote) {
100 dev_err(thc63->dev, "Endpoint in port@%u unconnected\n",
101 THC63_RGB_OUT0);
102 return -ENODEV;
103 }
104
105 if (!of_device_is_available(remote)) {
106 dev_err(thc63->dev, "port@%u remote endpoint is disabled\n",
107 THC63_RGB_OUT0);
108 of_node_put(remote);
109 return -ENODEV;
110 }
111
112 thc63->next = of_drm_find_bridge(remote);
113 of_node_put(remote);
114 if (!thc63->next)
115 return -EPROBE_DEFER;
116
117 return 0;
118}
119
120static int thc63_gpio_init(struct thc63_dev *thc63)
121{
122 thc63->oe = devm_gpiod_get_optional(thc63->dev, "oe", GPIOD_OUT_LOW);
123 if (IS_ERR(thc63->oe)) {
124 dev_err(thc63->dev, "Unable to get \"oe-gpios\": %ld\n",
125 PTR_ERR(thc63->oe));
126 return PTR_ERR(thc63->oe);
127 }
128
129 thc63->pdwn = devm_gpiod_get_optional(thc63->dev, "powerdown",
130 GPIOD_OUT_HIGH);
131 if (IS_ERR(thc63->pdwn)) {
132 dev_err(thc63->dev, "Unable to get \"powerdown-gpios\": %ld\n",
133 PTR_ERR(thc63->pdwn));
134 return PTR_ERR(thc63->pdwn);
135 }
136
137 return 0;
138}
139
140static int thc63_probe(struct platform_device *pdev)
141{
142 struct thc63_dev *thc63;
143 int ret;
144
145 thc63 = devm_kzalloc(&pdev->dev, sizeof(*thc63), GFP_KERNEL);
146 if (!thc63)
147 return -ENOMEM;
148
149 thc63->dev = &pdev->dev;
150 platform_set_drvdata(pdev, thc63);
151
152 thc63->vcc = devm_regulator_get_optional(thc63->dev, "vcc");
153 if (IS_ERR(thc63->vcc)) {
154 if (PTR_ERR(thc63->vcc) == -EPROBE_DEFER)
155 return -EPROBE_DEFER;
156
157 dev_err(thc63->dev, "Unable to get \"vcc\" supply: %ld\n",
158 PTR_ERR(thc63->vcc));
159 return PTR_ERR(thc63->vcc);
160 }
161
162 ret = thc63_gpio_init(thc63);
163 if (ret)
164 return ret;
165
166 ret = thc63_parse_dt(thc63);
167 if (ret)
168 return ret;
169
170 thc63->bridge.driver_private = thc63;
171 thc63->bridge.of_node = pdev->dev.of_node;
172 thc63->bridge.funcs = &thc63_bridge_func;
173
174 drm_bridge_add(&thc63->bridge);
175
176 return 0;
177}
178
179static int thc63_remove(struct platform_device *pdev)
180{
181 struct thc63_dev *thc63 = platform_get_drvdata(pdev);
182
183 drm_bridge_remove(&thc63->bridge);
184
185 return 0;
186}
187
188static const struct of_device_id thc63_match[] = {
189 { .compatible = "thine,thc63lvd1024", },
190 { },
191};
192MODULE_DEVICE_TABLE(of, thc63_match);
193
194static struct platform_driver thc63_driver = {
195 .probe = thc63_probe,
196 .remove = thc63_remove,
197 .driver = {
198 .name = "thc63lvd1024",
199 .of_match_table = thc63_match,
200 },
201};
202module_platform_driver(thc63_driver);
203
204MODULE_AUTHOR("Jacopo Mondi <jacopo@jmondi.org>");
205MODULE_DESCRIPTION("Thine THC63LVD1024 LVDS decoder DRM bridge driver");
206MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c825c76edc1d..895741e9cd7d 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -791,6 +791,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
791 state->src_w = val; 791 state->src_w = val;
792 } else if (property == config->prop_src_h) { 792 } else if (property == config->prop_src_h) {
793 state->src_h = val; 793 state->src_h = val;
794 } else if (property == plane->alpha_property) {
795 state->alpha = val;
794 } else if (property == plane->rotation_property) { 796 } else if (property == plane->rotation_property) {
795 if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) 797 if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
796 return -EINVAL; 798 return -EINVAL;
@@ -856,6 +858,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
856 *val = state->src_w; 858 *val = state->src_w;
857 } else if (property == config->prop_src_h) { 859 } else if (property == config->prop_src_h) {
858 *val = state->src_h; 860 *val = state->src_h;
861 } else if (property == plane->alpha_property) {
862 *val = state->alpha;
859 } else if (property == plane->rotation_property) { 863 } else if (property == plane->rotation_property) {
860 *val = state->rotation; 864 *val = state->rotation;
861 } else if (property == plane->zpos_property) { 865 } else if (property == plane->zpos_property) {
@@ -1429,7 +1433,9 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
1429{ 1433{
1430 struct drm_plane *plane = plane_state->plane; 1434 struct drm_plane *plane = plane_state->plane;
1431 struct drm_crtc_state *crtc_state; 1435 struct drm_crtc_state *crtc_state;
1432 1436 /* Nothing to do for same crtc*/
1437 if (plane_state->crtc == crtc)
1438 return 0;
1433 if (plane_state->crtc) { 1439 if (plane_state->crtc) {
1434 crtc_state = drm_atomic_get_crtc_state(plane_state->state, 1440 crtc_state = drm_atomic_get_crtc_state(plane_state->state,
1435 plane_state->crtc); 1441 plane_state->crtc);
@@ -1500,6 +1506,14 @@ EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
1500 * Otherwise, if &drm_plane_state.fence is not set this function we just set it 1506 * Otherwise, if &drm_plane_state.fence is not set this function we just set it
1501 * with the received implicit fence. In both cases this function consumes a 1507 * with the received implicit fence. In both cases this function consumes a
1502 * reference for @fence. 1508 * reference for @fence.
1509 *
1510 * This way explicit fencing can be used to overrule implicit fencing, which is
1511 * important to make explicit fencing use-cases work: One example is using one
1512 * buffer for 2 screens with different refresh rates. Implicit fencing will
1513 * clamp rendering to the refresh rate of the slower screen, whereas explicit
1514 * fence allows 2 independent render and display loops on a single buffer. If a
1515 * driver allows obeys both implicit and explicit fences for plane updates, then
1516 * it will break all the benefits of explicit fencing.
1503 */ 1517 */
1504void 1518void
1505drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, 1519drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state,
@@ -1710,11 +1724,15 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
1710 } 1724 }
1711 } 1725 }
1712 1726
1713 if (config->funcs->atomic_check) 1727 if (config->funcs->atomic_check) {
1714 ret = config->funcs->atomic_check(state->dev, state); 1728 ret = config->funcs->atomic_check(state->dev, state);
1715 1729
1716 if (ret) 1730 if (ret) {
1717 return ret; 1731 DRM_DEBUG_ATOMIC("atomic driver check for %p failed: %d\n",
1732 state, ret);
1733 return ret;
1734 }
1735 }
1718 1736
1719 if (!state->allow_modeset) { 1737 if (!state->allow_modeset) {
1720 for_each_new_crtc_in_state(state, crtc, crtc_state, i) { 1738 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index c35654591c12..130da5195f3b 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -766,7 +766,7 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
766 if (crtc_state->enable) 766 if (crtc_state->enable)
767 drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2); 767 drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
768 768
769 plane_state->visible = drm_rect_clip_scaled(src, dst, &clip, hscale, vscale); 769 plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
770 770
771 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation); 771 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
772 772
@@ -875,6 +875,11 @@ EXPORT_SYMBOL(drm_atomic_helper_check_planes);
875 * functions depend upon an updated adjusted_mode.clock to e.g. properly compute 875 * functions depend upon an updated adjusted_mode.clock to e.g. properly compute
876 * watermarks. 876 * watermarks.
877 * 877 *
878 * Note that zpos normalization will add all enable planes to the state which
879 * might not desired for some drivers.
880 * For example enable/disable of a cursor plane which have fixed zpos value
881 * would trigger all other enabled planes to be forced to the state change.
882 *
878 * RETURNS: 883 * RETURNS:
879 * Zero for success or -errno 884 * Zero for success or -errno
880 */ 885 */
@@ -887,6 +892,12 @@ int drm_atomic_helper_check(struct drm_device *dev,
887 if (ret) 892 if (ret)
888 return ret; 893 return ret;
889 894
895 if (dev->mode_config.normalize_zpos) {
896 ret = drm_atomic_normalize_zpos(dev, state);
897 if (ret)
898 return ret;
899 }
900
890 ret = drm_atomic_helper_check_planes(dev, state); 901 ret = drm_atomic_helper_check_planes(dev, state);
891 if (ret) 902 if (ret)
892 return ret; 903 return ret;
@@ -1561,6 +1572,17 @@ void drm_atomic_helper_async_commit(struct drm_device *dev,
1561 for_each_new_plane_in_state(state, plane, plane_state, i) { 1572 for_each_new_plane_in_state(state, plane, plane_state, i) {
1562 funcs = plane->helper_private; 1573 funcs = plane->helper_private;
1563 funcs->atomic_async_update(plane, plane_state); 1574 funcs->atomic_async_update(plane, plane_state);
1575
1576 /*
1577 * ->atomic_async_update() is supposed to update the
1578 * plane->state in-place, make sure at least common
1579 * properties have been properly updated.
1580 */
1581 WARN_ON_ONCE(plane->state->fb != plane_state->fb);
1582 WARN_ON_ONCE(plane->state->crtc_x != plane_state->crtc_x);
1583 WARN_ON_ONCE(plane->state->crtc_y != plane_state->crtc_y);
1584 WARN_ON_ONCE(plane->state->src_x != plane_state->src_x);
1585 WARN_ON_ONCE(plane->state->src_y != plane_state->src_y);
1564 } 1586 }
1565} 1587}
1566EXPORT_SYMBOL(drm_atomic_helper_async_commit); 1588EXPORT_SYMBOL(drm_atomic_helper_async_commit);
@@ -2659,7 +2681,7 @@ int drm_atomic_helper_disable_plane(struct drm_plane *plane,
2659 goto fail; 2681 goto fail;
2660 } 2682 }
2661 2683
2662 if (plane_state->crtc && (plane == plane->crtc->cursor)) 2684 if (plane_state->crtc && plane_state->crtc->cursor == plane)
2663 plane_state->state->legacy_cursor_update = true; 2685 plane_state->state->legacy_cursor_update = true;
2664 2686
2665 ret = __drm_atomic_helper_disable_plane(plane, plane_state); 2687 ret = __drm_atomic_helper_disable_plane(plane, plane_state);
@@ -2881,31 +2903,9 @@ commit:
2881 return 0; 2903 return 0;
2882} 2904}
2883 2905
2884/** 2906static int __drm_atomic_helper_disable_all(struct drm_device *dev,
2885 * drm_atomic_helper_disable_all - disable all currently active outputs 2907 struct drm_modeset_acquire_ctx *ctx,
2886 * @dev: DRM device 2908 bool clean_old_fbs)
2887 * @ctx: lock acquisition context
2888 *
2889 * Loops through all connectors, finding those that aren't turned off and then
2890 * turns them off by setting their DPMS mode to OFF and deactivating the CRTC
2891 * that they are connected to.
2892 *
2893 * This is used for example in suspend/resume to disable all currently active
2894 * functions when suspending. If you just want to shut down everything at e.g.
2895 * driver unload, look at drm_atomic_helper_shutdown().
2896 *
2897 * Note that if callers haven't already acquired all modeset locks this might
2898 * return -EDEADLK, which must be handled by calling drm_modeset_backoff().
2899 *
2900 * Returns:
2901 * 0 on success or a negative error code on failure.
2902 *
2903 * See also:
2904 * drm_atomic_helper_suspend(), drm_atomic_helper_resume() and
2905 * drm_atomic_helper_shutdown().
2906 */
2907int drm_atomic_helper_disable_all(struct drm_device *dev,
2908 struct drm_modeset_acquire_ctx *ctx)
2909{ 2909{
2910 struct drm_atomic_state *state; 2910 struct drm_atomic_state *state;
2911 struct drm_connector_state *conn_state; 2911 struct drm_connector_state *conn_state;
@@ -2957,8 +2957,11 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
2957 goto free; 2957 goto free;
2958 2958
2959 drm_atomic_set_fb_for_plane(plane_state, NULL); 2959 drm_atomic_set_fb_for_plane(plane_state, NULL);
2960 plane_mask |= BIT(drm_plane_index(plane)); 2960
2961 plane->old_fb = plane->fb; 2961 if (clean_old_fbs) {
2962 plane->old_fb = plane->fb;
2963 plane_mask |= BIT(drm_plane_index(plane));
2964 }
2962 } 2965 }
2963 2966
2964 ret = drm_atomic_commit(state); 2967 ret = drm_atomic_commit(state);
@@ -2969,6 +2972,34 @@ free:
2969 return ret; 2972 return ret;
2970} 2973}
2971 2974
2975/**
2976 * drm_atomic_helper_disable_all - disable all currently active outputs
2977 * @dev: DRM device
2978 * @ctx: lock acquisition context
2979 *
2980 * Loops through all connectors, finding those that aren't turned off and then
2981 * turns them off by setting their DPMS mode to OFF and deactivating the CRTC
2982 * that they are connected to.
2983 *
2984 * This is used for example in suspend/resume to disable all currently active
2985 * functions when suspending. If you just want to shut down everything at e.g.
2986 * driver unload, look at drm_atomic_helper_shutdown().
2987 *
2988 * Note that if callers haven't already acquired all modeset locks this might
2989 * return -EDEADLK, which must be handled by calling drm_modeset_backoff().
2990 *
2991 * Returns:
2992 * 0 on success or a negative error code on failure.
2993 *
2994 * See also:
2995 * drm_atomic_helper_suspend(), drm_atomic_helper_resume() and
2996 * drm_atomic_helper_shutdown().
2997 */
2998int drm_atomic_helper_disable_all(struct drm_device *dev,
2999 struct drm_modeset_acquire_ctx *ctx)
3000{
3001 return __drm_atomic_helper_disable_all(dev, ctx, false);
3002}
2972EXPORT_SYMBOL(drm_atomic_helper_disable_all); 3003EXPORT_SYMBOL(drm_atomic_helper_disable_all);
2973 3004
2974/** 3005/**
@@ -2991,7 +3022,7 @@ void drm_atomic_helper_shutdown(struct drm_device *dev)
2991 while (1) { 3022 while (1) {
2992 ret = drm_modeset_lock_all_ctx(dev, &ctx); 3023 ret = drm_modeset_lock_all_ctx(dev, &ctx);
2993 if (!ret) 3024 if (!ret)
2994 ret = drm_atomic_helper_disable_all(dev, &ctx); 3025 ret = __drm_atomic_helper_disable_all(dev, &ctx, true);
2995 3026
2996 if (ret != -EDEADLK) 3027 if (ret != -EDEADLK)
2997 break; 3028 break;
@@ -3095,14 +3126,14 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
3095 struct drm_connector_state *new_conn_state; 3126 struct drm_connector_state *new_conn_state;
3096 struct drm_crtc *crtc; 3127 struct drm_crtc *crtc;
3097 struct drm_crtc_state *new_crtc_state; 3128 struct drm_crtc_state *new_crtc_state;
3098 unsigned plane_mask = 0;
3099 struct drm_device *dev = state->dev;
3100 int ret;
3101 3129
3102 state->acquire_ctx = ctx; 3130 state->acquire_ctx = ctx;
3103 3131
3104 for_each_new_plane_in_state(state, plane, new_plane_state, i) { 3132 for_each_new_plane_in_state(state, plane, new_plane_state, i) {
3105 plane_mask |= BIT(drm_plane_index(plane)); 3133 WARN_ON(plane->crtc != new_plane_state->crtc);
3134 WARN_ON(plane->fb != new_plane_state->fb);
3135 WARN_ON(plane->old_fb);
3136
3106 state->planes[i].old_state = plane->state; 3137 state->planes[i].old_state = plane->state;
3107 } 3138 }
3108 3139
@@ -3112,11 +3143,7 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
3112 for_each_new_connector_in_state(state, connector, new_conn_state, i) 3143 for_each_new_connector_in_state(state, connector, new_conn_state, i)
3113 state->connectors[i].old_state = connector->state; 3144 state->connectors[i].old_state = connector->state;
3114 3145
3115 ret = drm_atomic_commit(state); 3146 return drm_atomic_commit(state);
3116 if (plane_mask)
3117 drm_atomic_clean_old_fb(dev, plane_mask, ret);
3118
3119 return ret;
3120} 3147}
3121EXPORT_SYMBOL(drm_atomic_helper_commit_duplicated_state); 3148EXPORT_SYMBOL(drm_atomic_helper_commit_duplicated_state);
3122 3149
@@ -3484,6 +3511,10 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
3484 if (plane->state) { 3511 if (plane->state) {
3485 plane->state->plane = plane; 3512 plane->state->plane = plane;
3486 plane->state->rotation = DRM_MODE_ROTATE_0; 3513 plane->state->rotation = DRM_MODE_ROTATE_0;
3514
3515 /* Reset the alpha value to fully opaque if it matters */
3516 if (plane->alpha_property)
3517 plane->state->alpha = plane->alpha_property->values[1];
3487 } 3518 }
3488} 3519}
3489EXPORT_SYMBOL(drm_atomic_helper_plane_reset); 3520EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 5a81e1b4c076..a16a74d7e15e 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -88,6 +88,13 @@
88 * On top of this basic transformation additional properties can be exposed by 88 * On top of this basic transformation additional properties can be exposed by
89 * the driver: 89 * the driver:
90 * 90 *
91 * alpha:
92 * Alpha is setup with drm_plane_create_alpha_property(). It controls the
93 * plane-wide opacity, from transparent (0) to opaque (0xffff). It can be
94 * combined with pixel alpha.
95 * The pixel values in the framebuffers are expected to not be
96 * pre-multiplied by the global alpha associated to the plane.
97 *
91 * rotation: 98 * rotation:
92 * Rotation is set up with drm_plane_create_rotation_property(). It adds a 99 * Rotation is set up with drm_plane_create_rotation_property(). It adds a
93 * rotation and reflection step between the source and destination rectangles. 100 * rotation and reflection step between the source and destination rectangles.
@@ -106,6 +113,38 @@
106 */ 113 */
107 114
108/** 115/**
116 * drm_plane_create_alpha_property - create a new alpha property
117 * @plane: drm plane
118 *
119 * This function creates a generic, mutable, alpha property and enables support
120 * for it in the DRM core. It is attached to @plane.
121 *
122 * The alpha property will be allowed to be within the bounds of 0
123 * (transparent) to 0xffff (opaque).
124 *
125 * Returns:
126 * 0 on success, negative error code on failure.
127 */
128int drm_plane_create_alpha_property(struct drm_plane *plane)
129{
130 struct drm_property *prop;
131
132 prop = drm_property_create_range(plane->dev, 0, "alpha",
133 0, DRM_BLEND_ALPHA_OPAQUE);
134 if (!prop)
135 return -ENOMEM;
136
137 drm_object_attach_property(&plane->base, prop, DRM_BLEND_ALPHA_OPAQUE);
138 plane->alpha_property = prop;
139
140 if (plane->state)
141 plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
142
143 return 0;
144}
145EXPORT_SYMBOL(drm_plane_create_alpha_property);
146
147/**
109 * drm_plane_create_rotation_property - create a new rotation property 148 * drm_plane_create_rotation_property - create a new rotation property
110 * @plane: drm plane 149 * @plane: drm plane
111 * @rotation: initial value of the rotation property 150 * @rotation: initial value of the rotation property
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b3cde897cd80..9b9ba5d5ec0c 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1069,7 +1069,7 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
1069 goto nomem; 1069 goto nomem;
1070 1070
1071 for (i = 0; i < num_modes; i++) 1071 for (i = 0; i < num_modes; i++)
1072 drm_property_add_enum(dev->mode_config.tv_mode_property, i, 1072 drm_property_add_enum(dev->mode_config.tv_mode_property,
1073 i, modes[i]); 1073 i, modes[i]);
1074 1074
1075 dev->mode_config.tv_brightness_property = 1075 dev->mode_config.tv_brightness_property =
@@ -1156,7 +1156,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
1156{ 1156{
1157 struct drm_device *dev = connector->dev; 1157 struct drm_device *dev = connector->dev;
1158 struct drm_property *scaling_mode_property; 1158 struct drm_property *scaling_mode_property;
1159 int i, j = 0; 1159 int i;
1160 const unsigned valid_scaling_mode_mask = 1160 const unsigned valid_scaling_mode_mask =
1161 (1U << ARRAY_SIZE(drm_scaling_mode_enum_list)) - 1; 1161 (1U << ARRAY_SIZE(drm_scaling_mode_enum_list)) - 1;
1162 1162
@@ -1177,7 +1177,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
1177 if (!(BIT(i) & scaling_mode_mask)) 1177 if (!(BIT(i) & scaling_mode_mask))
1178 continue; 1178 continue;
1179 1179
1180 ret = drm_property_add_enum(scaling_mode_property, j++, 1180 ret = drm_property_add_enum(scaling_mode_property,
1181 drm_scaling_mode_enum_list[i].type, 1181 drm_scaling_mode_enum_list[i].type,
1182 drm_scaling_mode_enum_list[i].name); 1182 drm_scaling_mode_enum_list[i].name);
1183 1183
@@ -1531,8 +1531,10 @@ static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *conne
1531 return connector->encoder; 1531 return connector->encoder;
1532} 1532}
1533 1533
1534static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode, 1534static bool
1535 const struct drm_file *file_priv) 1535drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
1536 const struct list_head *export_list,
1537 const struct drm_file *file_priv)
1536{ 1538{
1537 /* 1539 /*
1538 * If user-space hasn't configured the driver to expose the stereo 3D 1540 * If user-space hasn't configured the driver to expose the stereo 3D
@@ -1540,6 +1542,23 @@ static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
1540 */ 1542 */
1541 if (!file_priv->stereo_allowed && drm_mode_is_stereo(mode)) 1543 if (!file_priv->stereo_allowed && drm_mode_is_stereo(mode))
1542 return false; 1544 return false;
1545 /*
1546 * If user-space hasn't configured the driver to expose the modes
1547 * with aspect-ratio, don't expose them. However if such a mode
1548 * is unique, let it be exposed, but reset the aspect-ratio flags
1549 * while preparing the list of user-modes.
1550 */
1551 if (!file_priv->aspect_ratio_allowed) {
1552 struct drm_display_mode *mode_itr;
1553
1554 list_for_each_entry(mode_itr, export_list, export_head)
1555 if (drm_mode_match(mode_itr, mode,
1556 DRM_MODE_MATCH_TIMINGS |
1557 DRM_MODE_MATCH_CLOCK |
1558 DRM_MODE_MATCH_FLAGS |
1559 DRM_MODE_MATCH_3D_FLAGS))
1560 return false;
1561 }
1543 1562
1544 return true; 1563 return true;
1545} 1564}
@@ -1559,6 +1578,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
1559 struct drm_mode_modeinfo u_mode; 1578 struct drm_mode_modeinfo u_mode;
1560 struct drm_mode_modeinfo __user *mode_ptr; 1579 struct drm_mode_modeinfo __user *mode_ptr;
1561 uint32_t __user *encoder_ptr; 1580 uint32_t __user *encoder_ptr;
1581 LIST_HEAD(export_list);
1562 1582
1563 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1583 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1564 return -EINVAL; 1584 return -EINVAL;
@@ -1607,21 +1627,31 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
1607 1627
1608 /* delayed so we get modes regardless of pre-fill_modes state */ 1628 /* delayed so we get modes regardless of pre-fill_modes state */
1609 list_for_each_entry(mode, &connector->modes, head) 1629 list_for_each_entry(mode, &connector->modes, head)
1610 if (drm_mode_expose_to_userspace(mode, file_priv)) 1630 if (drm_mode_expose_to_userspace(mode, &export_list,
1631 file_priv)) {
1632 list_add_tail(&mode->export_head, &export_list);
1611 mode_count++; 1633 mode_count++;
1634 }
1612 1635
1613 /* 1636 /*
1614 * This ioctl is called twice, once to determine how much space is 1637 * This ioctl is called twice, once to determine how much space is
1615 * needed, and the 2nd time to fill it. 1638 * needed, and the 2nd time to fill it.
1639 * The modes that need to be exposed to the user are maintained in the
1640 * 'export_list'. When the ioctl is called first time to determine the,
1641 * space, the export_list gets filled, to find the no.of modes. In the
1642 * 2nd time, the user modes are filled, one by one from the export_list.
1616 */ 1643 */
1617 if ((out_resp->count_modes >= mode_count) && mode_count) { 1644 if ((out_resp->count_modes >= mode_count) && mode_count) {
1618 copied = 0; 1645 copied = 0;
1619 mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr; 1646 mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;
1620 list_for_each_entry(mode, &connector->modes, head) { 1647 list_for_each_entry(mode, &export_list, export_head) {
1621 if (!drm_mode_expose_to_userspace(mode, file_priv))
1622 continue;
1623
1624 drm_mode_convert_to_umode(&u_mode, mode); 1648 drm_mode_convert_to_umode(&u_mode, mode);
1649 /*
1650 * Reset aspect ratio flags of user-mode, if modes with
1651 * aspect-ratio are not supported.
1652 */
1653 if (!file_priv->aspect_ratio_allowed)
1654 u_mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
1625 if (copy_to_user(mode_ptr + copied, 1655 if (copy_to_user(mode_ptr + copied,
1626 &u_mode, sizeof(u_mode))) { 1656 &u_mode, sizeof(u_mode))) {
1627 ret = -EFAULT; 1657 ret = -EFAULT;
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 03583887cfec..98a36e6c69ad 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -402,6 +402,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
402{ 402{
403 struct drm_mode_crtc *crtc_resp = data; 403 struct drm_mode_crtc *crtc_resp = data;
404 struct drm_crtc *crtc; 404 struct drm_crtc *crtc;
405 struct drm_plane *plane;
405 406
406 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 407 if (!drm_core_check_feature(dev, DRIVER_MODESET))
407 return -EINVAL; 408 return -EINVAL;
@@ -410,34 +411,36 @@ int drm_mode_getcrtc(struct drm_device *dev,
410 if (!crtc) 411 if (!crtc)
411 return -ENOENT; 412 return -ENOENT;
412 413
414 plane = crtc->primary;
415
413 crtc_resp->gamma_size = crtc->gamma_size; 416 crtc_resp->gamma_size = crtc->gamma_size;
414 417
415 drm_modeset_lock(&crtc->primary->mutex, NULL); 418 drm_modeset_lock(&plane->mutex, NULL);
416 if (crtc->primary->state && crtc->primary->state->fb) 419 if (plane->state && plane->state->fb)
417 crtc_resp->fb_id = crtc->primary->state->fb->base.id; 420 crtc_resp->fb_id = plane->state->fb->base.id;
418 else if (!crtc->primary->state && crtc->primary->fb) 421 else if (!plane->state && plane->fb)
419 crtc_resp->fb_id = crtc->primary->fb->base.id; 422 crtc_resp->fb_id = plane->fb->base.id;
420 else 423 else
421 crtc_resp->fb_id = 0; 424 crtc_resp->fb_id = 0;
422 425
423 if (crtc->primary->state) { 426 if (plane->state) {
424 crtc_resp->x = crtc->primary->state->src_x >> 16; 427 crtc_resp->x = plane->state->src_x >> 16;
425 crtc_resp->y = crtc->primary->state->src_y >> 16; 428 crtc_resp->y = plane->state->src_y >> 16;
426 } 429 }
427 drm_modeset_unlock(&crtc->primary->mutex); 430 drm_modeset_unlock(&plane->mutex);
428 431
429 drm_modeset_lock(&crtc->mutex, NULL); 432 drm_modeset_lock(&crtc->mutex, NULL);
430 if (crtc->state) { 433 if (crtc->state) {
431 if (crtc->state->enable) { 434 if (crtc->state->enable) {
432 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode); 435 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
433 crtc_resp->mode_valid = 1; 436 crtc_resp->mode_valid = 1;
434
435 } else { 437 } else {
436 crtc_resp->mode_valid = 0; 438 crtc_resp->mode_valid = 0;
437 } 439 }
438 } else { 440 } else {
439 crtc_resp->x = crtc->x; 441 crtc_resp->x = crtc->x;
440 crtc_resp->y = crtc->y; 442 crtc_resp->y = crtc->y;
443
441 if (crtc->enabled) { 444 if (crtc->enabled) {
442 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode); 445 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
443 crtc_resp->mode_valid = 1; 446 crtc_resp->mode_valid = 1;
@@ -446,6 +449,8 @@ int drm_mode_getcrtc(struct drm_device *dev,
446 crtc_resp->mode_valid = 0; 449 crtc_resp->mode_valid = 0;
447 } 450 }
448 } 451 }
452 if (!file_priv->aspect_ratio_allowed)
453 crtc_resp->mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
449 drm_modeset_unlock(&crtc->mutex); 454 drm_modeset_unlock(&crtc->mutex);
450 455
451 return 0; 456 return 0;
@@ -471,7 +476,7 @@ static int __drm_mode_set_config_internal(struct drm_mode_set *set,
471 476
472 ret = crtc->funcs->set_config(set, ctx); 477 ret = crtc->funcs->set_config(set, ctx);
473 if (ret == 0) { 478 if (ret == 0) {
474 crtc->primary->crtc = crtc; 479 crtc->primary->crtc = fb ? crtc : NULL;
475 crtc->primary->fb = fb; 480 crtc->primary->fb = fb;
476 } 481 }
477 482
@@ -554,6 +559,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
554 struct drm_mode_config *config = &dev->mode_config; 559 struct drm_mode_config *config = &dev->mode_config;
555 struct drm_mode_crtc *crtc_req = data; 560 struct drm_mode_crtc *crtc_req = data;
556 struct drm_crtc *crtc; 561 struct drm_crtc *crtc;
562 struct drm_plane *plane;
557 struct drm_connector **connector_set = NULL, *connector; 563 struct drm_connector **connector_set = NULL, *connector;
558 struct drm_framebuffer *fb = NULL; 564 struct drm_framebuffer *fb = NULL;
559 struct drm_display_mode *mode = NULL; 565 struct drm_display_mode *mode = NULL;
@@ -580,22 +586,33 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
580 } 586 }
581 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); 587 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
582 588
589 plane = crtc->primary;
590
583 mutex_lock(&crtc->dev->mode_config.mutex); 591 mutex_lock(&crtc->dev->mode_config.mutex);
584 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); 592 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
585retry: 593retry:
586 ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx); 594 ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
587 if (ret) 595 if (ret)
588 goto out; 596 goto out;
597
589 if (crtc_req->mode_valid) { 598 if (crtc_req->mode_valid) {
590 /* If we have a mode we need a framebuffer. */ 599 /* If we have a mode we need a framebuffer. */
591 /* If we pass -1, set the mode with the currently bound fb */ 600 /* If we pass -1, set the mode with the currently bound fb */
592 if (crtc_req->fb_id == -1) { 601 if (crtc_req->fb_id == -1) {
593 if (!crtc->primary->fb) { 602 struct drm_framebuffer *old_fb;
603
604 if (plane->state)
605 old_fb = plane->state->fb;
606 else
607 old_fb = plane->fb;
608
609 if (!old_fb) {
594 DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); 610 DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
595 ret = -EINVAL; 611 ret = -EINVAL;
596 goto out; 612 goto out;
597 } 613 }
598 fb = crtc->primary->fb; 614
615 fb = old_fb;
599 /* Make refcounting symmetric with the lookup path. */ 616 /* Make refcounting symmetric with the lookup path. */
600 drm_framebuffer_get(fb); 617 drm_framebuffer_get(fb);
601 } else { 618 } else {
@@ -613,6 +630,13 @@ retry:
613 ret = -ENOMEM; 630 ret = -ENOMEM;
614 goto out; 631 goto out;
615 } 632 }
633 if (!file_priv->aspect_ratio_allowed &&
634 (crtc_req->mode.flags & DRM_MODE_FLAG_PIC_AR_MASK) != DRM_MODE_FLAG_PIC_AR_NONE) {
635 DRM_DEBUG_KMS("Unexpected aspect-ratio flag bits\n");
636 ret = -EINVAL;
637 goto out;
638 }
639
616 640
617 ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode); 641 ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode);
618 if (ret) { 642 if (ret) {
@@ -627,8 +651,8 @@ retry:
627 * match real hardware capabilities. Skip the check in that 651 * match real hardware capabilities. Skip the check in that
628 * case. 652 * case.
629 */ 653 */
630 if (!crtc->primary->format_default) { 654 if (!plane->format_default) {
631 ret = drm_plane_check_pixel_format(crtc->primary, 655 ret = drm_plane_check_pixel_format(plane,
632 fb->format->format, 656 fb->format->format,
633 fb->modifier); 657 fb->modifier);
634 if (ret) { 658 if (ret) {
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 3c2b82865ad2..5d307b23a4e6 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -220,3 +220,5 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
220 220
221/* drm_edid.c */ 221/* drm_edid.c */
222void drm_mode_fixup_1366x768(struct drm_display_mode *mode); 222void drm_mode_fixup_1366x768(struct drm_display_mode *mode);
223void drm_reset_display_info(struct drm_connector *connector);
224u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid);
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 70ae1f232331..a7ba602a43a8 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -119,18 +119,32 @@ u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SI
119EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis); 119EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
120 120
121void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) { 121void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
122 if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) 122 int rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
123 DP_TRAINING_AUX_RD_MASK;
124
125 if (rd_interval > 4)
126 DRM_DEBUG_KMS("AUX interval %d, out of range (max 4)\n",
127 rd_interval);
128
129 if (rd_interval == 0 || dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14)
123 udelay(100); 130 udelay(100);
124 else 131 else
125 mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4); 132 mdelay(rd_interval * 4);
126} 133}
127EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay); 134EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
128 135
129void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) { 136void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
130 if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) 137 int rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
138 DP_TRAINING_AUX_RD_MASK;
139
140 if (rd_interval > 4)
141 DRM_DEBUG_KMS("AUX interval %d, out of range (max 4)\n",
142 rd_interval);
143
144 if (rd_interval == 0)
131 udelay(400); 145 udelay(400);
132 else 146 else
133 mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4); 147 mdelay(rd_interval * 4);
134} 148}
135EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay); 149EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay);
136 150
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 6fac4129e6a2..658830620ca3 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2941,12 +2941,14 @@ static void drm_dp_mst_dump_mstb(struct seq_file *m,
2941 } 2941 }
2942} 2942}
2943 2943
2944#define DP_PAYLOAD_TABLE_SIZE 64
2945
2944static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr, 2946static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,
2945 char *buf) 2947 char *buf)
2946{ 2948{
2947 int i; 2949 int i;
2948 2950
2949 for (i = 0; i < 64; i += 16) { 2951 for (i = 0; i < DP_PAYLOAD_TABLE_SIZE; i += 16) {
2950 if (drm_dp_dpcd_read(mgr->aux, 2952 if (drm_dp_dpcd_read(mgr->aux,
2951 DP_PAYLOAD_TABLE_UPDATE_STATUS + i, 2953 DP_PAYLOAD_TABLE_UPDATE_STATUS + i,
2952 &buf[i], 16) != 16) 2954 &buf[i], 16) != 16)
@@ -3015,7 +3017,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
3015 3017
3016 mutex_lock(&mgr->lock); 3018 mutex_lock(&mgr->lock);
3017 if (mgr->mst_primary) { 3019 if (mgr->mst_primary) {
3018 u8 buf[64]; 3020 u8 buf[DP_PAYLOAD_TABLE_SIZE];
3019 int ret; 3021 int ret;
3020 3022
3021 ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, buf, DP_RECEIVER_CAP_SIZE); 3023 ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, buf, DP_RECEIVER_CAP_SIZE);
@@ -3033,8 +3035,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
3033 seq_printf(m, " revision: hw: %x.%x sw: %x.%x\n", 3035 seq_printf(m, " revision: hw: %x.%x sw: %x.%x\n",
3034 buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]); 3036 buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]);
3035 if (dump_dp_payload_table(mgr, buf)) 3037 if (dump_dp_payload_table(mgr, buf))
3036 seq_printf(m, "payload table: %*ph\n", 63, buf); 3038 seq_printf(m, "payload table: %*ph\n", DP_PAYLOAD_TABLE_SIZE, buf);
3037
3038 } 3039 }
3039 3040
3040 mutex_unlock(&mgr->lock); 3041 mutex_unlock(&mgr->lock);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index c2c21d839727..b553a6f2ff0e 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -32,6 +32,7 @@
32#include <linux/moduleparam.h> 32#include <linux/moduleparam.h>
33#include <linux/mount.h> 33#include <linux/mount.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/srcu.h>
35 36
36#include <drm/drm_drv.h> 37#include <drm/drm_drv.h>
37#include <drm/drmP.h> 38#include <drm/drmP.h>
@@ -75,6 +76,8 @@ static bool drm_core_init_complete = false;
75 76
76static struct dentry *drm_debugfs_root; 77static struct dentry *drm_debugfs_root;
77 78
79DEFINE_STATIC_SRCU(drm_unplug_srcu);
80
78/* 81/*
79 * DRM Minors 82 * DRM Minors
80 * A DRM device can provide several char-dev interfaces on the DRM-Major. Each 83 * A DRM device can provide several char-dev interfaces on the DRM-Major. Each
@@ -96,8 +99,6 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
96 return &dev->primary; 99 return &dev->primary;
97 case DRM_MINOR_RENDER: 100 case DRM_MINOR_RENDER:
98 return &dev->render; 101 return &dev->render;
99 case DRM_MINOR_CONTROL:
100 return &dev->control;
101 default: 102 default:
102 BUG(); 103 BUG();
103 } 104 }
@@ -318,18 +319,51 @@ void drm_put_dev(struct drm_device *dev)
318} 319}
319EXPORT_SYMBOL(drm_put_dev); 320EXPORT_SYMBOL(drm_put_dev);
320 321
321static void drm_device_set_unplugged(struct drm_device *dev) 322/**
323 * drm_dev_enter - Enter device critical section
324 * @dev: DRM device
325 * @idx: Pointer to index that will be passed to the matching drm_dev_exit()
326 *
327 * This function marks and protects the beginning of a section that should not
328 * be entered after the device has been unplugged. The section end is marked
329 * with drm_dev_exit(). Calls to this function can be nested.
330 *
331 * Returns:
332 * True if it is OK to enter the section, false otherwise.
333 */
334bool drm_dev_enter(struct drm_device *dev, int *idx)
322{ 335{
323 smp_wmb(); 336 *idx = srcu_read_lock(&drm_unplug_srcu);
324 atomic_set(&dev->unplugged, 1); 337
338 if (dev->unplugged) {
339 srcu_read_unlock(&drm_unplug_srcu, *idx);
340 return false;
341 }
342
343 return true;
325} 344}
345EXPORT_SYMBOL(drm_dev_enter);
346
347/**
348 * drm_dev_exit - Exit device critical section
349 * @idx: index returned from drm_dev_enter()
350 *
351 * This function marks the end of a section that should not be entered after
352 * the device has been unplugged.
353 */
354void drm_dev_exit(int idx)
355{
356 srcu_read_unlock(&drm_unplug_srcu, idx);
357}
358EXPORT_SYMBOL(drm_dev_exit);
326 359
327/** 360/**
328 * drm_dev_unplug - unplug a DRM device 361 * drm_dev_unplug - unplug a DRM device
329 * @dev: DRM device 362 * @dev: DRM device
330 * 363 *
331 * This unplugs a hotpluggable DRM device, which makes it inaccessible to 364 * This unplugs a hotpluggable DRM device, which makes it inaccessible to
332 * userspace operations. Entry-points can use drm_dev_is_unplugged(). This 365 * userspace operations. Entry-points can use drm_dev_enter() and
366 * drm_dev_exit() to protect device resources in a race free manner. This
333 * essentially unregisters the device like drm_dev_unregister(), but can be 367 * essentially unregisters the device like drm_dev_unregister(), but can be
334 * called while there are still open users of @dev. 368 * called while there are still open users of @dev.
335 */ 369 */
@@ -338,10 +372,18 @@ void drm_dev_unplug(struct drm_device *dev)
338 drm_dev_unregister(dev); 372 drm_dev_unregister(dev);
339 373
340 mutex_lock(&drm_global_mutex); 374 mutex_lock(&drm_global_mutex);
341 drm_device_set_unplugged(dev);
342 if (dev->open_count == 0) 375 if (dev->open_count == 0)
343 drm_dev_put(dev); 376 drm_dev_put(dev);
344 mutex_unlock(&drm_global_mutex); 377 mutex_unlock(&drm_global_mutex);
378
379 /*
380 * After synchronizing any critical read section is guaranteed to see
381 * the new value of ->unplugged, and any critical section which might
382 * still have seen the old value of ->unplugged is guaranteed to have
383 * finished.
384 */
385 dev->unplugged = true;
386 synchronize_srcu(&drm_unplug_srcu);
345} 387}
346EXPORT_SYMBOL(drm_dev_unplug); 388EXPORT_SYMBOL(drm_dev_unplug);
347 389
@@ -523,7 +565,6 @@ err_ctxbitmap:
523err_minors: 565err_minors:
524 drm_minor_free(dev, DRM_MINOR_PRIMARY); 566 drm_minor_free(dev, DRM_MINOR_PRIMARY);
525 drm_minor_free(dev, DRM_MINOR_RENDER); 567 drm_minor_free(dev, DRM_MINOR_RENDER);
526 drm_minor_free(dev, DRM_MINOR_CONTROL);
527 drm_fs_inode_free(dev->anon_inode); 568 drm_fs_inode_free(dev->anon_inode);
528err_free: 569err_free:
529 mutex_destroy(&dev->master_mutex); 570 mutex_destroy(&dev->master_mutex);
@@ -559,7 +600,6 @@ void drm_dev_fini(struct drm_device *dev)
559 600
560 drm_minor_free(dev, DRM_MINOR_PRIMARY); 601 drm_minor_free(dev, DRM_MINOR_PRIMARY);
561 drm_minor_free(dev, DRM_MINOR_RENDER); 602 drm_minor_free(dev, DRM_MINOR_RENDER);
562 drm_minor_free(dev, DRM_MINOR_CONTROL);
563 603
564 mutex_destroy(&dev->master_mutex); 604 mutex_destroy(&dev->master_mutex);
565 mutex_destroy(&dev->ctxlist_mutex); 605 mutex_destroy(&dev->ctxlist_mutex);
@@ -752,10 +792,6 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
752 792
753 mutex_lock(&drm_global_mutex); 793 mutex_lock(&drm_global_mutex);
754 794
755 ret = drm_minor_register(dev, DRM_MINOR_CONTROL);
756 if (ret)
757 goto err_minors;
758
759 ret = drm_minor_register(dev, DRM_MINOR_RENDER); 795 ret = drm_minor_register(dev, DRM_MINOR_RENDER);
760 if (ret) 796 if (ret)
761 goto err_minors; 797 goto err_minors;
@@ -793,7 +829,6 @@ err_minors:
793 remove_compat_control_link(dev); 829 remove_compat_control_link(dev);
794 drm_minor_unregister(dev, DRM_MINOR_PRIMARY); 830 drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
795 drm_minor_unregister(dev, DRM_MINOR_RENDER); 831 drm_minor_unregister(dev, DRM_MINOR_RENDER);
796 drm_minor_unregister(dev, DRM_MINOR_CONTROL);
797out_unlock: 832out_unlock:
798 mutex_unlock(&drm_global_mutex); 833 mutex_unlock(&drm_global_mutex);
799 return ret; 834 return ret;
@@ -838,7 +873,6 @@ void drm_dev_unregister(struct drm_device *dev)
838 remove_compat_control_link(dev); 873 remove_compat_control_link(dev);
839 drm_minor_unregister(dev, DRM_MINOR_PRIMARY); 874 drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
840 drm_minor_unregister(dev, DRM_MINOR_RENDER); 875 drm_minor_unregister(dev, DRM_MINOR_RENDER);
841 drm_minor_unregister(dev, DRM_MINOR_CONTROL);
842} 876}
843EXPORT_SYMBOL(drm_dev_unregister); 877EXPORT_SYMBOL(drm_dev_unregister);
844 878
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 39f1db4acda4..40e1e24f2ff0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2930,11 +2930,15 @@ cea_mode_alternate_timings(u8 vic, struct drm_display_mode *mode)
2930static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match, 2930static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match,
2931 unsigned int clock_tolerance) 2931 unsigned int clock_tolerance)
2932{ 2932{
2933 unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
2933 u8 vic; 2934 u8 vic;
2934 2935
2935 if (!to_match->clock) 2936 if (!to_match->clock)
2936 return 0; 2937 return 0;
2937 2938
2939 if (to_match->picture_aspect_ratio)
2940 match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
2941
2938 for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) { 2942 for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) {
2939 struct drm_display_mode cea_mode = edid_cea_modes[vic]; 2943 struct drm_display_mode cea_mode = edid_cea_modes[vic];
2940 unsigned int clock1, clock2; 2944 unsigned int clock1, clock2;
@@ -2948,7 +2952,7 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m
2948 continue; 2952 continue;
2949 2953
2950 do { 2954 do {
2951 if (drm_mode_equal_no_clocks_no_stereo(to_match, &cea_mode)) 2955 if (drm_mode_match(to_match, &cea_mode, match_flags))
2952 return vic; 2956 return vic;
2953 } while (cea_mode_alternate_timings(vic, &cea_mode)); 2957 } while (cea_mode_alternate_timings(vic, &cea_mode));
2954 } 2958 }
@@ -2965,11 +2969,15 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m
2965 */ 2969 */
2966u8 drm_match_cea_mode(const struct drm_display_mode *to_match) 2970u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
2967{ 2971{
2972 unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
2968 u8 vic; 2973 u8 vic;
2969 2974
2970 if (!to_match->clock) 2975 if (!to_match->clock)
2971 return 0; 2976 return 0;
2972 2977
2978 if (to_match->picture_aspect_ratio)
2979 match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
2980
2973 for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) { 2981 for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) {
2974 struct drm_display_mode cea_mode = edid_cea_modes[vic]; 2982 struct drm_display_mode cea_mode = edid_cea_modes[vic];
2975 unsigned int clock1, clock2; 2983 unsigned int clock1, clock2;
@@ -2983,7 +2991,7 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
2983 continue; 2991 continue;
2984 2992
2985 do { 2993 do {
2986 if (drm_mode_equal_no_clocks_no_stereo(to_match, &cea_mode)) 2994 if (drm_mode_match(to_match, &cea_mode, match_flags))
2987 return vic; 2995 return vic;
2988 } while (cea_mode_alternate_timings(vic, &cea_mode)); 2996 } while (cea_mode_alternate_timings(vic, &cea_mode));
2989 } 2997 }
@@ -3030,6 +3038,7 @@ hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode)
3030static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match, 3038static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match,
3031 unsigned int clock_tolerance) 3039 unsigned int clock_tolerance)
3032{ 3040{
3041 unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
3033 u8 vic; 3042 u8 vic;
3034 3043
3035 if (!to_match->clock) 3044 if (!to_match->clock)
@@ -3047,7 +3056,7 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_
3047 abs(to_match->clock - clock2) > clock_tolerance) 3056 abs(to_match->clock - clock2) > clock_tolerance)
3048 continue; 3057 continue;
3049 3058
3050 if (drm_mode_equal_no_clocks(to_match, hdmi_mode)) 3059 if (drm_mode_match(to_match, hdmi_mode, match_flags))
3051 return vic; 3060 return vic;
3052 } 3061 }
3053 3062
@@ -3064,6 +3073,7 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_
3064 */ 3073 */
3065static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) 3074static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
3066{ 3075{
3076 unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
3067 u8 vic; 3077 u8 vic;
3068 3078
3069 if (!to_match->clock) 3079 if (!to_match->clock)
@@ -3079,7 +3089,7 @@ static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
3079 3089
3080 if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || 3090 if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
3081 KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && 3091 KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
3082 drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode)) 3092 drm_mode_match(to_match, hdmi_mode, match_flags))
3083 return vic; 3093 return vic;
3084 } 3094 }
3085 return 0; 3095 return 0;
@@ -4455,7 +4465,6 @@ drm_reset_display_info(struct drm_connector *connector)
4455 4465
4456 info->non_desktop = 0; 4466 info->non_desktop = 0;
4457} 4467}
4458EXPORT_SYMBOL_GPL(drm_reset_display_info);
4459 4468
4460u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid) 4469u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)
4461{ 4470{
@@ -4533,7 +4542,6 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
4533 info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; 4542 info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
4534 return quirks; 4543 return quirks;
4535} 4544}
4536EXPORT_SYMBOL_GPL(drm_add_display_info);
4537 4545
4538static int validate_displayid(u8 *displayid, int length, int idx) 4546static int validate_displayid(u8 *displayid, int length, int idx)
4539{ 4547{
@@ -4825,6 +4833,7 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
4825 const struct drm_display_mode *mode, 4833 const struct drm_display_mode *mode,
4826 bool is_hdmi2_sink) 4834 bool is_hdmi2_sink)
4827{ 4835{
4836 enum hdmi_picture_aspect picture_aspect;
4828 int err; 4837 int err;
4829 4838
4830 if (!frame || !mode) 4839 if (!frame || !mode)
@@ -4867,13 +4876,23 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
4867 * Populate picture aspect ratio from either 4876 * Populate picture aspect ratio from either
4868 * user input (if specified) or from the CEA mode list. 4877 * user input (if specified) or from the CEA mode list.
4869 */ 4878 */
4870 if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 || 4879 picture_aspect = mode->picture_aspect_ratio;
4871 mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9) 4880 if (picture_aspect == HDMI_PICTURE_ASPECT_NONE)
4872 frame->picture_aspect = mode->picture_aspect_ratio; 4881 picture_aspect = drm_get_cea_aspect_ratio(frame->video_code);
4873 else if (frame->video_code > 0) 4882
4874 frame->picture_aspect = drm_get_cea_aspect_ratio( 4883 /*
4875 frame->video_code); 4884 * The infoframe can't convey anything but none, 4:3
4885 * and 16:9, so if the user has asked for anything else
4886 * we can only satisfy it by specifying the right VIC.
4887 */
4888 if (picture_aspect > HDMI_PICTURE_ASPECT_16_9) {
4889 if (picture_aspect !=
4890 drm_get_cea_aspect_ratio(frame->video_code))
4891 return -EINVAL;
4892 picture_aspect = HDMI_PICTURE_ASPECT_NONE;
4893 }
4876 4894
4895 frame->picture_aspect = picture_aspect;
4877 frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; 4896 frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
4878 frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN; 4897 frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
4879 4898
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 0646b108030b..2ee1eaa66188 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -2183,7 +2183,11 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
2183 for (j = 0; j < i; j++) { 2183 for (j = 0; j < i; j++) {
2184 if (!enabled[j]) 2184 if (!enabled[j])
2185 continue; 2185 continue;
2186 if (!drm_mode_equal(modes[j], modes[i])) 2186 if (!drm_mode_match(modes[j], modes[i],
2187 DRM_MODE_MATCH_TIMINGS |
2188 DRM_MODE_MATCH_CLOCK |
2189 DRM_MODE_MATCH_FLAGS |
2190 DRM_MODE_MATCH_3D_FLAGS))
2187 can_clone = false; 2191 can_clone = false;
2188 } 2192 }
2189 } 2193 }
@@ -2203,7 +2207,11 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
2203 2207
2204 fb_helper_conn = fb_helper->connector_info[i]; 2208 fb_helper_conn = fb_helper->connector_info[i];
2205 list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) { 2209 list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) {
2206 if (drm_mode_equal(mode, dmt_mode)) 2210 if (drm_mode_match(mode, dmt_mode,
2211 DRM_MODE_MATCH_TIMINGS |
2212 DRM_MODE_MATCH_CLOCK |
2213 DRM_MODE_MATCH_FLAGS |
2214 DRM_MODE_MATCH_3D_FLAGS))
2207 modes[i] = mode; 2215 modes[i] = mode;
2208 } 2216 }
2209 if (!modes[i]) 2217 if (!modes[i])
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index ad67203de715..bfedceff87bb 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -468,29 +468,30 @@ int drm_mode_getfb(struct drm_device *dev,
468 goto out; 468 goto out;
469 } 469 }
470 470
471 if (!fb->funcs->create_handle) {
472 ret = -ENODEV;
473 goto out;
474 }
475
471 r->height = fb->height; 476 r->height = fb->height;
472 r->width = fb->width; 477 r->width = fb->width;
473 r->depth = fb->format->depth; 478 r->depth = fb->format->depth;
474 r->bpp = fb->format->cpp[0] * 8; 479 r->bpp = fb->format->cpp[0] * 8;
475 r->pitch = fb->pitches[0]; 480 r->pitch = fb->pitches[0];
476 if (fb->funcs->create_handle) { 481
477 if (drm_is_current_master(file_priv) || capable(CAP_SYS_ADMIN) || 482 /* GET_FB() is an unprivileged ioctl so we must not return a
478 drm_is_control_client(file_priv)) { 483 * buffer-handle to non-master processes! For
479 ret = fb->funcs->create_handle(fb, file_priv, 484 * backwards-compatibility reasons, we cannot make GET_FB() privileged,
480 &r->handle); 485 * so just return an invalid handle for non-masters.
481 } else { 486 */
482 /* GET_FB() is an unprivileged ioctl so we must not 487 if (!drm_is_current_master(file_priv) && !capable(CAP_SYS_ADMIN)) {
483 * return a buffer-handle to non-master processes! For 488 r->handle = 0;
484 * backwards-compatibility reasons, we cannot make 489 ret = 0;
485 * GET_FB() privileged, so just return an invalid handle 490 goto out;
486 * for non-masters. */
487 r->handle = 0;
488 ret = 0;
489 }
490 } else {
491 ret = -ENODEV;
492 } 491 }
493 492
493 ret = fb->funcs->create_handle(fb, file_priv, &r->handle);
494
494out: 495out:
495 drm_framebuffer_put(fb); 496 drm_framebuffer_put(fb);
496 497
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 4975ba9a7bc8..4a16d7b26c89 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -436,9 +436,12 @@ err_unref:
436 * @obj: object to register 436 * @obj: object to register
437 * @handlep: pionter to return the created handle to the caller 437 * @handlep: pionter to return the created handle to the caller
438 * 438 *
439 * Create a handle for this object. This adds a handle reference 439 * Create a handle for this object. This adds a handle reference to the object,
440 * to the object, which includes a regular reference count. Callers 440 * which includes a regular reference count. Callers will likely want to
441 * will likely want to dereference the object afterwards. 441 * dereference the object afterwards.
442 *
443 * Since this publishes @obj to userspace it must be fully set up by this point,
444 * drivers must call this last in their buffer object creation callbacks.
442 */ 445 */
443int drm_gem_handle_create(struct drm_file *file_priv, 446int drm_gem_handle_create(struct drm_file *file_priv,
444 struct drm_gem_object *obj, 447 struct drm_gem_object *obj,
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 4d682a6e8bcb..acfbc0641a06 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -22,6 +22,7 @@
22#include <drm/drm_gem.h> 22#include <drm/drm_gem.h>
23#include <drm/drm_gem_framebuffer_helper.h> 23#include <drm/drm_gem_framebuffer_helper.h>
24#include <drm/drm_modeset_helper.h> 24#include <drm/drm_modeset_helper.h>
25#include <drm/drm_simple_kms_helper.h>
25 26
26/** 27/**
27 * DOC: overview 28 * DOC: overview
@@ -266,6 +267,24 @@ int drm_gem_fb_prepare_fb(struct drm_plane *plane,
266EXPORT_SYMBOL_GPL(drm_gem_fb_prepare_fb); 267EXPORT_SYMBOL_GPL(drm_gem_fb_prepare_fb);
267 268
268/** 269/**
270 * drm_gem_fb_simple_display_pipe_prepare_fb - prepare_fb helper for
271 * &drm_simple_display_pipe
272 * @pipe: Simple display pipe
273 * @plane_state: Plane state
274 *
275 * This function uses drm_gem_fb_prepare_fb() to check if the plane FB has a
276 * &dma_buf attached, extracts the exclusive fence and attaches it to plane
277 * state for the atomic helper to wait on. Drivers can use this as their
278 * &drm_simple_display_pipe_funcs.prepare_fb callback.
279 */
280int drm_gem_fb_simple_display_pipe_prepare_fb(struct drm_simple_display_pipe *pipe,
281 struct drm_plane_state *plane_state)
282{
283 return drm_gem_fb_prepare_fb(&pipe->plane, plane_state);
284}
285EXPORT_SYMBOL(drm_gem_fb_simple_display_pipe_prepare_fb);
286
287/**
269 * drm_gem_fbdev_fb_create - Create a GEM backed &drm_framebuffer for fbdev 288 * drm_gem_fbdev_fb_create - Create a GEM backed &drm_framebuffer for fbdev
270 * emulation 289 * emulation
271 * @dev: DRM device 290 * @dev: DRM device
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index f8e96e648acf..67b1fca39aa6 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -105,7 +105,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
105 .desc = compat_ptr(v32.desc), 105 .desc = compat_ptr(v32.desc),
106 }; 106 };
107 err = drm_ioctl_kernel(file, drm_version, &v, 107 err = drm_ioctl_kernel(file, drm_version, &v,
108 DRM_UNLOCKED|DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW); 108 DRM_UNLOCKED|DRM_RENDER_ALLOW);
109 if (err) 109 if (err)
110 return err; 110 return err;
111 111
@@ -885,7 +885,7 @@ static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd,
885 return -EFAULT; 885 return -EFAULT;
886 886
887 err = drm_ioctl_kernel(file, drm_mode_addfb2, &req64, 887 err = drm_ioctl_kernel(file, drm_mode_addfb2, &req64,
888 DRM_CONTROL_ALLOW|DRM_UNLOCKED); 888 DRM_UNLOCKED);
889 if (err) 889 if (err)
890 return err; 890 return err;
891 891
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index af782911c505..0d4cfb232576 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -324,6 +324,15 @@ drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
324 return -EINVAL; 324 return -EINVAL;
325 file_priv->atomic = req->value; 325 file_priv->atomic = req->value;
326 file_priv->universal_planes = req->value; 326 file_priv->universal_planes = req->value;
327 /*
328 * No atomic user-space blows up on aspect ratio mode bits.
329 */
330 file_priv->aspect_ratio_allowed = req->value;
331 break;
332 case DRM_CLIENT_CAP_ASPECT_RATIO:
333 if (req->value > 1)
334 return -EINVAL;
335 file_priv->aspect_ratio_allowed = req->value;
327 break; 336 break;
328 default: 337 default:
329 return -EINVAL; 338 return -EINVAL;
@@ -510,13 +519,7 @@ int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
510 519
511 /* MASTER is only for master or control clients */ 520 /* MASTER is only for master or control clients */
512 if (unlikely((flags & DRM_MASTER) && 521 if (unlikely((flags & DRM_MASTER) &&
513 !drm_is_current_master(file_priv) && 522 !drm_is_current_master(file_priv)))
514 !drm_is_control_client(file_priv)))
515 return -EACCES;
516
517 /* Control clients must be explicitly allowed */
518 if (unlikely(!(flags & DRM_CONTROL_ALLOW) &&
519 drm_is_control_client(file_priv)))
520 return -EACCES; 523 return -EACCES;
521 524
522 /* Render clients must be explicitly allowed */ 525 /* Render clients must be explicitly allowed */
@@ -539,7 +542,7 @@ EXPORT_SYMBOL(drm_ioctl_permit);
539/* Ioctl table */ 542/* Ioctl table */
540static const struct drm_ioctl_desc drm_ioctls[] = { 543static const struct drm_ioctl_desc drm_ioctls[] = {
541 DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 544 DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version,
542 DRM_UNLOCKED|DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW), 545 DRM_UNLOCKED|DRM_RENDER_ALLOW),
543 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, DRM_UNLOCKED), 546 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, DRM_UNLOCKED),
544 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, DRM_UNLOCKED), 547 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, DRM_UNLOCKED),
545 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), 548 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
@@ -613,41 +616,41 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
613 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), 616 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
614 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), 617 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
615 618
616 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 619 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_UNLOCKED),
617 620
618 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 621 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
619 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 622 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
620 623
621 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 624 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_UNLOCKED),
622 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 625 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_UNLOCKED),
623 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 626 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_UNLOCKED),
624 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 627 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_UNLOCKED),
625 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 628 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_UNLOCKED),
626 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 629 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_UNLOCKED),
627 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED), 630 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
628 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), 631 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
629 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 632 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_UNLOCKED),
630 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 633 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_UNLOCKED),
631 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 634 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_UNLOCKED),
632 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 635 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_UNLOCKED),
633 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 636 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_UNLOCKED),
634 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 637 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
635 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 638 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_UNLOCKED),
636 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 639 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_UNLOCKED),
637 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 640 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_UNLOCKED),
638 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 641 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_UNLOCKED),
639 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 642 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_UNLOCKED),
640 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 643 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_UNLOCKED),
641 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 644 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_UNLOCKED),
642 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 645 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_UNLOCKED),
643 DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 646 DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_UNLOCKED),
644 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 647 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_UNLOCKED),
645 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 648 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_UNLOCKED),
646 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 649 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_UNLOCKED),
647 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 650 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_UNLOCKED),
648 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATOMIC, drm_mode_atomic_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 651 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATOMIC, drm_mode_atomic_ioctl, DRM_MASTER|DRM_UNLOCKED),
649 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATEPROPBLOB, drm_mode_createblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 652 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATEPROPBLOB, drm_mode_createblob_ioctl, DRM_UNLOCKED),
650 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROYPROPBLOB, drm_mode_destroyblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 653 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROYPROPBLOB, drm_mode_destroyblob_ioctl, DRM_UNLOCKED),
651 654
652 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_CREATE, drm_syncobj_create_ioctl, 655 DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_CREATE, drm_syncobj_create_ioctl,
653 DRM_UNLOCKED|DRM_RENDER_ALLOW), 656 DRM_UNLOCKED|DRM_RENDER_ALLOW),
@@ -665,10 +668,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
665 DRM_UNLOCKED|DRM_RENDER_ALLOW), 668 DRM_UNLOCKED|DRM_RENDER_ALLOW),
666 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED), 669 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),
667 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED), 670 DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED),
668 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 671 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_UNLOCKED),
669 DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 672 DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_UNLOCKED),
670 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 673 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_UNLOCKED),
671 DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 674 DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_UNLOCKED),
672}; 675};
673 676
674#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) 677#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index d345563fdff3..50c73c0a20b9 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -340,7 +340,7 @@ static void _drm_lease_revoke(struct drm_master *top)
340 break; 340 break;
341 341
342 /* Over */ 342 /* Over */
343 master = list_entry(master->lessee_list.next, struct drm_master, lessee_list); 343 master = list_next_entry(master, lessee_list);
344 } 344 }
345 } 345 }
346} 346}
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index e82b61e08f8c..c78ca0e84ffd 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -939,17 +939,68 @@ struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
939} 939}
940EXPORT_SYMBOL(drm_mode_duplicate); 940EXPORT_SYMBOL(drm_mode_duplicate);
941 941
942static bool drm_mode_match_timings(const struct drm_display_mode *mode1,
943 const struct drm_display_mode *mode2)
944{
945 return mode1->hdisplay == mode2->hdisplay &&
946 mode1->hsync_start == mode2->hsync_start &&
947 mode1->hsync_end == mode2->hsync_end &&
948 mode1->htotal == mode2->htotal &&
949 mode1->hskew == mode2->hskew &&
950 mode1->vdisplay == mode2->vdisplay &&
951 mode1->vsync_start == mode2->vsync_start &&
952 mode1->vsync_end == mode2->vsync_end &&
953 mode1->vtotal == mode2->vtotal &&
954 mode1->vscan == mode2->vscan;
955}
956
957static bool drm_mode_match_clock(const struct drm_display_mode *mode1,
958 const struct drm_display_mode *mode2)
959{
960 /*
961 * do clock check convert to PICOS
962 * so fb modes get matched the same
963 */
964 if (mode1->clock && mode2->clock)
965 return KHZ2PICOS(mode1->clock) == KHZ2PICOS(mode2->clock);
966 else
967 return mode1->clock == mode2->clock;
968}
969
970static bool drm_mode_match_flags(const struct drm_display_mode *mode1,
971 const struct drm_display_mode *mode2)
972{
973 return (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
974 (mode2->flags & ~DRM_MODE_FLAG_3D_MASK);
975}
976
977static bool drm_mode_match_3d_flags(const struct drm_display_mode *mode1,
978 const struct drm_display_mode *mode2)
979{
980 return (mode1->flags & DRM_MODE_FLAG_3D_MASK) ==
981 (mode2->flags & DRM_MODE_FLAG_3D_MASK);
982}
983
984static bool drm_mode_match_aspect_ratio(const struct drm_display_mode *mode1,
985 const struct drm_display_mode *mode2)
986{
987 return mode1->picture_aspect_ratio == mode2->picture_aspect_ratio;
988}
989
942/** 990/**
943 * drm_mode_equal - test modes for equality 991 * drm_mode_match - test modes for (partial) equality
944 * @mode1: first mode 992 * @mode1: first mode
945 * @mode2: second mode 993 * @mode2: second mode
994 * @match_flags: which parts need to match (DRM_MODE_MATCH_*)
946 * 995 *
947 * Check to see if @mode1 and @mode2 are equivalent. 996 * Check to see if @mode1 and @mode2 are equivalent.
948 * 997 *
949 * Returns: 998 * Returns:
950 * True if the modes are equal, false otherwise. 999 * True if the modes are (partially) equal, false otherwise.
951 */ 1000 */
952bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) 1001bool drm_mode_match(const struct drm_display_mode *mode1,
1002 const struct drm_display_mode *mode2,
1003 unsigned int match_flags)
953{ 1004{
954 if (!mode1 && !mode2) 1005 if (!mode1 && !mode2)
955 return true; 1006 return true;
@@ -957,15 +1008,49 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_displ
957 if (!mode1 || !mode2) 1008 if (!mode1 || !mode2)
958 return false; 1009 return false;
959 1010
960 /* do clock check convert to PICOS so fb modes get matched 1011 if (match_flags & DRM_MODE_MATCH_TIMINGS &&
961 * the same */ 1012 !drm_mode_match_timings(mode1, mode2))
962 if (mode1->clock && mode2->clock) { 1013 return false;
963 if (KHZ2PICOS(mode1->clock) != KHZ2PICOS(mode2->clock)) 1014
964 return false; 1015 if (match_flags & DRM_MODE_MATCH_CLOCK &&
965 } else if (mode1->clock != mode2->clock) 1016 !drm_mode_match_clock(mode1, mode2))
1017 return false;
1018
1019 if (match_flags & DRM_MODE_MATCH_FLAGS &&
1020 !drm_mode_match_flags(mode1, mode2))
1021 return false;
1022
1023 if (match_flags & DRM_MODE_MATCH_3D_FLAGS &&
1024 !drm_mode_match_3d_flags(mode1, mode2))
966 return false; 1025 return false;
967 1026
968 return drm_mode_equal_no_clocks(mode1, mode2); 1027 if (match_flags & DRM_MODE_MATCH_ASPECT_RATIO &&
1028 !drm_mode_match_aspect_ratio(mode1, mode2))
1029 return false;
1030
1031 return true;
1032}
1033EXPORT_SYMBOL(drm_mode_match);
1034
1035/**
1036 * drm_mode_equal - test modes for equality
1037 * @mode1: first mode
1038 * @mode2: second mode
1039 *
1040 * Check to see if @mode1 and @mode2 are equivalent.
1041 *
1042 * Returns:
1043 * True if the modes are equal, false otherwise.
1044 */
1045bool drm_mode_equal(const struct drm_display_mode *mode1,
1046 const struct drm_display_mode *mode2)
1047{
1048 return drm_mode_match(mode1, mode2,
1049 DRM_MODE_MATCH_TIMINGS |
1050 DRM_MODE_MATCH_CLOCK |
1051 DRM_MODE_MATCH_FLAGS |
1052 DRM_MODE_MATCH_3D_FLAGS|
1053 DRM_MODE_MATCH_ASPECT_RATIO);
969} 1054}
970EXPORT_SYMBOL(drm_mode_equal); 1055EXPORT_SYMBOL(drm_mode_equal);
971 1056
@@ -980,13 +1065,13 @@ EXPORT_SYMBOL(drm_mode_equal);
980 * Returns: 1065 * Returns:
981 * True if the modes are equal, false otherwise. 1066 * True if the modes are equal, false otherwise.
982 */ 1067 */
983bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) 1068bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1,
1069 const struct drm_display_mode *mode2)
984{ 1070{
985 if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) != 1071 return drm_mode_match(mode1, mode2,
986 (mode2->flags & DRM_MODE_FLAG_3D_MASK)) 1072 DRM_MODE_MATCH_TIMINGS |
987 return false; 1073 DRM_MODE_MATCH_FLAGS |
988 1074 DRM_MODE_MATCH_3D_FLAGS);
989 return drm_mode_equal_no_clocks_no_stereo(mode1, mode2);
990} 1075}
991EXPORT_SYMBOL(drm_mode_equal_no_clocks); 1076EXPORT_SYMBOL(drm_mode_equal_no_clocks);
992 1077
@@ -1004,21 +1089,9 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks);
1004bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, 1089bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
1005 const struct drm_display_mode *mode2) 1090 const struct drm_display_mode *mode2)
1006{ 1091{
1007 if (mode1->hdisplay == mode2->hdisplay && 1092 return drm_mode_match(mode1, mode2,
1008 mode1->hsync_start == mode2->hsync_start && 1093 DRM_MODE_MATCH_TIMINGS |
1009 mode1->hsync_end == mode2->hsync_end && 1094 DRM_MODE_MATCH_FLAGS);
1010 mode1->htotal == mode2->htotal &&
1011 mode1->hskew == mode2->hskew &&
1012 mode1->vdisplay == mode2->vdisplay &&
1013 mode1->vsync_start == mode2->vsync_start &&
1014 mode1->vsync_end == mode2->vsync_end &&
1015 mode1->vtotal == mode2->vtotal &&
1016 mode1->vscan == mode2->vscan &&
1017 (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
1018 (mode2->flags & ~DRM_MODE_FLAG_3D_MASK))
1019 return true;
1020
1021 return false;
1022} 1095}
1023EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); 1096EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
1024 1097
@@ -1575,6 +1648,26 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
1575 out->vrefresh = in->vrefresh; 1648 out->vrefresh = in->vrefresh;
1576 out->flags = in->flags; 1649 out->flags = in->flags;
1577 out->type = in->type; 1650 out->type = in->type;
1651
1652 switch (in->picture_aspect_ratio) {
1653 case HDMI_PICTURE_ASPECT_4_3:
1654 out->flags |= DRM_MODE_FLAG_PIC_AR_4_3;
1655 break;
1656 case HDMI_PICTURE_ASPECT_16_9:
1657 out->flags |= DRM_MODE_FLAG_PIC_AR_16_9;
1658 break;
1659 case HDMI_PICTURE_ASPECT_64_27:
1660 out->flags |= DRM_MODE_FLAG_PIC_AR_64_27;
1661 break;
1662 case HDMI_PICTURE_ASPECT_256_135:
1663 out->flags |= DRM_MODE_FLAG_PIC_AR_256_135;
1664 break;
1665 case HDMI_PICTURE_ASPECT_RESERVED:
1666 default:
1667 out->flags |= DRM_MODE_FLAG_PIC_AR_NONE;
1668 break;
1669 }
1670
1578 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 1671 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1579 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 1672 out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1580} 1673}
@@ -1621,6 +1714,30 @@ int drm_mode_convert_umode(struct drm_device *dev,
1621 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 1714 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1622 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 1715 out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1623 1716
1717 /* Clearing picture aspect ratio bits from out flags,
1718 * as the aspect-ratio information is not stored in
1719 * flags for kernel-mode, but in picture_aspect_ratio.
1720 */
1721 out->flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
1722
1723 switch (in->flags & DRM_MODE_FLAG_PIC_AR_MASK) {
1724 case DRM_MODE_FLAG_PIC_AR_4_3:
1725 out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_4_3;
1726 break;
1727 case DRM_MODE_FLAG_PIC_AR_16_9:
1728 out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_16_9;
1729 break;
1730 case DRM_MODE_FLAG_PIC_AR_64_27:
1731 out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_64_27;
1732 break;
1733 case DRM_MODE_FLAG_PIC_AR_256_135:
1734 out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_256_135;
1735 break;
1736 default:
1737 out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
1738 break;
1739 }
1740
1624 out->status = drm_mode_validate_driver(dev, out); 1741 out->status = drm_mode_validate_driver(dev, out);
1625 if (out->status != MODE_OK) 1742 if (out->status != MODE_OK)
1626 return -EINVAL; 1743 return -EINVAL;
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
index 902cc1a71e45..fe9c6c731e87 100644
--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -60,7 +60,7 @@ static const struct drm_dmi_panel_orientation_data itworks_tw891 = {
60 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, 60 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
61}; 61};
62 62
63static const struct drm_dmi_panel_orientation_data vios_lth17 = { 63static const struct drm_dmi_panel_orientation_data lcd800x1280_rightside_up = {
64 .width = 800, 64 .width = 800,
65 .height = 1280, 65 .height = 1280,
66 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, 66 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
@@ -102,12 +102,30 @@ static const struct dmi_system_id orientation_data[] = {
102 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"), 102 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
103 }, 103 },
104 .driver_data = (void *)&itworks_tw891, 104 .driver_data = (void *)&itworks_tw891,
105 }, { /*
106 * Lenovo Ideapad Miix 310 laptop, only some production batches
107 * have a portrait screen, the resolution checks makes the quirk
108 * apply only to those batches.
109 */
110 .matches = {
111 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
112 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80SG"),
113 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"),
114 },
115 .driver_data = (void *)&lcd800x1280_rightside_up,
116 }, { /* Lenovo Ideapad Miix 320 */
117 .matches = {
118 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
119 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
120 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
121 },
122 .driver_data = (void *)&lcd800x1280_rightside_up,
105 }, { /* VIOS LTH17 */ 123 }, { /* VIOS LTH17 */
106 .matches = { 124 .matches = {
107 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"), 125 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
108 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"), 126 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
109 }, 127 },
110 .driver_data = (void *)&vios_lth17, 128 .driver_data = (void *)&lcd800x1280_rightside_up,
111 }, 129 },
112 {} 130 {}
113}; 131};
@@ -154,10 +172,9 @@ int drm_get_panel_orientation_quirk(int width, int height)
154 if (!bios_date) 172 if (!bios_date)
155 continue; 173 continue;
156 174
157 for (i = 0; data->bios_dates[i]; i++) { 175 i = match_string(data->bios_dates, -1, bios_date);
158 if (!strcmp(data->bios_dates[i], bios_date)) 176 if (i >= 0)
159 return data->orientation; 177 return data->orientation;
160 }
161 } 178 }
162 179
163 return DRM_MODE_PANEL_ORIENTATION_UNKNOWN; 180 return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 6d2a6e428a3e..035054455301 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -756,6 +756,7 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
756 struct drm_modeset_acquire_ctx *ctx) 756 struct drm_modeset_acquire_ctx *ctx)
757{ 757{
758 struct drm_device *dev = crtc->dev; 758 struct drm_device *dev = crtc->dev;
759 struct drm_plane *plane = crtc->cursor;
759 struct drm_framebuffer *fb = NULL; 760 struct drm_framebuffer *fb = NULL;
760 struct drm_mode_fb_cmd2 fbreq = { 761 struct drm_mode_fb_cmd2 fbreq = {
761 .width = req->width, 762 .width = req->width,
@@ -769,8 +770,8 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
769 uint32_t src_w = 0, src_h = 0; 770 uint32_t src_w = 0, src_h = 0;
770 int ret = 0; 771 int ret = 0;
771 772
772 BUG_ON(!crtc->cursor); 773 BUG_ON(!plane);
773 WARN_ON(crtc->cursor->crtc != crtc && crtc->cursor->crtc != NULL); 774 WARN_ON(plane->crtc != crtc && plane->crtc != NULL);
774 775
775 /* 776 /*
776 * Obtain fb we'll be using (either new or existing) and take an extra 777 * Obtain fb we'll be using (either new or existing) and take an extra
@@ -784,13 +785,18 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
784 DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); 785 DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n");
785 return PTR_ERR(fb); 786 return PTR_ERR(fb);
786 } 787 }
788
787 fb->hot_x = req->hot_x; 789 fb->hot_x = req->hot_x;
788 fb->hot_y = req->hot_y; 790 fb->hot_y = req->hot_y;
789 } else { 791 } else {
790 fb = NULL; 792 fb = NULL;
791 } 793 }
792 } else { 794 } else {
793 fb = crtc->cursor->fb; 795 if (plane->state)
796 fb = plane->state->fb;
797 else
798 fb = plane->fb;
799
794 if (fb) 800 if (fb)
795 drm_framebuffer_get(fb); 801 drm_framebuffer_get(fb);
796 } 802 }
@@ -810,7 +816,7 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
810 src_h = fb->height << 16; 816 src_h = fb->height << 16;
811 } 817 }
812 818
813 ret = __setplane_internal(crtc->cursor, crtc, fb, 819 ret = __setplane_internal(plane, crtc, fb,
814 crtc_x, crtc_y, crtc_w, crtc_h, 820 crtc_x, crtc_y, crtc_w, crtc_h,
815 0, 0, src_w, src_h, ctx); 821 0, 0, src_w, src_h, ctx);
816 822
@@ -931,7 +937,8 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
931{ 937{
932 struct drm_mode_crtc_page_flip_target *page_flip = data; 938 struct drm_mode_crtc_page_flip_target *page_flip = data;
933 struct drm_crtc *crtc; 939 struct drm_crtc *crtc;
934 struct drm_framebuffer *fb = NULL; 940 struct drm_plane *plane;
941 struct drm_framebuffer *fb = NULL, *old_fb;
935 struct drm_pending_vblank_event *e = NULL; 942 struct drm_pending_vblank_event *e = NULL;
936 u32 target_vblank = page_flip->sequence; 943 u32 target_vblank = page_flip->sequence;
937 struct drm_modeset_acquire_ctx ctx; 944 struct drm_modeset_acquire_ctx ctx;
@@ -959,6 +966,8 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
959 if (!crtc) 966 if (!crtc)
960 return -ENOENT; 967 return -ENOENT;
961 968
969 plane = crtc->primary;
970
962 if (crtc->funcs->page_flip_target) { 971 if (crtc->funcs->page_flip_target) {
963 u32 current_vblank; 972 u32 current_vblank;
964 int r; 973 int r;
@@ -1003,11 +1012,16 @@ retry:
1003 ret = drm_modeset_lock(&crtc->mutex, &ctx); 1012 ret = drm_modeset_lock(&crtc->mutex, &ctx);
1004 if (ret) 1013 if (ret)
1005 goto out; 1014 goto out;
1006 ret = drm_modeset_lock(&crtc->primary->mutex, &ctx); 1015 ret = drm_modeset_lock(&plane->mutex, &ctx);
1007 if (ret) 1016 if (ret)
1008 goto out; 1017 goto out;
1009 1018
1010 if (crtc->primary->fb == NULL) { 1019 if (plane->state)
1020 old_fb = plane->state->fb;
1021 else
1022 old_fb = plane->fb;
1023
1024 if (old_fb == NULL) {
1011 /* The framebuffer is currently unbound, presumably 1025 /* The framebuffer is currently unbound, presumably
1012 * due to a hotplug event, that userspace has not 1026 * due to a hotplug event, that userspace has not
1013 * yet discovered. 1027 * yet discovered.
@@ -1022,8 +1036,8 @@ retry:
1022 goto out; 1036 goto out;
1023 } 1037 }
1024 1038
1025 if (crtc->state) { 1039 if (plane->state) {
1026 const struct drm_plane_state *state = crtc->primary->state; 1040 const struct drm_plane_state *state = plane->state;
1027 1041
1028 ret = drm_framebuffer_check_src_coords(state->src_x, 1042 ret = drm_framebuffer_check_src_coords(state->src_x,
1029 state->src_y, 1043 state->src_y,
@@ -1031,12 +1045,13 @@ retry:
1031 state->src_h, 1045 state->src_h,
1032 fb); 1046 fb);
1033 } else { 1047 } else {
1034 ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb); 1048 ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y,
1049 &crtc->mode, fb);
1035 } 1050 }
1036 if (ret) 1051 if (ret)
1037 goto out; 1052 goto out;
1038 1053
1039 if (crtc->primary->fb->format != fb->format) { 1054 if (old_fb->format != fb->format) {
1040 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); 1055 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
1041 ret = -EINVAL; 1056 ret = -EINVAL;
1042 goto out; 1057 goto out;
@@ -1048,10 +1063,12 @@ retry:
1048 ret = -ENOMEM; 1063 ret = -ENOMEM;
1049 goto out; 1064 goto out;
1050 } 1065 }
1066
1051 e->event.base.type = DRM_EVENT_FLIP_COMPLETE; 1067 e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
1052 e->event.base.length = sizeof(e->event); 1068 e->event.base.length = sizeof(e->event);
1053 e->event.vbl.user_data = page_flip->user_data; 1069 e->event.vbl.user_data = page_flip->user_data;
1054 e->event.vbl.crtc_id = crtc->base.id; 1070 e->event.vbl.crtc_id = crtc->base.id;
1071
1055 ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); 1072 ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
1056 if (ret) { 1073 if (ret) {
1057 kfree(e); 1074 kfree(e);
@@ -1060,7 +1077,7 @@ retry:
1060 } 1077 }
1061 } 1078 }
1062 1079
1063 crtc->primary->old_fb = crtc->primary->fb; 1080 plane->old_fb = plane->fb;
1064 if (crtc->funcs->page_flip_target) 1081 if (crtc->funcs->page_flip_target)
1065 ret = crtc->funcs->page_flip_target(crtc, fb, e, 1082 ret = crtc->funcs->page_flip_target(crtc, fb, e,
1066 page_flip->flags, 1083 page_flip->flags,
@@ -1073,19 +1090,18 @@ retry:
1073 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) 1090 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT)
1074 drm_event_cancel_free(dev, &e->base); 1091 drm_event_cancel_free(dev, &e->base);
1075 /* Keep the old fb, don't unref it. */ 1092 /* Keep the old fb, don't unref it. */
1076 crtc->primary->old_fb = NULL; 1093 plane->old_fb = NULL;
1077 } else { 1094 } else {
1078 crtc->primary->fb = fb; 1095 plane->fb = fb;
1079 /* Unref only the old framebuffer. */ 1096 drm_framebuffer_get(fb);
1080 fb = NULL;
1081 } 1097 }
1082 1098
1083out: 1099out:
1084 if (fb) 1100 if (fb)
1085 drm_framebuffer_put(fb); 1101 drm_framebuffer_put(fb);
1086 if (crtc->primary->old_fb) 1102 if (plane->old_fb)
1087 drm_framebuffer_put(crtc->primary->old_fb); 1103 drm_framebuffer_put(plane->old_fb);
1088 crtc->primary->old_fb = NULL; 1104 plane->old_fb = NULL;
1089 1105
1090 if (ret == -EDEADLK) { 1106 if (ret == -EDEADLK) {
1091 ret = drm_modeset_backoff(&ctx); 1107 ret = drm_modeset_backoff(&ctx);
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 7856a9b3f8a8..397b46b33739 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -331,6 +331,9 @@ EXPORT_SYMBOL(drm_gem_map_dma_buf);
331 331
332/** 332/**
333 * drm_gem_unmap_dma_buf - unmap_dma_buf implementation for GEM 333 * drm_gem_unmap_dma_buf - unmap_dma_buf implementation for GEM
334 * @attach: attachment to unmap buffer from
335 * @sgt: scatterlist info of the buffer to unmap
336 * @dir: direction of DMA transfer
334 * 337 *
335 * Not implemented. The unmap is done at drm_gem_map_detach(). This can be 338 * Not implemented. The unmap is done at drm_gem_map_detach(). This can be
336 * used as the &dma_buf_ops.unmap_dma_buf callback. 339 * used as the &dma_buf_ops.unmap_dma_buf callback.
@@ -406,7 +409,10 @@ void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf)
406 struct drm_gem_object *obj = dma_buf->priv; 409 struct drm_gem_object *obj = dma_buf->priv;
407 struct drm_device *dev = obj->dev; 410 struct drm_device *dev = obj->dev;
408 411
409 return dev->driver->gem_prime_vmap(obj); 412 if (dev->driver->gem_prime_vmap)
413 return dev->driver->gem_prime_vmap(obj);
414 else
415 return NULL;
410} 416}
411EXPORT_SYMBOL(drm_gem_dmabuf_vmap); 417EXPORT_SYMBOL(drm_gem_dmabuf_vmap);
412 418
@@ -423,12 +429,15 @@ void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
423 struct drm_gem_object *obj = dma_buf->priv; 429 struct drm_gem_object *obj = dma_buf->priv;
424 struct drm_device *dev = obj->dev; 430 struct drm_device *dev = obj->dev;
425 431
426 dev->driver->gem_prime_vunmap(obj, vaddr); 432 if (dev->driver->gem_prime_vunmap)
433 dev->driver->gem_prime_vunmap(obj, vaddr);
427} 434}
428EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); 435EXPORT_SYMBOL(drm_gem_dmabuf_vunmap);
429 436
430/** 437/**
431 * drm_gem_dmabuf_kmap_atomic - map_atomic implementation for GEM 438 * drm_gem_dmabuf_kmap_atomic - map_atomic implementation for GEM
439 * @dma_buf: buffer to be mapped
440 * @page_num: page number within the buffer
432 * 441 *
433 * Not implemented. This can be used as the &dma_buf_ops.map_atomic callback. 442 * Not implemented. This can be used as the &dma_buf_ops.map_atomic callback.
434 */ 443 */
@@ -441,6 +450,9 @@ EXPORT_SYMBOL(drm_gem_dmabuf_kmap_atomic);
441 450
442/** 451/**
443 * drm_gem_dmabuf_kunmap_atomic - unmap_atomic implementation for GEM 452 * drm_gem_dmabuf_kunmap_atomic - unmap_atomic implementation for GEM
453 * @dma_buf: buffer to be unmapped
454 * @page_num: page number within the buffer
455 * @addr: virtual address of the buffer
444 * 456 *
445 * Not implemented. This can be used as the &dma_buf_ops.unmap_atomic callback. 457 * Not implemented. This can be used as the &dma_buf_ops.unmap_atomic callback.
446 */ 458 */
@@ -453,6 +465,8 @@ EXPORT_SYMBOL(drm_gem_dmabuf_kunmap_atomic);
453 465
454/** 466/**
455 * drm_gem_dmabuf_kmap - map implementation for GEM 467 * drm_gem_dmabuf_kmap - map implementation for GEM
468 * @dma_buf: buffer to be mapped
469 * @page_num: page number within the buffer
456 * 470 *
457 * Not implemented. This can be used as the &dma_buf_ops.map callback. 471 * Not implemented. This can be used as the &dma_buf_ops.map callback.
458 */ 472 */
@@ -464,6 +478,9 @@ EXPORT_SYMBOL(drm_gem_dmabuf_kmap);
464 478
465/** 479/**
466 * drm_gem_dmabuf_kunmap - unmap implementation for GEM 480 * drm_gem_dmabuf_kunmap - unmap implementation for GEM
481 * @dma_buf: buffer to be unmapped
482 * @page_num: page number within the buffer
483 * @addr: virtual address of the buffer
467 * 484 *
468 * Not implemented. This can be used as the &dma_buf_ops.unmap callback. 485 * Not implemented. This can be used as the &dma_buf_ops.unmap callback.
469 */ 486 */
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 8f4672daac7f..1f8031e30f53 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -169,9 +169,9 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev,
169 return NULL; 169 return NULL;
170 170
171 for (i = 0; i < num_values; i++) { 171 for (i = 0; i < num_values; i++) {
172 ret = drm_property_add_enum(property, i, 172 ret = drm_property_add_enum(property,
173 props[i].type, 173 props[i].type,
174 props[i].name); 174 props[i].name);
175 if (ret) { 175 if (ret) {
176 drm_property_destroy(dev, property); 176 drm_property_destroy(dev, property);
177 return NULL; 177 return NULL;
@@ -209,7 +209,7 @@ struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
209 uint64_t supported_bits) 209 uint64_t supported_bits)
210{ 210{
211 struct drm_property *property; 211 struct drm_property *property;
212 int i, ret, index = 0; 212 int i, ret;
213 int num_values = hweight64(supported_bits); 213 int num_values = hweight64(supported_bits);
214 214
215 flags |= DRM_MODE_PROP_BITMASK; 215 flags |= DRM_MODE_PROP_BITMASK;
@@ -221,14 +221,9 @@ struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
221 if (!(supported_bits & (1ULL << props[i].type))) 221 if (!(supported_bits & (1ULL << props[i].type)))
222 continue; 222 continue;
223 223
224 if (WARN_ON(index >= num_values)) { 224 ret = drm_property_add_enum(property,
225 drm_property_destroy(dev, property); 225 props[i].type,
226 return NULL; 226 props[i].name);
227 }
228
229 ret = drm_property_add_enum(property, index++,
230 props[i].type,
231 props[i].name);
232 if (ret) { 227 if (ret) {
233 drm_property_destroy(dev, property); 228 drm_property_destroy(dev, property);
234 return NULL; 229 return NULL;
@@ -376,7 +371,6 @@ EXPORT_SYMBOL(drm_property_create_bool);
376/** 371/**
377 * drm_property_add_enum - add a possible value to an enumeration property 372 * drm_property_add_enum - add a possible value to an enumeration property
378 * @property: enumeration property to change 373 * @property: enumeration property to change
379 * @index: index of the new enumeration
380 * @value: value of the new enumeration 374 * @value: value of the new enumeration
381 * @name: symbolic name of the new enumeration 375 * @name: symbolic name of the new enumeration
382 * 376 *
@@ -388,10 +382,11 @@ EXPORT_SYMBOL(drm_property_create_bool);
388 * Returns: 382 * Returns:
389 * Zero on success, error code on failure. 383 * Zero on success, error code on failure.
390 */ 384 */
391int drm_property_add_enum(struct drm_property *property, int index, 385int drm_property_add_enum(struct drm_property *property,
392 uint64_t value, const char *name) 386 uint64_t value, const char *name)
393{ 387{
394 struct drm_property_enum *prop_enum; 388 struct drm_property_enum *prop_enum;
389 int index = 0;
395 390
396 if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN)) 391 if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN))
397 return -EINVAL; 392 return -EINVAL;
@@ -411,8 +406,12 @@ int drm_property_add_enum(struct drm_property *property, int index,
411 list_for_each_entry(prop_enum, &property->enum_list, head) { 406 list_for_each_entry(prop_enum, &property->enum_list, head) {
412 if (WARN_ON(prop_enum->value == value)) 407 if (WARN_ON(prop_enum->value == value))
413 return -EINVAL; 408 return -EINVAL;
409 index++;
414 } 410 }
415 411
412 if (WARN_ON(index >= property->num_values))
413 return -EINVAL;
414
416 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL); 415 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
417 if (!prop_enum) 416 if (!prop_enum)
418 return -ENOMEM; 417 return -ENOMEM;
diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c
index 9817c1445ba9..8c057829b804 100644
--- a/drivers/gpu/drm/drm_rect.c
+++ b/drivers/gpu/drm/drm_rect.c
@@ -50,13 +50,25 @@ bool drm_rect_intersect(struct drm_rect *r1, const struct drm_rect *r2)
50} 50}
51EXPORT_SYMBOL(drm_rect_intersect); 51EXPORT_SYMBOL(drm_rect_intersect);
52 52
53static u32 clip_scaled(u32 src, u32 dst, u32 clip)
54{
55 u64 tmp = mul_u32_u32(src, dst - clip);
56
57 /*
58 * Round toward 1.0 when clipping so that we don't accidentally
59 * change upscaling to downscaling or vice versa.
60 */
61 if (src < (dst << 16))
62 return DIV_ROUND_UP_ULL(tmp, dst);
63 else
64 return DIV_ROUND_DOWN_ULL(tmp, dst);
65}
66
53/** 67/**
54 * drm_rect_clip_scaled - perform a scaled clip operation 68 * drm_rect_clip_scaled - perform a scaled clip operation
55 * @src: source window rectangle 69 * @src: source window rectangle
56 * @dst: destination window rectangle 70 * @dst: destination window rectangle
57 * @clip: clip rectangle 71 * @clip: clip rectangle
58 * @hscale: horizontal scaling factor
59 * @vscale: vertical scaling factor
60 * 72 *
61 * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by the 73 * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by the
62 * same amounts multiplied by @hscale and @vscale. 74 * same amounts multiplied by @hscale and @vscale.
@@ -66,33 +78,44 @@ EXPORT_SYMBOL(drm_rect_intersect);
66 * %false otherwise 78 * %false otherwise
67 */ 79 */
68bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, 80bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst,
69 const struct drm_rect *clip, 81 const struct drm_rect *clip)
70 int hscale, int vscale)
71{ 82{
72 int diff; 83 int diff;
73 84
74 diff = clip->x1 - dst->x1; 85 diff = clip->x1 - dst->x1;
75 if (diff > 0) { 86 if (diff > 0) {
76 int64_t tmp = src->x1 + (int64_t) diff * hscale; 87 u32 new_src_w = clip_scaled(drm_rect_width(src),
77 src->x1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); 88 drm_rect_width(dst), diff);
89
90 src->x1 = clamp_t(int64_t, src->x2 - new_src_w, INT_MIN, INT_MAX);
91 dst->x1 = clip->x1;
78 } 92 }
79 diff = clip->y1 - dst->y1; 93 diff = clip->y1 - dst->y1;
80 if (diff > 0) { 94 if (diff > 0) {
81 int64_t tmp = src->y1 + (int64_t) diff * vscale; 95 u32 new_src_h = clip_scaled(drm_rect_height(src),
82 src->y1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); 96 drm_rect_height(dst), diff);
97
98 src->y1 = clamp_t(int64_t, src->y2 - new_src_h, INT_MIN, INT_MAX);
99 dst->y1 = clip->y1;
83 } 100 }
84 diff = dst->x2 - clip->x2; 101 diff = dst->x2 - clip->x2;
85 if (diff > 0) { 102 if (diff > 0) {
86 int64_t tmp = src->x2 - (int64_t) diff * hscale; 103 u32 new_src_w = clip_scaled(drm_rect_width(src),
87 src->x2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); 104 drm_rect_width(dst), diff);
105
106 src->x2 = clamp_t(int64_t, src->x1 + new_src_w, INT_MIN, INT_MAX);
107 dst->x2 = clip->x2;
88 } 108 }
89 diff = dst->y2 - clip->y2; 109 diff = dst->y2 - clip->y2;
90 if (diff > 0) { 110 if (diff > 0) {
91 int64_t tmp = src->y2 - (int64_t) diff * vscale; 111 u32 new_src_h = clip_scaled(drm_rect_height(src),
92 src->y2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); 112 drm_rect_height(dst), diff);
113
114 src->y2 = clamp_t(int64_t, src->y1 + new_src_h, INT_MIN, INT_MAX);
115 dst->y2 = clip->y2;
93 } 116 }
94 117
95 return drm_rect_intersect(dst, clip); 118 return drm_rect_visible(dst);
96} 119}
97EXPORT_SYMBOL(drm_rect_clip_scaled); 120EXPORT_SYMBOL(drm_rect_clip_scaled);
98 121
@@ -106,7 +129,10 @@ static int drm_calc_scale(int src, int dst)
106 if (dst == 0) 129 if (dst == 0)
107 return 0; 130 return 0;
108 131
109 scale = src / dst; 132 if (src > (dst << 16))
133 return DIV_ROUND_UP(src, dst);
134 else
135 scale = src / dst;
110 136
111 return scale; 137 return scale;
112} 138}
@@ -121,6 +147,10 @@ static int drm_calc_scale(int src, int dst)
121 * Calculate the horizontal scaling factor as 147 * Calculate the horizontal scaling factor as
122 * (@src width) / (@dst width). 148 * (@src width) / (@dst width).
123 * 149 *
150 * If the scale is below 1 << 16, round down. If the scale is above
151 * 1 << 16, round up. This will calculate the scale with the most
152 * pessimistic limit calculation.
153 *
124 * RETURNS: 154 * RETURNS:
125 * The horizontal scaling factor, or errno of out of limits. 155 * The horizontal scaling factor, or errno of out of limits.
126 */ 156 */
@@ -152,6 +182,10 @@ EXPORT_SYMBOL(drm_rect_calc_hscale);
152 * Calculate the vertical scaling factor as 182 * Calculate the vertical scaling factor as
153 * (@src height) / (@dst height). 183 * (@src height) / (@dst height).
154 * 184 *
185 * If the scale is below 1 << 16, round down. If the scale is above
186 * 1 << 16, round up. This will calculate the scale with the most
187 * pessimistic limit calculation.
188 *
155 * RETURNS: 189 * RETURNS:
156 * The vertical scaling factor, or errno of out of limits. 190 * The vertical scaling factor, or errno of out of limits.
157 */ 191 */
@@ -189,6 +223,10 @@ EXPORT_SYMBOL(drm_rect_calc_vscale);
189 * If the calculated scaling factor is above @max_vscale, 223 * If the calculated scaling factor is above @max_vscale,
190 * decrease the height of rectangle @src to compensate. 224 * decrease the height of rectangle @src to compensate.
191 * 225 *
226 * If the scale is below 1 << 16, round down. If the scale is above
227 * 1 << 16, round up. This will calculate the scale with the most
228 * pessimistic limit calculation.
229 *
192 * RETURNS: 230 * RETURNS:
193 * The horizontal scaling factor. 231 * The horizontal scaling factor.
194 */ 232 */
@@ -239,6 +277,10 @@ EXPORT_SYMBOL(drm_rect_calc_hscale_relaxed);
239 * If the calculated scaling factor is above @max_vscale, 277 * If the calculated scaling factor is above @max_vscale,
240 * decrease the height of rectangle @src to compensate. 278 * decrease the height of rectangle @src to compensate.
241 * 279 *
280 * If the scale is below 1 << 16, round down. If the scale is above
281 * 1 << 16, round up. This will calculate the scale with the most
282 * pessimistic limit calculation.
283 *
242 * RETURNS: 284 * RETURNS:
243 * The vertical scaling factor. 285 * The vertical scaling factor.
244 */ 286 */
@@ -373,8 +415,8 @@ EXPORT_SYMBOL(drm_rect_rotate);
373 * them when doing a rotatation and its inverse. 415 * them when doing a rotatation and its inverse.
374 * That is, if you do :: 416 * That is, if you do ::
375 * 417 *
376 * DRM_MODE_PROP_ROTATE(&r, width, height, rotation); 418 * drm_rect_rotate(&r, width, height, rotation);
377 * DRM_MODE_ROTATE_inv(&r, width, height, rotation); 419 * drm_rect_rotate_inv(&r, width, height, rotation);
378 * 420 *
379 * you will always get back the original rectangle. 421 * you will always get back the original rectangle.
380 */ 422 */
diff --git a/drivers/gpu/drm/drm_scdc_helper.c b/drivers/gpu/drm/drm_scdc_helper.c
index 657ea5ab6c3f..870e25f1f788 100644
--- a/drivers/gpu/drm/drm_scdc_helper.c
+++ b/drivers/gpu/drm/drm_scdc_helper.c
@@ -141,7 +141,7 @@ bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter)
141 141
142 ret = drm_scdc_readb(adapter, SCDC_SCRAMBLER_STATUS, &status); 142 ret = drm_scdc_readb(adapter, SCDC_SCRAMBLER_STATUS, &status);
143 if (ret < 0) { 143 if (ret < 0) {
144 DRM_ERROR("Failed to read scrambling status: %d\n", ret); 144 DRM_DEBUG_KMS("Failed to read scrambling status: %d\n", ret);
145 return false; 145 return false;
146 } 146 }
147 147
@@ -168,7 +168,7 @@ bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable)
168 168
169 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config); 169 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config);
170 if (ret < 0) { 170 if (ret < 0) {
171 DRM_ERROR("Failed to read TMDS config: %d\n", ret); 171 DRM_DEBUG_KMS("Failed to read TMDS config: %d\n", ret);
172 return false; 172 return false;
173 } 173 }
174 174
@@ -179,7 +179,7 @@ bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable)
179 179
180 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config); 180 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config);
181 if (ret < 0) { 181 if (ret < 0) {
182 DRM_ERROR("Failed to enable scrambling: %d\n", ret); 182 DRM_DEBUG_KMS("Failed to enable scrambling: %d\n", ret);
183 return false; 183 return false;
184 } 184 }
185 185
@@ -223,7 +223,7 @@ bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set)
223 223
224 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config); 224 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config);
225 if (ret < 0) { 225 if (ret < 0) {
226 DRM_ERROR("Failed to read TMDS config: %d\n", ret); 226 DRM_DEBUG_KMS("Failed to read TMDS config: %d\n", ret);
227 return false; 227 return false;
228 } 228 }
229 229
@@ -234,7 +234,7 @@ bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set)
234 234
235 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config); 235 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config);
236 if (ret < 0) { 236 if (ret < 0) {
237 DRM_ERROR("Failed to set TMDS clock ratio: %d\n", ret); 237 DRM_DEBUG_KMS("Failed to set TMDS clock ratio: %d\n", ret);
238 return false; 238 return false;
239 } 239 }
240 240
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index 987a353c7f72..7a00455ca568 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -64,13 +64,15 @@ static int drm_simple_kms_crtc_check(struct drm_crtc *crtc,
64static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc, 64static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc,
65 struct drm_crtc_state *old_state) 65 struct drm_crtc_state *old_state)
66{ 66{
67 struct drm_plane *plane;
67 struct drm_simple_display_pipe *pipe; 68 struct drm_simple_display_pipe *pipe;
68 69
69 pipe = container_of(crtc, struct drm_simple_display_pipe, crtc); 70 pipe = container_of(crtc, struct drm_simple_display_pipe, crtc);
70 if (!pipe->funcs || !pipe->funcs->enable) 71 if (!pipe->funcs || !pipe->funcs->enable)
71 return; 72 return;
72 73
73 pipe->funcs->enable(pipe, crtc->state); 74 plane = &pipe->plane;
75 pipe->funcs->enable(pipe, crtc->state, plane->state);
74} 76}
75 77
76static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc, 78static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 1c5b5ce1fd7f..b3c1daad1169 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -331,9 +331,7 @@ struct device *drm_sysfs_minor_alloc(struct drm_minor *minor)
331 struct device *kdev; 331 struct device *kdev;
332 int r; 332 int r;
333 333
334 if (minor->type == DRM_MINOR_CONTROL) 334 if (minor->type == DRM_MINOR_RENDER)
335 minor_str = "controlD%d";
336 else if (minor->type == DRM_MINOR_RENDER)
337 minor_str = "renderD%d"; 335 minor_str = "renderD%d";
338 else 336 else
339 minor_str = "card%d"; 337 minor_str = "card%d";
diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kconfig
index e5bfeca361bd..041a77e400d4 100644
--- a/drivers/gpu/drm/etnaviv/Kconfig
+++ b/drivers/gpu/drm/etnaviv/Kconfig
@@ -22,11 +22,3 @@ config DRM_ETNAVIV_THERMAL
22 help 22 help
23 Compile in support for thermal throttling. 23 Compile in support for thermal throttling.
24 Say Y unless you want to risk burning your SoC. 24 Say Y unless you want to risk burning your SoC.
25
26config DRM_ETNAVIV_REGISTER_LOGGING
27 bool "enable ETNAVIV register logging"
28 depends on DRM_ETNAVIV
29 help
30 Compile in support for logging register reads/writes in a format
31 that can be parsed by envytools demsm tool. If enabled, register
32 logging can be switched on via etnaviv.reglog=y module param.
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
index bfc6d4aa3b7c..7fea74861a87 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
@@ -1,18 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2014 Etnaviv Project 3 * Copyright (C) 2014-2018 Etnaviv Project
3 * Author: Christian Gmeiner <christian.gmeiner@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 4 */
17 5
18#include "etnaviv_cmdbuf.h" 6#include "etnaviv_cmdbuf.h"
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c b/drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c
index 68e6d3772ad8..b106e8b288ad 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include <linux/kernel.h> 6#include <linux/kernel.h>
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c
index 3746827f45eb..a3c44f145c1d 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2017 Etnaviv Project 3 * Copyright (C) 2017-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include <drm/drm_mm.h> 6#include <drm/drm_mm.h>
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h
index ddc3f7ea169c..acb68c698363 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h
@@ -1,17 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2017 Etnaviv Project 3 * Copyright (C) 2017 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#ifndef __ETNAVIV_CMDBUF_H__ 6#ifndef __ETNAVIV_CMDBUF_H__
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index ab50090d066c..e5013a999147 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include <linux/component.h> 6#include <linux/component.h>
@@ -25,57 +14,6 @@
25#include "etnaviv_mmu.h" 14#include "etnaviv_mmu.h"
26#include "etnaviv_perfmon.h" 15#include "etnaviv_perfmon.h"
27 16
28#ifdef CONFIG_DRM_ETNAVIV_REGISTER_LOGGING
29static bool reglog;
30MODULE_PARM_DESC(reglog, "Enable register read/write logging");
31module_param(reglog, bool, 0600);
32#else
33#define reglog 0
34#endif
35
36void __iomem *etnaviv_ioremap(struct platform_device *pdev, const char *name,
37 const char *dbgname)
38{
39 struct resource *res;
40 void __iomem *ptr;
41
42 if (name)
43 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
44 else
45 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
46
47 ptr = devm_ioremap_resource(&pdev->dev, res);
48 if (IS_ERR(ptr)) {
49 dev_err(&pdev->dev, "failed to ioremap %s: %ld\n", name,
50 PTR_ERR(ptr));
51 return ptr;
52 }
53
54 if (reglog)
55 dev_printk(KERN_DEBUG, &pdev->dev, "IO:region %s 0x%p %08zx\n",
56 dbgname, ptr, (size_t)resource_size(res));
57
58 return ptr;
59}
60
61void etnaviv_writel(u32 data, void __iomem *addr)
62{
63 if (reglog)
64 printk(KERN_DEBUG "IO:W %p %08x\n", addr, data);
65
66 writel(data, addr);
67}
68
69u32 etnaviv_readl(const void __iomem *addr)
70{
71 u32 val = readl(addr);
72
73 if (reglog)
74 printk(KERN_DEBUG "IO:R %p %08x\n", addr, val);
75
76 return val;
77}
78
79/* 17/*
80 * DRM operations: 18 * DRM operations:
81 */ 19 */
@@ -116,7 +54,7 @@ static int etnaviv_open(struct drm_device *dev, struct drm_file *file)
116 drm_sched_entity_init(&gpu->sched, 54 drm_sched_entity_init(&gpu->sched,
117 &ctx->sched_entity[i], 55 &ctx->sched_entity[i],
118 &gpu->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL], 56 &gpu->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL],
119 32, NULL); 57 NULL);
120 } 58 }
121 } 59 }
122 60
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index ddb17ee565e9..d36c7bbe66db 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -1,17 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#ifndef __ETNAVIV_DRV_H__ 6#ifndef __ETNAVIV_DRV_H__
@@ -26,6 +15,7 @@
26#include <linux/pm_runtime.h> 15#include <linux/pm_runtime.h>
27#include <linux/slab.h> 16#include <linux/slab.h>
28#include <linux/list.h> 17#include <linux/list.h>
18#include <linux/time64.h>
29#include <linux/types.h> 19#include <linux/types.h>
30#include <linux/sizes.h> 20#include <linux/sizes.h>
31 21
@@ -101,11 +91,6 @@ void etnaviv_gem_describe_objects(struct etnaviv_drm_private *priv,
101 struct seq_file *m); 91 struct seq_file *m);
102#endif 92#endif
103 93
104void __iomem *etnaviv_ioremap(struct platform_device *pdev, const char *name,
105 const char *dbgname);
106void etnaviv_writel(u32 data, void __iomem *addr);
107u32 etnaviv_readl(const void __iomem *addr);
108
109#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 94#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
110#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 95#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
111 96
@@ -132,19 +117,27 @@ static inline bool fence_after_eq(u32 a, u32 b)
132 return (s32)(a - b) >= 0; 117 return (s32)(a - b) >= 0;
133} 118}
134 119
120/*
121 * Etnaviv timeouts are specified wrt CLOCK_MONOTONIC, not jiffies.
122 * We need to calculate the timeout in terms of number of jiffies
123 * between the specified timeout and the current CLOCK_MONOTONIC time.
124 */
135static inline unsigned long etnaviv_timeout_to_jiffies( 125static inline unsigned long etnaviv_timeout_to_jiffies(
136 const struct timespec *timeout) 126 const struct timespec *timeout)
137{ 127{
138 unsigned long timeout_jiffies = timespec_to_jiffies(timeout); 128 struct timespec64 ts, to;
139 unsigned long start_jiffies = jiffies; 129
140 unsigned long remaining_jiffies; 130 to = timespec_to_timespec64(*timeout);
131
132 ktime_get_ts64(&ts);
133
134 /* timeouts before "now" have already expired */
135 if (timespec64_compare(&to, &ts) <= 0)
136 return 0;
141 137
142 if (time_after(start_jiffies, timeout_jiffies)) 138 ts = timespec64_sub(to, ts);
143 remaining_jiffies = 0;
144 else
145 remaining_jiffies = timeout_jiffies - start_jiffies;
146 139
147 return remaining_jiffies; 140 return timespec64_to_jiffies(&ts);
148} 141}
149 142
150#endif /* __ETNAVIV_DRV_H__ */ 143#endif /* __ETNAVIV_DRV_H__ */
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
index 48aef6cf6a42..9146e30e24a6 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include <linux/devcoredump.h> 6#include <linux/devcoredump.h>
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.h b/drivers/gpu/drm/etnaviv/etnaviv_dump.h
index 97f2f8db9133..2d916c2667ee 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_dump.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.h
@@ -1,20 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Etnaviv devcoredump file definitions
17 */ 4 */
5
18#ifndef ETNAVIV_DUMP_H 6#ifndef ETNAVIV_DUMP_H
19#define ETNAVIV_DUMP_H 7#define ETNAVIV_DUMP_H
20 8
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index fcc969fa0e69..209ef1274b80 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include <linux/spinlock.h> 6#include <linux/spinlock.h>
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnaviv/etnaviv_gem.h
index 93e696fcc14f..76079c2291f8 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h
@@ -1,17 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#ifndef __ETNAVIV_GEM_H__ 6#ifndef __ETNAVIV_GEM_H__
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
index 5704305d41e6..0566171f8df2 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
@@ -1,18 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2013 Red Hat 3 * Copyright (C) 2014-2018 Etnaviv Project
3 * Author: Rob Clark <robdclark@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 4 */
17 5
18#include <linux/dma-buf.h> 6#include <linux/dma-buf.h>
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 8a88799bf79b..686f6552db48 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include <linux/component.h> 6#include <linux/component.h>
@@ -1735,6 +1724,7 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
1735{ 1724{
1736 struct device *dev = &pdev->dev; 1725 struct device *dev = &pdev->dev;
1737 struct etnaviv_gpu *gpu; 1726 struct etnaviv_gpu *gpu;
1727 struct resource *res;
1738 int err; 1728 int err;
1739 1729
1740 gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL); 1730 gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL);
@@ -1746,7 +1736,8 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
1746 mutex_init(&gpu->fence_idr_lock); 1736 mutex_init(&gpu->fence_idr_lock);
1747 1737
1748 /* Map registers: */ 1738 /* Map registers: */
1749 gpu->mmio = etnaviv_ioremap(pdev, NULL, dev_name(gpu->dev)); 1739 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1740 gpu->mmio = devm_ioremap_resource(&pdev->dev, res);
1750 if (IS_ERR(gpu->mmio)) 1741 if (IS_ERR(gpu->mmio))
1751 return PTR_ERR(gpu->mmio); 1742 return PTR_ERR(gpu->mmio);
1752 1743
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
index 3c3005501846..dd430f0f8ff5 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
@@ -1,17 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#ifndef __ETNAVIV_GPU_H__ 6#ifndef __ETNAVIV_GPU_H__
@@ -161,12 +150,12 @@ struct etnaviv_gpu {
161 150
162static inline void gpu_write(struct etnaviv_gpu *gpu, u32 reg, u32 data) 151static inline void gpu_write(struct etnaviv_gpu *gpu, u32 reg, u32 data)
163{ 152{
164 etnaviv_writel(data, gpu->mmio + reg); 153 writel(data, gpu->mmio + reg);
165} 154}
166 155
167static inline u32 gpu_read(struct etnaviv_gpu *gpu, u32 reg) 156static inline u32 gpu_read(struct etnaviv_gpu *gpu, u32 reg)
168{ 157{
169 return etnaviv_readl(gpu->mmio + reg); 158 return readl(gpu->mmio + reg);
170} 159}
171 160
172static inline bool fence_completed(struct etnaviv_gpu *gpu, u32 fence) 161static inline bool fence_completed(struct etnaviv_gpu *gpu, u32 fence)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
index ea08bb38caaf..39b463db76c9 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2018 Etnaviv Project 3 * Copyright (C) 2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include "etnaviv_gpu.h" 6#include "etnaviv_gpu.h"
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
index 4b9b11ca6f03..b163bdbcb880 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2014 Christian Gmeiner <christian.gmeiner@gmail.com> 3 * Copyright (C) 2014-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include <linux/platform_device.h> 6#include <linux/platform_device.h>
@@ -47,11 +36,10 @@ static int __etnaviv_iommu_init(struct etnaviv_iommuv1_domain *etnaviv_domain)
47 u32 *p; 36 u32 *p;
48 int i; 37 int i;
49 38
50 etnaviv_domain->base.bad_page_cpu = dma_alloc_coherent( 39 etnaviv_domain->base.bad_page_cpu =
51 etnaviv_domain->base.dev, 40 dma_alloc_wc(etnaviv_domain->base.dev, SZ_4K,
52 SZ_4K, 41 &etnaviv_domain->base.bad_page_dma,
53 &etnaviv_domain->base.bad_page_dma, 42 GFP_KERNEL);
54 GFP_KERNEL);
55 if (!etnaviv_domain->base.bad_page_cpu) 43 if (!etnaviv_domain->base.bad_page_cpu)
56 return -ENOMEM; 44 return -ENOMEM;
57 45
@@ -59,14 +47,14 @@ static int __etnaviv_iommu_init(struct etnaviv_iommuv1_domain *etnaviv_domain)
59 for (i = 0; i < SZ_4K / 4; i++) 47 for (i = 0; i < SZ_4K / 4; i++)
60 *p++ = 0xdead55aa; 48 *p++ = 0xdead55aa;
61 49
62 etnaviv_domain->pgtable_cpu = 50 etnaviv_domain->pgtable_cpu = dma_alloc_wc(etnaviv_domain->base.dev,
63 dma_alloc_coherent(etnaviv_domain->base.dev, PT_SIZE, 51 PT_SIZE,
64 &etnaviv_domain->pgtable_dma, 52 &etnaviv_domain->pgtable_dma,
65 GFP_KERNEL); 53 GFP_KERNEL);
66 if (!etnaviv_domain->pgtable_cpu) { 54 if (!etnaviv_domain->pgtable_cpu) {
67 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 55 dma_free_wc(etnaviv_domain->base.dev, SZ_4K,
68 etnaviv_domain->base.bad_page_cpu, 56 etnaviv_domain->base.bad_page_cpu,
69 etnaviv_domain->base.bad_page_dma); 57 etnaviv_domain->base.bad_page_dma);
70 return -ENOMEM; 58 return -ENOMEM;
71 } 59 }
72 60
@@ -81,13 +69,12 @@ static void etnaviv_iommuv1_domain_free(struct etnaviv_iommu_domain *domain)
81 struct etnaviv_iommuv1_domain *etnaviv_domain = 69 struct etnaviv_iommuv1_domain *etnaviv_domain =
82 to_etnaviv_domain(domain); 70 to_etnaviv_domain(domain);
83 71
84 dma_free_coherent(etnaviv_domain->base.dev, PT_SIZE, 72 dma_free_wc(etnaviv_domain->base.dev, PT_SIZE,
85 etnaviv_domain->pgtable_cpu, 73 etnaviv_domain->pgtable_cpu, etnaviv_domain->pgtable_dma);
86 etnaviv_domain->pgtable_dma);
87 74
88 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 75 dma_free_wc(etnaviv_domain->base.dev, SZ_4K,
89 etnaviv_domain->base.bad_page_cpu, 76 etnaviv_domain->base.bad_page_cpu,
90 etnaviv_domain->base.bad_page_dma); 77 etnaviv_domain->base.bad_page_dma);
91 78
92 kfree(etnaviv_domain); 79 kfree(etnaviv_domain);
93} 80}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.h b/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
index 01d59bf70d78..b279404ce91a 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
@@ -1,17 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2014 Christian Gmeiner <christian.gmeiner@gmail.com> 3 * Copyright (C) 2014-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#ifndef __ETNAVIV_IOMMU_H__ 6#ifndef __ETNAVIV_IOMMU_H__
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
index 9752dbd5d28b..71fbc1f96cb6 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2016 Etnaviv Project 3 * Copyright (C) 2016-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include <linux/platform_device.h> 6#include <linux/platform_device.h>
@@ -47,8 +36,8 @@ struct etnaviv_iommuv2_domain {
47 u32 *mtlb_cpu; 36 u32 *mtlb_cpu;
48 dma_addr_t mtlb_dma; 37 dma_addr_t mtlb_dma;
49 /* S(lave) TLB aka second level pagetable */ 38 /* S(lave) TLB aka second level pagetable */
50 u32 *stlb_cpu[1024]; 39 u32 *stlb_cpu[MMUv2_MAX_STLB_ENTRIES];
51 dma_addr_t stlb_dma[1024]; 40 dma_addr_t stlb_dma[MMUv2_MAX_STLB_ENTRIES];
52}; 41};
53 42
54static struct etnaviv_iommuv2_domain * 43static struct etnaviv_iommuv2_domain *
@@ -57,24 +46,54 @@ to_etnaviv_domain(struct etnaviv_iommu_domain *domain)
57 return container_of(domain, struct etnaviv_iommuv2_domain, base); 46 return container_of(domain, struct etnaviv_iommuv2_domain, base);
58} 47}
59 48
49static int
50etnaviv_iommuv2_ensure_stlb(struct etnaviv_iommuv2_domain *etnaviv_domain,
51 int stlb)
52{
53 if (etnaviv_domain->stlb_cpu[stlb])
54 return 0;
55
56 etnaviv_domain->stlb_cpu[stlb] =
57 dma_alloc_wc(etnaviv_domain->base.dev, SZ_4K,
58 &etnaviv_domain->stlb_dma[stlb],
59 GFP_KERNEL);
60
61 if (!etnaviv_domain->stlb_cpu[stlb])
62 return -ENOMEM;
63
64 memset32(etnaviv_domain->stlb_cpu[stlb], MMUv2_PTE_EXCEPTION,
65 SZ_4K / sizeof(u32));
66
67 etnaviv_domain->mtlb_cpu[stlb] = etnaviv_domain->stlb_dma[stlb] |
68 MMUv2_PTE_PRESENT;
69 return 0;
70}
71
60static int etnaviv_iommuv2_map(struct etnaviv_iommu_domain *domain, 72static int etnaviv_iommuv2_map(struct etnaviv_iommu_domain *domain,
61 unsigned long iova, phys_addr_t paddr, 73 unsigned long iova, phys_addr_t paddr,
62 size_t size, int prot) 74 size_t size, int prot)
63{ 75{
64 struct etnaviv_iommuv2_domain *etnaviv_domain = 76 struct etnaviv_iommuv2_domain *etnaviv_domain =
65 to_etnaviv_domain(domain); 77 to_etnaviv_domain(domain);
66 int mtlb_entry, stlb_entry; 78 int mtlb_entry, stlb_entry, ret;
67 u32 entry = (u32)paddr | MMUv2_PTE_PRESENT; 79 u32 entry = lower_32_bits(paddr) | MMUv2_PTE_PRESENT;
68 80
69 if (size != SZ_4K) 81 if (size != SZ_4K)
70 return -EINVAL; 82 return -EINVAL;
71 83
84 if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))
85 entry |= (upper_32_bits(paddr) & 0xff) << 4;
86
72 if (prot & ETNAVIV_PROT_WRITE) 87 if (prot & ETNAVIV_PROT_WRITE)
73 entry |= MMUv2_PTE_WRITEABLE; 88 entry |= MMUv2_PTE_WRITEABLE;
74 89
75 mtlb_entry = (iova & MMUv2_MTLB_MASK) >> MMUv2_MTLB_SHIFT; 90 mtlb_entry = (iova & MMUv2_MTLB_MASK) >> MMUv2_MTLB_SHIFT;
76 stlb_entry = (iova & MMUv2_STLB_MASK) >> MMUv2_STLB_SHIFT; 91 stlb_entry = (iova & MMUv2_STLB_MASK) >> MMUv2_STLB_SHIFT;
77 92
93 ret = etnaviv_iommuv2_ensure_stlb(etnaviv_domain, mtlb_entry);
94 if (ret)
95 return ret;
96
78 etnaviv_domain->stlb_cpu[mtlb_entry][stlb_entry] = entry; 97 etnaviv_domain->stlb_cpu[mtlb_entry][stlb_entry] = entry;
79 98
80 return 0; 99 return 0;
@@ -101,14 +120,13 @@ static size_t etnaviv_iommuv2_unmap(struct etnaviv_iommu_domain *domain,
101static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain) 120static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain)
102{ 121{
103 u32 *p; 122 u32 *p;
104 int ret, i, j; 123 int ret, i;
105 124
106 /* allocate scratch page */ 125 /* allocate scratch page */
107 etnaviv_domain->base.bad_page_cpu = dma_alloc_coherent( 126 etnaviv_domain->base.bad_page_cpu =
108 etnaviv_domain->base.dev, 127 dma_alloc_wc(etnaviv_domain->base.dev, SZ_4K,
109 SZ_4K, 128 &etnaviv_domain->base.bad_page_dma,
110 &etnaviv_domain->base.bad_page_dma, 129 GFP_KERNEL);
111 GFP_KERNEL);
112 if (!etnaviv_domain->base.bad_page_cpu) { 130 if (!etnaviv_domain->base.bad_page_cpu) {
113 ret = -ENOMEM; 131 ret = -ENOMEM;
114 goto fail_mem; 132 goto fail_mem;
@@ -117,67 +135,40 @@ static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain)
117 for (i = 0; i < SZ_4K / 4; i++) 135 for (i = 0; i < SZ_4K / 4; i++)
118 *p++ = 0xdead55aa; 136 *p++ = 0xdead55aa;
119 137
120 etnaviv_domain->pta_cpu = dma_alloc_coherent(etnaviv_domain->base.dev, 138 etnaviv_domain->pta_cpu = dma_alloc_wc(etnaviv_domain->base.dev,
121 SZ_4K, 139 SZ_4K, &etnaviv_domain->pta_dma,
122 &etnaviv_domain->pta_dma, 140 GFP_KERNEL);
123 GFP_KERNEL);
124 if (!etnaviv_domain->pta_cpu) { 141 if (!etnaviv_domain->pta_cpu) {
125 ret = -ENOMEM; 142 ret = -ENOMEM;
126 goto fail_mem; 143 goto fail_mem;
127 } 144 }
128 145
129 etnaviv_domain->mtlb_cpu = dma_alloc_coherent(etnaviv_domain->base.dev, 146 etnaviv_domain->mtlb_cpu = dma_alloc_wc(etnaviv_domain->base.dev,
130 SZ_4K, 147 SZ_4K, &etnaviv_domain->mtlb_dma,
131 &etnaviv_domain->mtlb_dma, 148 GFP_KERNEL);
132 GFP_KERNEL);
133 if (!etnaviv_domain->mtlb_cpu) { 149 if (!etnaviv_domain->mtlb_cpu) {
134 ret = -ENOMEM; 150 ret = -ENOMEM;
135 goto fail_mem; 151 goto fail_mem;
136 } 152 }
137 153
138 /* pre-populate STLB pages (may want to switch to on-demand later) */ 154 memset32(etnaviv_domain->mtlb_cpu, MMUv2_PTE_EXCEPTION,
139 for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) { 155 MMUv2_MAX_STLB_ENTRIES);
140 etnaviv_domain->stlb_cpu[i] =
141 dma_alloc_coherent(etnaviv_domain->base.dev,
142 SZ_4K,
143 &etnaviv_domain->stlb_dma[i],
144 GFP_KERNEL);
145 if (!etnaviv_domain->stlb_cpu[i]) {
146 ret = -ENOMEM;
147 goto fail_mem;
148 }
149 p = etnaviv_domain->stlb_cpu[i];
150 for (j = 0; j < SZ_4K / 4; j++)
151 *p++ = MMUv2_PTE_EXCEPTION;
152
153 etnaviv_domain->mtlb_cpu[i] = etnaviv_domain->stlb_dma[i] |
154 MMUv2_PTE_PRESENT;
155 }
156 156
157 return 0; 157 return 0;
158 158
159fail_mem: 159fail_mem:
160 if (etnaviv_domain->base.bad_page_cpu) 160 if (etnaviv_domain->base.bad_page_cpu)
161 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 161 dma_free_wc(etnaviv_domain->base.dev, SZ_4K,
162 etnaviv_domain->base.bad_page_cpu, 162 etnaviv_domain->base.bad_page_cpu,
163 etnaviv_domain->base.bad_page_dma); 163 etnaviv_domain->base.bad_page_dma);
164 164
165 if (etnaviv_domain->pta_cpu) 165 if (etnaviv_domain->pta_cpu)
166 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 166 dma_free_wc(etnaviv_domain->base.dev, SZ_4K,
167 etnaviv_domain->pta_cpu, 167 etnaviv_domain->pta_cpu, etnaviv_domain->pta_dma);
168 etnaviv_domain->pta_dma);
169 168
170 if (etnaviv_domain->mtlb_cpu) 169 if (etnaviv_domain->mtlb_cpu)
171 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 170 dma_free_wc(etnaviv_domain->base.dev, SZ_4K,
172 etnaviv_domain->mtlb_cpu, 171 etnaviv_domain->mtlb_cpu, etnaviv_domain->mtlb_dma);
173 etnaviv_domain->mtlb_dma);
174
175 for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) {
176 if (etnaviv_domain->stlb_cpu[i])
177 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K,
178 etnaviv_domain->stlb_cpu[i],
179 etnaviv_domain->stlb_dma[i]);
180 }
181 172
182 return ret; 173 return ret;
183} 174}
@@ -188,23 +179,21 @@ static void etnaviv_iommuv2_domain_free(struct etnaviv_iommu_domain *domain)
188 to_etnaviv_domain(domain); 179 to_etnaviv_domain(domain);
189 int i; 180 int i;
190 181
191 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 182 dma_free_wc(etnaviv_domain->base.dev, SZ_4K,
192 etnaviv_domain->base.bad_page_cpu, 183 etnaviv_domain->base.bad_page_cpu,
193 etnaviv_domain->base.bad_page_dma); 184 etnaviv_domain->base.bad_page_dma);
194 185
195 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 186 dma_free_wc(etnaviv_domain->base.dev, SZ_4K,
196 etnaviv_domain->pta_cpu, 187 etnaviv_domain->pta_cpu, etnaviv_domain->pta_dma);
197 etnaviv_domain->pta_dma);
198 188
199 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 189 dma_free_wc(etnaviv_domain->base.dev, SZ_4K,
200 etnaviv_domain->mtlb_cpu, 190 etnaviv_domain->mtlb_cpu, etnaviv_domain->mtlb_dma);
201 etnaviv_domain->mtlb_dma);
202 191
203 for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) { 192 for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) {
204 if (etnaviv_domain->stlb_cpu[i]) 193 if (etnaviv_domain->stlb_cpu[i])
205 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 194 dma_free_wc(etnaviv_domain->base.dev, SZ_4K,
206 etnaviv_domain->stlb_cpu[i], 195 etnaviv_domain->stlb_cpu[i],
207 etnaviv_domain->stlb_dma[i]); 196 etnaviv_domain->stlb_dma[i]);
208 } 197 }
209 198
210 vfree(etnaviv_domain); 199 vfree(etnaviv_domain);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
index 49e049713a52..8069f9f36a2e 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include "common.xml.h" 6#include "common.xml.h"
@@ -162,22 +151,10 @@ static int etnaviv_iommu_find_iova(struct etnaviv_iommu *mmu,
162 bool found; 151 bool found;
163 152
164 ret = drm_mm_insert_node_in_range(&mmu->mm, node, 153 ret = drm_mm_insert_node_in_range(&mmu->mm, node,
165 size, 0, 0, 154 size, 0, 0, 0, U64_MAX, mode);
166 mmu->last_iova, U64_MAX,
167 mode);
168 if (ret != -ENOSPC) 155 if (ret != -ENOSPC)
169 break; 156 break;
170 157
171 /*
172 * If we did not search from the start of the MMU region,
173 * try again in case there are free slots.
174 */
175 if (mmu->last_iova) {
176 mmu->last_iova = 0;
177 mmu->need_flush = true;
178 continue;
179 }
180
181 /* Try to retire some entries */ 158 /* Try to retire some entries */
182 drm_mm_scan_init(&scan, &mmu->mm, size, 0, 0, mode); 159 drm_mm_scan_init(&scan, &mmu->mm, size, 0, 0, mode);
183 160
@@ -274,7 +251,6 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu *mmu,
274 if (ret < 0) 251 if (ret < 0)
275 goto unlock; 252 goto unlock;
276 253
277 mmu->last_iova = node->start + etnaviv_obj->base.size;
278 mapping->iova = node->start; 254 mapping->iova = node->start;
279 ret = etnaviv_iommu_map(mmu, node->start, sgt, etnaviv_obj->base.size, 255 ret = etnaviv_iommu_map(mmu, node->start, sgt, etnaviv_obj->base.size,
280 ETNAVIV_PROT_READ | ETNAVIV_PROT_WRITE); 256 ETNAVIV_PROT_READ | ETNAVIV_PROT_WRITE);
@@ -381,7 +357,6 @@ int etnaviv_iommu_get_suballoc_va(struct etnaviv_gpu *gpu, dma_addr_t paddr,
381 mutex_unlock(&mmu->lock); 357 mutex_unlock(&mmu->lock);
382 return ret; 358 return ret;
383 } 359 }
384 mmu->last_iova = vram_node->start + size;
385 gpu->mmu->need_flush = true; 360 gpu->mmu->need_flush = true;
386 mutex_unlock(&mmu->lock); 361 mutex_unlock(&mmu->lock);
387 362
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
index ab603f5166b1..a0db17ffb686 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
@@ -1,17 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2015 Etnaviv Project 3 * Copyright (C) 2015-2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#ifndef __ETNAVIV_MMU_H__ 6#ifndef __ETNAVIV_MMU_H__
@@ -59,7 +48,6 @@ struct etnaviv_iommu {
59 struct mutex lock; 48 struct mutex lock;
60 struct list_head mappings; 49 struct list_head mappings;
61 struct drm_mm mm; 50 struct drm_mm mm;
62 u32 last_iova;
63 bool need_flush; 51 bool need_flush;
64}; 52};
65 53
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c
index 26dddfc41aac..9980d81a26e3 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c
@@ -1,18 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2017 Etnaviv Project 3 * Copyright (C) 2017 Etnaviv Project
3 * Copyright (C) 2017 Zodiac Inflight Innovations 4 * Copyright (C) 2017 Zodiac Inflight Innovations
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 5 */
17 6
18#include "etnaviv_gpu.h" 7#include "etnaviv_gpu.h"
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h
index c1653c64ab6b..4a9d508f6e10 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h
@@ -1,18 +1,7 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2017 Etnaviv Project 3 * Copyright (C) 2017 Etnaviv Project
3 * Copyright (C) 2017 Zodiac Inflight Innovations 4 * Copyright (C) 2017 Zodiac Inflight Innovations
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 5 */
17 6
18#ifndef __ETNAVIV_PERFMON_H__ 7#ifndef __ETNAVIV_PERFMON_H__
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
index 6cf0775dbcd7..a74eb57af15b 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
@@ -1,17 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) 2017 Etnaviv Project 3 * Copyright (C) 2017 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#include <linux/kthread.h> 6#include <linux/kthread.h>
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.h b/drivers/gpu/drm/etnaviv/etnaviv_sched.h
index 097635fa78ae..c0a6796e22c9 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.h
@@ -1,17 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (C) 2017 Etnaviv Project 3 * Copyright (C) 2017 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 4 */
16 5
17#ifndef __ETNAVIV_SCHED_H__ 6#ifndef __ETNAVIV_SCHED_H__
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 735ce47688f9..208bc27be3cc 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -1,6 +1,6 @@
1config DRM_EXYNOS 1config DRM_EXYNOS
2 tristate "DRM Support for Samsung SoC EXYNOS Series" 2 tristate "DRM Support for Samsung SoC EXYNOS Series"
3 depends on OF && DRM && (ARCH_S3C64XX || ARCH_EXYNOS || ARCH_MULTIPLATFORM) 3 depends on OF && DRM && (ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || ARCH_MULTIPLATFORM)
4 select DRM_KMS_HELPER 4 select DRM_KMS_HELPER
5 select VIDEOMODE_HELPERS 5 select VIDEOMODE_HELPERS
6 select SND_SOC_HDMI_CODEC if SND_SOC 6 select SND_SOC_HDMI_CODEC if SND_SOC
@@ -95,21 +95,31 @@ config DRM_EXYNOS_G2D
95 help 95 help
96 Choose this option if you want to use Exynos G2D for DRM. 96 Choose this option if you want to use Exynos G2D for DRM.
97 97
98config DRM_EXYNOS_IPP
99 bool
100
98config DRM_EXYNOS_FIMC 101config DRM_EXYNOS_FIMC
99 bool "FIMC" 102 bool "FIMC"
100 depends on BROKEN && MFD_SYSCON 103 select DRM_EXYNOS_IPP
101 help 104 help
102 Choose this option if you want to use Exynos FIMC for DRM. 105 Choose this option if you want to use Exynos FIMC for DRM.
103 106
104config DRM_EXYNOS_ROTATOR 107config DRM_EXYNOS_ROTATOR
105 bool "Rotator" 108 bool "Rotator"
106 depends on BROKEN 109 select DRM_EXYNOS_IPP
107 help 110 help
108 Choose this option if you want to use Exynos Rotator for DRM. 111 Choose this option if you want to use Exynos Rotator for DRM.
109 112
113config DRM_EXYNOS_SCALER
114 bool "Scaler"
115 select DRM_EXYNOS_IPP
116 help
117 Choose this option if you want to use Exynos Scaler for DRM.
118
110config DRM_EXYNOS_GSC 119config DRM_EXYNOS_GSC
111 bool "GScaler" 120 bool "GScaler"
112 depends on BROKEN && ARCH_EXYNOS5 && VIDEO_SAMSUNG_EXYNOS_GSC=n 121 depends on VIDEO_SAMSUNG_EXYNOS_GSC=n
122 select DRM_EXYNOS_IPP
113 help 123 help
114 Choose this option if you want to use Exynos GSC for DRM. 124 Choose this option if you want to use Exynos GSC for DRM.
115 125
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index a51c5459bb13..3b323f1e0475 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -18,8 +18,10 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER) += exynos_mixer.o
18exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o 18exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o
19exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o 19exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o
20exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o 20exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o
21exynosdrm-$(CONFIG_DRM_EXYNOS_IPP) += exynos_drm_ipp.o
21exynosdrm-$(CONFIG_DRM_EXYNOS_FIMC) += exynos_drm_fimc.o 22exynosdrm-$(CONFIG_DRM_EXYNOS_FIMC) += exynos_drm_fimc.o
22exynosdrm-$(CONFIG_DRM_EXYNOS_ROTATOR) += exynos_drm_rotator.o 23exynosdrm-$(CONFIG_DRM_EXYNOS_ROTATOR) += exynos_drm_rotator.o
24exynosdrm-$(CONFIG_DRM_EXYNOS_SCALER) += exynos_drm_scaler.o
23exynosdrm-$(CONFIG_DRM_EXYNOS_GSC) += exynos_drm_gsc.o 25exynosdrm-$(CONFIG_DRM_EXYNOS_GSC) += exynos_drm_gsc.o
24exynosdrm-$(CONFIG_DRM_EXYNOS_MIC) += exynos_drm_mic.o 26exynosdrm-$(CONFIG_DRM_EXYNOS_MIC) += exynos_drm_mic.o
25 27
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 1c330f2a7a5d..82c95c34447f 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -31,7 +31,10 @@
31#define DSD_CFG_MUX 0x1004 31#define DSD_CFG_MUX 0x1004
32#define DSD_CFG_MUX_TE_UNMASK_GLOBAL BIT(13) 32#define DSD_CFG_MUX_TE_UNMASK_GLOBAL BIT(13)
33 33
34#define WINDOWS_NR 3 34#define WINDOWS_NR 5
35#define PRIMARY_WIN 2
36#define CURSON_WIN 4
37
35#define MIN_FB_WIDTH_FOR_16WORD_BURST 128 38#define MIN_FB_WIDTH_FOR_16WORD_BURST 128
36 39
37#define I80_HW_TRG (1 << 0) 40#define I80_HW_TRG (1 << 0)
@@ -43,6 +46,9 @@ static const char * const decon_clks_name[] = {
43 "aclk_smmu_decon0x", 46 "aclk_smmu_decon0x",
44 "aclk_xiu_decon0x", 47 "aclk_xiu_decon0x",
45 "pclk_smmu_decon0x", 48 "pclk_smmu_decon0x",
49 "aclk_smmu_decon1x",
50 "aclk_xiu_decon1x",
51 "pclk_smmu_decon1x",
46 "sclk_decon_vclk", 52 "sclk_decon_vclk",
47 "sclk_decon_eclk", 53 "sclk_decon_eclk",
48}; 54};
@@ -74,9 +80,8 @@ static const uint32_t decon_formats[] = {
74}; 80};
75 81
76static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { 82static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
77 DRM_PLANE_TYPE_PRIMARY, 83 [PRIMARY_WIN] = DRM_PLANE_TYPE_PRIMARY,
78 DRM_PLANE_TYPE_OVERLAY, 84 [CURSON_WIN] = DRM_PLANE_TYPE_CURSOR,
79 DRM_PLANE_TYPE_CURSOR,
80}; 85};
81 86
82static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, 87static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
@@ -552,12 +557,10 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
552 drm_dev->max_vblank_count = 0xffffffff; 557 drm_dev->max_vblank_count = 0xffffffff;
553 558
554 for (win = ctx->first_win; win < WINDOWS_NR; win++) { 559 for (win = ctx->first_win; win < WINDOWS_NR; win++) {
555 int tmp = (win == ctx->first_win) ? 0 : win;
556
557 ctx->configs[win].pixel_formats = decon_formats; 560 ctx->configs[win].pixel_formats = decon_formats;
558 ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats); 561 ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats);
559 ctx->configs[win].zpos = win; 562 ctx->configs[win].zpos = win - ctx->first_win;
560 ctx->configs[win].type = decon_win_types[tmp]; 563 ctx->configs[win].type = decon_win_types[win];
561 564
562 ret = exynos_plane_init(drm_dev, &ctx->planes[win], win, 565 ret = exynos_plane_init(drm_dev, &ctx->planes[win], win,
563 &ctx->configs[win]); 566 &ctx->configs[win]);
@@ -565,7 +568,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
565 return ret; 568 return ret;
566 } 569 }
567 570
568 exynos_plane = &ctx->planes[ctx->first_win]; 571 exynos_plane = &ctx->planes[PRIMARY_WIN];
569 out_type = (ctx->out_type & IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI 572 out_type = (ctx->out_type & IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI
570 : EXYNOS_DISPLAY_TYPE_LCD; 573 : EXYNOS_DISPLAY_TYPE_LCD;
571 ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, 574 ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c
index 964831dab102..86330f396784 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -162,7 +162,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
162 dp->drm_dev = drm_dev; 162 dp->drm_dev = drm_dev;
163 163
164 dp->plat_data.dev_type = EXYNOS_DP; 164 dp->plat_data.dev_type = EXYNOS_DP;
165 dp->plat_data.power_on = exynos_dp_poweron; 165 dp->plat_data.power_on_start = exynos_dp_poweron;
166 dp->plat_data.power_off = exynos_dp_poweroff; 166 dp->plat_data.power_off = exynos_dp_poweroff;
167 dp->plat_data.attach = exynos_dp_bridge_attach; 167 dp->plat_data.attach = exynos_dp_bridge_attach;
168 dp->plat_data.get_modes = exynos_dp_get_modes; 168 dp->plat_data.get_modes = exynos_dp_get_modes;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index dc01342e759a..eea90251808f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -228,7 +228,7 @@ struct exynos_drm_crtc *exynos_drm_crtc_get_by_type(struct drm_device *drm_dev,
228 if (to_exynos_crtc(crtc)->type == out_type) 228 if (to_exynos_crtc(crtc)->type == out_type)
229 return to_exynos_crtc(crtc); 229 return to_exynos_crtc(crtc);
230 230
231 return ERR_PTR(-EPERM); 231 return ERR_PTR(-ENODEV);
232} 232}
233 233
234int exynos_drm_set_possible_crtcs(struct drm_encoder *encoder, 234int exynos_drm_set_possible_crtcs(struct drm_encoder *encoder,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index a518e9c6d6cc..a81b4a5e24a7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -27,35 +27,23 @@
27#include "exynos_drm_fb.h" 27#include "exynos_drm_fb.h"
28#include "exynos_drm_gem.h" 28#include "exynos_drm_gem.h"
29#include "exynos_drm_plane.h" 29#include "exynos_drm_plane.h"
30#include "exynos_drm_ipp.h"
30#include "exynos_drm_vidi.h" 31#include "exynos_drm_vidi.h"
31#include "exynos_drm_g2d.h" 32#include "exynos_drm_g2d.h"
32#include "exynos_drm_iommu.h" 33#include "exynos_drm_iommu.h"
33 34
34#define DRIVER_NAME "exynos" 35#define DRIVER_NAME "exynos"
35#define DRIVER_DESC "Samsung SoC DRM" 36#define DRIVER_DESC "Samsung SoC DRM"
36#define DRIVER_DATE "20110530" 37#define DRIVER_DATE "20180330"
37#define DRIVER_MAJOR 1
38#define DRIVER_MINOR 0
39
40int exynos_atomic_check(struct drm_device *dev,
41 struct drm_atomic_state *state)
42{
43 int ret;
44
45 ret = drm_atomic_helper_check_modeset(dev, state);
46 if (ret)
47 return ret;
48 38
49 ret = drm_atomic_normalize_zpos(dev, state); 39/*
50 if (ret) 40 * Interface history:
51 return ret; 41 *
52 42 * 1.0 - Original version
53 ret = drm_atomic_helper_check_planes(dev, state); 43 * 1.1 - Upgrade IPP driver to version 2.0
54 if (ret) 44 */
55 return ret; 45#define DRIVER_MAJOR 1
56 46#define DRIVER_MINOR 1
57 return ret;
58}
59 47
60static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) 48static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
61{ 49{
@@ -108,6 +96,16 @@ static const struct drm_ioctl_desc exynos_ioctls[] = {
108 DRM_AUTH | DRM_RENDER_ALLOW), 96 DRM_AUTH | DRM_RENDER_ALLOW),
109 DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC, exynos_g2d_exec_ioctl, 97 DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC, exynos_g2d_exec_ioctl,
110 DRM_AUTH | DRM_RENDER_ALLOW), 98 DRM_AUTH | DRM_RENDER_ALLOW),
99 DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_RESOURCES,
100 exynos_drm_ipp_get_res_ioctl,
101 DRM_AUTH | DRM_RENDER_ALLOW),
102 DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_CAPS, exynos_drm_ipp_get_caps_ioctl,
103 DRM_AUTH | DRM_RENDER_ALLOW),
104 DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_LIMITS,
105 exynos_drm_ipp_get_limits_ioctl,
106 DRM_AUTH | DRM_RENDER_ALLOW),
107 DRM_IOCTL_DEF_DRV(EXYNOS_IPP_COMMIT, exynos_drm_ipp_commit_ioctl,
108 DRM_AUTH | DRM_RENDER_ALLOW),
111}; 109};
112 110
113static const struct file_operations exynos_drm_driver_fops = { 111static const struct file_operations exynos_drm_driver_fops = {
@@ -204,6 +202,7 @@ struct exynos_drm_driver_info {
204#define DRM_COMPONENT_DRIVER BIT(0) /* supports component framework */ 202#define DRM_COMPONENT_DRIVER BIT(0) /* supports component framework */
205#define DRM_VIRTUAL_DEVICE BIT(1) /* create virtual platform device */ 203#define DRM_VIRTUAL_DEVICE BIT(1) /* create virtual platform device */
206#define DRM_DMA_DEVICE BIT(2) /* can be used for dma allocations */ 204#define DRM_DMA_DEVICE BIT(2) /* can be used for dma allocations */
205#define DRM_FIMC_DEVICE BIT(3) /* devices shared with V4L2 subsystem */
207 206
208#define DRV_PTR(drv, cond) (IS_ENABLED(cond) ? &drv : NULL) 207#define DRV_PTR(drv, cond) (IS_ENABLED(cond) ? &drv : NULL)
209 208
@@ -243,10 +242,16 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = {
243 DRV_PTR(g2d_driver, CONFIG_DRM_EXYNOS_G2D), 242 DRV_PTR(g2d_driver, CONFIG_DRM_EXYNOS_G2D),
244 }, { 243 }, {
245 DRV_PTR(fimc_driver, CONFIG_DRM_EXYNOS_FIMC), 244 DRV_PTR(fimc_driver, CONFIG_DRM_EXYNOS_FIMC),
245 DRM_COMPONENT_DRIVER | DRM_FIMC_DEVICE,
246 }, { 246 }, {
247 DRV_PTR(rotator_driver, CONFIG_DRM_EXYNOS_ROTATOR), 247 DRV_PTR(rotator_driver, CONFIG_DRM_EXYNOS_ROTATOR),
248 DRM_COMPONENT_DRIVER
249 }, {
250 DRV_PTR(scaler_driver, CONFIG_DRM_EXYNOS_SCALER),
251 DRM_COMPONENT_DRIVER
248 }, { 252 }, {
249 DRV_PTR(gsc_driver, CONFIG_DRM_EXYNOS_GSC), 253 DRV_PTR(gsc_driver, CONFIG_DRM_EXYNOS_GSC),
254 DRM_COMPONENT_DRIVER
250 }, { 255 }, {
251 &exynos_drm_platform_driver, 256 &exynos_drm_platform_driver,
252 DRM_VIRTUAL_DEVICE 257 DRM_VIRTUAL_DEVICE
@@ -274,7 +279,11 @@ static struct component_match *exynos_drm_match_add(struct device *dev)
274 &info->driver->driver, 279 &info->driver->driver,
275 (void *)platform_bus_type.match))) { 280 (void *)platform_bus_type.match))) {
276 put_device(p); 281 put_device(p);
277 component_match_add(dev, &match, compare_dev, d); 282
283 if (!(info->flags & DRM_FIMC_DEVICE) ||
284 exynos_drm_check_fimc_device(d) == 0)
285 component_match_add(dev, &match,
286 compare_dev, d);
278 p = d; 287 p = d;
279 } 288 }
280 put_device(p); 289 put_device(p);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index df2262f70d91..0f6d079a55c9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -273,9 +273,17 @@ static inline int exynos_dpi_bind(struct drm_device *dev,
273} 273}
274#endif 274#endif
275 275
276#ifdef CONFIG_DRM_EXYNOS_FIMC
277int exynos_drm_check_fimc_device(struct device *dev);
278#else
279static inline int exynos_drm_check_fimc_device(struct device *dev)
280{
281 return 0;
282}
283#endif
284
276int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, 285int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
277 bool nonblock); 286 bool nonblock);
278int exynos_atomic_check(struct drm_device *dev, struct drm_atomic_state *state);
279 287
280 288
281extern struct platform_driver fimd_driver; 289extern struct platform_driver fimd_driver;
@@ -289,6 +297,7 @@ extern struct platform_driver vidi_driver;
289extern struct platform_driver g2d_driver; 297extern struct platform_driver g2d_driver;
290extern struct platform_driver fimc_driver; 298extern struct platform_driver fimc_driver;
291extern struct platform_driver rotator_driver; 299extern struct platform_driver rotator_driver;
300extern struct platform_driver scaler_driver;
292extern struct platform_driver gsc_driver; 301extern struct platform_driver gsc_driver;
293extern struct platform_driver mic_driver; 302extern struct platform_driver mic_driver;
294#endif 303#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 7904ffa9abfb..7c3030b7e586 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -270,7 +270,6 @@ struct exynos_dsi {
270 u32 lanes; 270 u32 lanes;
271 u32 mode_flags; 271 u32 mode_flags;
272 u32 format; 272 u32 format;
273 struct videomode vm;
274 273
275 int state; 274 int state;
276 struct drm_property *brightness; 275 struct drm_property *brightness;
@@ -881,30 +880,30 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
881 880
882static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi) 881static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
883{ 882{
884 struct videomode *vm = &dsi->vm; 883 struct drm_display_mode *m = &dsi->encoder.crtc->state->adjusted_mode;
885 unsigned int num_bits_resol = dsi->driver_data->num_bits_resol; 884 unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
886 u32 reg; 885 u32 reg;
887 886
888 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { 887 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
889 reg = DSIM_CMD_ALLOW(0xf) 888 reg = DSIM_CMD_ALLOW(0xf)
890 | DSIM_STABLE_VFP(vm->vfront_porch) 889 | DSIM_STABLE_VFP(m->vsync_start - m->vdisplay)
891 | DSIM_MAIN_VBP(vm->vback_porch); 890 | DSIM_MAIN_VBP(m->vtotal - m->vsync_end);
892 exynos_dsi_write(dsi, DSIM_MVPORCH_REG, reg); 891 exynos_dsi_write(dsi, DSIM_MVPORCH_REG, reg);
893 892
894 reg = DSIM_MAIN_HFP(vm->hfront_porch) 893 reg = DSIM_MAIN_HFP(m->hsync_start - m->hdisplay)
895 | DSIM_MAIN_HBP(vm->hback_porch); 894 | DSIM_MAIN_HBP(m->htotal - m->hsync_end);
896 exynos_dsi_write(dsi, DSIM_MHPORCH_REG, reg); 895 exynos_dsi_write(dsi, DSIM_MHPORCH_REG, reg);
897 896
898 reg = DSIM_MAIN_VSA(vm->vsync_len) 897 reg = DSIM_MAIN_VSA(m->vsync_end - m->vsync_start)
899 | DSIM_MAIN_HSA(vm->hsync_len); 898 | DSIM_MAIN_HSA(m->hsync_end - m->hsync_start);
900 exynos_dsi_write(dsi, DSIM_MSYNC_REG, reg); 899 exynos_dsi_write(dsi, DSIM_MSYNC_REG, reg);
901 } 900 }
902 reg = DSIM_MAIN_HRESOL(vm->hactive, num_bits_resol) | 901 reg = DSIM_MAIN_HRESOL(m->hdisplay, num_bits_resol) |
903 DSIM_MAIN_VRESOL(vm->vactive, num_bits_resol); 902 DSIM_MAIN_VRESOL(m->vdisplay, num_bits_resol);
904 903
905 exynos_dsi_write(dsi, DSIM_MDRESOL_REG, reg); 904 exynos_dsi_write(dsi, DSIM_MDRESOL_REG, reg);
906 905
907 dev_dbg(dsi->dev, "LCD size = %dx%d\n", vm->hactive, vm->vactive); 906 dev_dbg(dsi->dev, "LCD size = %dx%d\n", m->hdisplay, m->vdisplay);
908} 907}
909 908
910static void exynos_dsi_set_display_enable(struct exynos_dsi *dsi, bool enable) 909static void exynos_dsi_set_display_enable(struct exynos_dsi *dsi, bool enable)
@@ -1265,15 +1264,15 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
1265 1264
1266 if (status & DSIM_INT_SW_RST_RELEASE) { 1265 if (status & DSIM_INT_SW_RST_RELEASE) {
1267 u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY | 1266 u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |
1268 DSIM_INT_SFR_HDR_FIFO_EMPTY | DSIM_INT_FRAME_DONE | 1267 DSIM_INT_SFR_HDR_FIFO_EMPTY | DSIM_INT_RX_ECC_ERR |
1269 DSIM_INT_RX_ECC_ERR | DSIM_INT_SW_RST_RELEASE); 1268 DSIM_INT_SW_RST_RELEASE);
1270 exynos_dsi_write(dsi, DSIM_INTMSK_REG, mask); 1269 exynos_dsi_write(dsi, DSIM_INTMSK_REG, mask);
1271 complete(&dsi->completed); 1270 complete(&dsi->completed);
1272 return IRQ_HANDLED; 1271 return IRQ_HANDLED;
1273 } 1272 }
1274 1273
1275 if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY | 1274 if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |
1276 DSIM_INT_FRAME_DONE | DSIM_INT_PLL_STABLE))) 1275 DSIM_INT_PLL_STABLE)))
1277 return IRQ_HANDLED; 1276 return IRQ_HANDLED;
1278 1277
1279 if (exynos_dsi_transfer_finish(dsi)) 1278 if (exynos_dsi_transfer_finish(dsi))
@@ -1485,26 +1484,7 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder)
1485 return 0; 1484 return 0;
1486} 1485}
1487 1486
1488static void exynos_dsi_mode_set(struct drm_encoder *encoder,
1489 struct drm_display_mode *mode,
1490 struct drm_display_mode *adjusted_mode)
1491{
1492 struct exynos_dsi *dsi = encoder_to_dsi(encoder);
1493 struct videomode *vm = &dsi->vm;
1494 struct drm_display_mode *m = adjusted_mode;
1495
1496 vm->hactive = m->hdisplay;
1497 vm->vactive = m->vdisplay;
1498 vm->vfront_porch = m->vsync_start - m->vdisplay;
1499 vm->vback_porch = m->vtotal - m->vsync_end;
1500 vm->vsync_len = m->vsync_end - m->vsync_start;
1501 vm->hfront_porch = m->hsync_start - m->hdisplay;
1502 vm->hback_porch = m->htotal - m->hsync_end;
1503 vm->hsync_len = m->hsync_end - m->hsync_start;
1504}
1505
1506static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = { 1487static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
1507 .mode_set = exynos_dsi_mode_set,
1508 .enable = exynos_dsi_enable, 1488 .enable = exynos_dsi_enable,
1509 .disable = exynos_dsi_disable, 1489 .disable = exynos_dsi_disable,
1510}; 1490};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index f0e79178bde6..7fcc1a7ab1a0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -161,7 +161,7 @@ static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = {
161static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { 161static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
162 .fb_create = exynos_user_fb_create, 162 .fb_create = exynos_user_fb_create,
163 .output_poll_changed = drm_fb_helper_output_poll_changed, 163 .output_poll_changed = drm_fb_helper_output_poll_changed,
164 .atomic_check = exynos_atomic_check, 164 .atomic_check = drm_atomic_helper_check,
165 .atomic_commit = drm_atomic_helper_commit, 165 .atomic_commit = drm_atomic_helper_commit,
166}; 166};
167 167
@@ -182,4 +182,6 @@ void exynos_drm_mode_config_init(struct drm_device *dev)
182 dev->mode_config.helper_private = &exynos_drm_mode_config_helpers; 182 dev->mode_config.helper_private = &exynos_drm_mode_config_helpers;
183 183
184 dev->mode_config.allow_fb_modifiers = true; 184 dev->mode_config.allow_fb_modifiers = true;
185
186 dev->mode_config.normalize_zpos = true;
185} 187}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index 5b18b5c5fdf2..5ce84025d1cb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -12,6 +12,7 @@
12 * 12 *
13 */ 13 */
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/component.h>
15#include <linux/platform_device.h> 16#include <linux/platform_device.h>
16#include <linux/mfd/syscon.h> 17#include <linux/mfd/syscon.h>
17#include <linux/regmap.h> 18#include <linux/regmap.h>
@@ -24,8 +25,8 @@
24#include <drm/exynos_drm.h> 25#include <drm/exynos_drm.h>
25#include "regs-fimc.h" 26#include "regs-fimc.h"
26#include "exynos_drm_drv.h" 27#include "exynos_drm_drv.h"
28#include "exynos_drm_iommu.h"
27#include "exynos_drm_ipp.h" 29#include "exynos_drm_ipp.h"
28#include "exynos_drm_fimc.h"
29 30
30/* 31/*
31 * FIMC stands for Fully Interactive Mobile Camera and 32 * FIMC stands for Fully Interactive Mobile Camera and
@@ -33,23 +34,6 @@
33 * input DMA reads image data from the memory. 34 * input DMA reads image data from the memory.
34 * output DMA writes image data to memory. 35 * output DMA writes image data to memory.
35 * FIMC supports image rotation and image effect functions. 36 * FIMC supports image rotation and image effect functions.
36 *
37 * M2M operation : supports crop/scale/rotation/csc so on.
38 * Memory ----> FIMC H/W ----> Memory.
39 * Writeback operation : supports cloned screen with FIMD.
40 * FIMD ----> FIMC H/W ----> Memory.
41 * Output operation : supports direct display using local path.
42 * Memory ----> FIMC H/W ----> FIMD.
43 */
44
45/*
46 * TODO
47 * 1. check suspend/resume api if needed.
48 * 2. need to check use case platform_device_id.
49 * 3. check src/dst size with, height.
50 * 4. added check_prepare api for right register.
51 * 5. need to add supported list in prop_list.
52 * 6. check prescaler/scaler optimization.
53 */ 37 */
54 38
55#define FIMC_MAX_DEVS 4 39#define FIMC_MAX_DEVS 4
@@ -59,29 +43,19 @@
59#define FIMC_BUF_STOP 1 43#define FIMC_BUF_STOP 1
60#define FIMC_BUF_START 2 44#define FIMC_BUF_START 2
61#define FIMC_WIDTH_ITU_709 1280 45#define FIMC_WIDTH_ITU_709 1280
62#define FIMC_REFRESH_MAX 60 46#define FIMC_AUTOSUSPEND_DELAY 2000
63#define FIMC_REFRESH_MIN 12 47
64#define FIMC_CROP_MAX 8192 48static unsigned int fimc_mask = 0xc;
65#define FIMC_CROP_MIN 32 49module_param_named(fimc_devs, fimc_mask, uint, 0644);
66#define FIMC_SCALE_MAX 4224 50MODULE_PARM_DESC(fimc_devs, "Alias mask for assigning FIMC devices to Exynos DRM");
67#define FIMC_SCALE_MIN 32
68 51
69#define get_fimc_context(dev) platform_get_drvdata(to_platform_device(dev)) 52#define get_fimc_context(dev) platform_get_drvdata(to_platform_device(dev))
70#define get_ctx_from_ippdrv(ippdrv) container_of(ippdrv,\
71 struct fimc_context, ippdrv);
72enum fimc_wb {
73 FIMC_WB_NONE,
74 FIMC_WB_A,
75 FIMC_WB_B,
76};
77 53
78enum { 54enum {
79 FIMC_CLK_LCLK, 55 FIMC_CLK_LCLK,
80 FIMC_CLK_GATE, 56 FIMC_CLK_GATE,
81 FIMC_CLK_WB_A, 57 FIMC_CLK_WB_A,
82 FIMC_CLK_WB_B, 58 FIMC_CLK_WB_B,
83 FIMC_CLK_MUX,
84 FIMC_CLK_PARENT,
85 FIMC_CLKS_MAX 59 FIMC_CLKS_MAX
86}; 60};
87 61
@@ -90,12 +64,8 @@ static const char * const fimc_clock_names[] = {
90 [FIMC_CLK_GATE] = "fimc", 64 [FIMC_CLK_GATE] = "fimc",
91 [FIMC_CLK_WB_A] = "pxl_async0", 65 [FIMC_CLK_WB_A] = "pxl_async0",
92 [FIMC_CLK_WB_B] = "pxl_async1", 66 [FIMC_CLK_WB_B] = "pxl_async1",
93 [FIMC_CLK_MUX] = "mux",
94 [FIMC_CLK_PARENT] = "parent",
95}; 67};
96 68
97#define FIMC_DEFAULT_LCLK_FREQUENCY 133000000UL
98
99/* 69/*
100 * A structure of scaler. 70 * A structure of scaler.
101 * 71 *
@@ -107,7 +77,7 @@ static const char * const fimc_clock_names[] = {
107 * @vratio: vertical ratio. 77 * @vratio: vertical ratio.
108 */ 78 */
109struct fimc_scaler { 79struct fimc_scaler {
110 bool range; 80 bool range;
111 bool bypass; 81 bool bypass;
112 bool up_h; 82 bool up_h;
113 bool up_v; 83 bool up_v;
@@ -116,56 +86,32 @@ struct fimc_scaler {
116}; 86};
117 87
118/* 88/*
119 * A structure of scaler capability.
120 *
121 * find user manual table 43-1.
122 * @in_hori: scaler input horizontal size.
123 * @bypass: scaler bypass mode.
124 * @dst_h_wo_rot: target horizontal size without output rotation.
125 * @dst_h_rot: target horizontal size with output rotation.
126 * @rl_w_wo_rot: real width without input rotation.
127 * @rl_h_rot: real height without output rotation.
128 */
129struct fimc_capability {
130 /* scaler */
131 u32 in_hori;
132 u32 bypass;
133 /* output rotator */
134 u32 dst_h_wo_rot;
135 u32 dst_h_rot;
136 /* input rotator */
137 u32 rl_w_wo_rot;
138 u32 rl_h_rot;
139};
140
141/*
142 * A structure of fimc context. 89 * A structure of fimc context.
143 * 90 *
144 * @ippdrv: prepare initialization using ippdrv.
145 * @regs_res: register resources. 91 * @regs_res: register resources.
146 * @regs: memory mapped io registers. 92 * @regs: memory mapped io registers.
147 * @lock: locking of operations. 93 * @lock: locking of operations.
148 * @clocks: fimc clocks. 94 * @clocks: fimc clocks.
149 * @clk_frequency: LCLK clock frequency.
150 * @sysreg: handle to SYSREG block regmap.
151 * @sc: scaler infomations. 95 * @sc: scaler infomations.
152 * @pol: porarity of writeback. 96 * @pol: porarity of writeback.
153 * @id: fimc id. 97 * @id: fimc id.
154 * @irq: irq number. 98 * @irq: irq number.
155 * @suspended: qos operations.
156 */ 99 */
157struct fimc_context { 100struct fimc_context {
158 struct exynos_drm_ippdrv ippdrv; 101 struct exynos_drm_ipp ipp;
102 struct drm_device *drm_dev;
103 struct device *dev;
104 struct exynos_drm_ipp_task *task;
105 struct exynos_drm_ipp_formats *formats;
106 unsigned int num_formats;
107
159 struct resource *regs_res; 108 struct resource *regs_res;
160 void __iomem *regs; 109 void __iomem *regs;
161 spinlock_t lock; 110 spinlock_t lock;
162 struct clk *clocks[FIMC_CLKS_MAX]; 111 struct clk *clocks[FIMC_CLKS_MAX];
163 u32 clk_frequency;
164 struct regmap *sysreg;
165 struct fimc_scaler sc; 112 struct fimc_scaler sc;
166 int id; 113 int id;
167 int irq; 114 int irq;
168 bool suspended;
169}; 115};
170 116
171static u32 fimc_read(struct fimc_context *ctx, u32 reg) 117static u32 fimc_read(struct fimc_context *ctx, u32 reg)
@@ -217,19 +163,10 @@ static void fimc_sw_reset(struct fimc_context *ctx)
217 fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ); 163 fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
218} 164}
219 165
220static int fimc_set_camblk_fimd0_wb(struct fimc_context *ctx) 166static void fimc_set_type_ctrl(struct fimc_context *ctx)
221{
222 return regmap_update_bits(ctx->sysreg, SYSREG_CAMERA_BLK,
223 SYSREG_FIMD0WB_DEST_MASK,
224 ctx->id << SYSREG_FIMD0WB_DEST_SHIFT);
225}
226
227static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb)
228{ 167{
229 u32 cfg; 168 u32 cfg;
230 169
231 DRM_DEBUG_KMS("wb[%d]\n", wb);
232
233 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 170 cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
234 cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK | 171 cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK |
235 EXYNOS_CIGCTRL_SELCAM_ITU_MASK | 172 EXYNOS_CIGCTRL_SELCAM_ITU_MASK |
@@ -238,23 +175,10 @@ static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb)
238 EXYNOS_CIGCTRL_SELWB_CAMIF_MASK | 175 EXYNOS_CIGCTRL_SELWB_CAMIF_MASK |
239 EXYNOS_CIGCTRL_SELWRITEBACK_MASK); 176 EXYNOS_CIGCTRL_SELWRITEBACK_MASK);
240 177
241 switch (wb) { 178 cfg |= (EXYNOS_CIGCTRL_SELCAM_ITU_A |
242 case FIMC_WB_A: 179 EXYNOS_CIGCTRL_SELWRITEBACK_A |
243 cfg |= (EXYNOS_CIGCTRL_SELWRITEBACK_A | 180 EXYNOS_CIGCTRL_SELCAM_MIPI_A |
244 EXYNOS_CIGCTRL_SELWB_CAMIF_WRITEBACK); 181 EXYNOS_CIGCTRL_SELCAM_FIMC_ITU);
245 break;
246 case FIMC_WB_B:
247 cfg |= (EXYNOS_CIGCTRL_SELWRITEBACK_B |
248 EXYNOS_CIGCTRL_SELWB_CAMIF_WRITEBACK);
249 break;
250 case FIMC_WB_NONE:
251 default:
252 cfg |= (EXYNOS_CIGCTRL_SELCAM_ITU_A |
253 EXYNOS_CIGCTRL_SELWRITEBACK_A |
254 EXYNOS_CIGCTRL_SELCAM_MIPI_A |
255 EXYNOS_CIGCTRL_SELCAM_FIMC_ITU);
256 break;
257 }
258 182
259 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 183 fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
260} 184}
@@ -296,7 +220,6 @@ static void fimc_clear_irq(struct fimc_context *ctx)
296 220
297static bool fimc_check_ovf(struct fimc_context *ctx) 221static bool fimc_check_ovf(struct fimc_context *ctx)
298{ 222{
299 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
300 u32 status, flag; 223 u32 status, flag;
301 224
302 status = fimc_read(ctx, EXYNOS_CISTATUS); 225 status = fimc_read(ctx, EXYNOS_CISTATUS);
@@ -310,7 +233,7 @@ static bool fimc_check_ovf(struct fimc_context *ctx)
310 EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB | 233 EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
311 EXYNOS_CIWDOFST_CLROVFICR); 234 EXYNOS_CIWDOFST_CLROVFICR);
312 235
313 dev_err(ippdrv->dev, "occurred overflow at %d, status 0x%x.\n", 236 dev_err(ctx->dev, "occurred overflow at %d, status 0x%x.\n",
314 ctx->id, status); 237 ctx->id, status);
315 return true; 238 return true;
316 } 239 }
@@ -376,10 +299,8 @@ static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
376 fimc_write(ctx, cfg, EXYNOS_CIOCTRL); 299 fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
377} 300}
378 301
379 302static void fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
380static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
381{ 303{
382 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
383 u32 cfg; 304 u32 cfg;
384 305
385 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 306 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
@@ -392,12 +313,12 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
392 case DRM_FORMAT_RGB565: 313 case DRM_FORMAT_RGB565:
393 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB565; 314 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB565;
394 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 315 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
395 return 0; 316 return;
396 case DRM_FORMAT_RGB888: 317 case DRM_FORMAT_RGB888:
397 case DRM_FORMAT_XRGB8888: 318 case DRM_FORMAT_XRGB8888:
398 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888; 319 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888;
399 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 320 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
400 return 0; 321 return;
401 default: 322 default:
402 /* bypass */ 323 /* bypass */
403 break; 324 break;
@@ -438,20 +359,13 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
438 cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CBCR | 359 cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CBCR |
439 EXYNOS_MSCTRL_C_INT_IN_2PLANE); 360 EXYNOS_MSCTRL_C_INT_IN_2PLANE);
440 break; 361 break;
441 default:
442 dev_err(ippdrv->dev, "invalid source yuv order 0x%x.\n", fmt);
443 return -EINVAL;
444 } 362 }
445 363
446 fimc_write(ctx, cfg, EXYNOS_MSCTRL); 364 fimc_write(ctx, cfg, EXYNOS_MSCTRL);
447
448 return 0;
449} 365}
450 366
451static int fimc_src_set_fmt(struct device *dev, u32 fmt) 367static void fimc_src_set_fmt(struct fimc_context *ctx, u32 fmt, bool tiled)
452{ 368{
453 struct fimc_context *ctx = get_fimc_context(dev);
454 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
455 u32 cfg; 369 u32 cfg;
456 370
457 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 371 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
@@ -485,9 +399,6 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
485 case DRM_FORMAT_NV21: 399 case DRM_FORMAT_NV21:
486 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420; 400 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420;
487 break; 401 break;
488 default:
489 dev_err(ippdrv->dev, "invalid source format 0x%x.\n", fmt);
490 return -EINVAL;
491 } 402 }
492 403
493 fimc_write(ctx, cfg, EXYNOS_MSCTRL); 404 fimc_write(ctx, cfg, EXYNOS_MSCTRL);
@@ -495,22 +406,22 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
495 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM); 406 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
496 cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK; 407 cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK;
497 408
498 cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR; 409 if (tiled)
410 cfg |= EXYNOS_CIDMAPARAM_R_MODE_64X32;
411 else
412 cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR;
499 413
500 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM); 414 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
501 415
502 return fimc_src_set_fmt_order(ctx, fmt); 416 fimc_src_set_fmt_order(ctx, fmt);
503} 417}
504 418
505static int fimc_src_set_transf(struct device *dev, 419static void fimc_src_set_transf(struct fimc_context *ctx, unsigned int rotation)
506 enum drm_exynos_degree degree,
507 enum drm_exynos_flip flip, bool *swap)
508{ 420{
509 struct fimc_context *ctx = get_fimc_context(dev); 421 unsigned int degree = rotation & DRM_MODE_ROTATE_MASK;
510 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
511 u32 cfg1, cfg2; 422 u32 cfg1, cfg2;
512 423
513 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip); 424 DRM_DEBUG_KMS("rotation[%x]\n", rotation);
514 425
515 cfg1 = fimc_read(ctx, EXYNOS_MSCTRL); 426 cfg1 = fimc_read(ctx, EXYNOS_MSCTRL);
516 cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR | 427 cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR |
@@ -520,61 +431,56 @@ static int fimc_src_set_transf(struct device *dev,
520 cfg2 &= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 431 cfg2 &= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
521 432
522 switch (degree) { 433 switch (degree) {
523 case EXYNOS_DRM_DEGREE_0: 434 case DRM_MODE_ROTATE_0:
524 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 435 if (rotation & DRM_MODE_REFLECT_X)
525 cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR; 436 cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR;
526 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 437 if (rotation & DRM_MODE_REFLECT_Y)
527 cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR; 438 cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR;
528 break; 439 break;
529 case EXYNOS_DRM_DEGREE_90: 440 case DRM_MODE_ROTATE_90:
530 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 441 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
531 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 442 if (rotation & DRM_MODE_REFLECT_X)
532 cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR; 443 cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR;
533 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 444 if (rotation & DRM_MODE_REFLECT_Y)
534 cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR; 445 cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR;
535 break; 446 break;
536 case EXYNOS_DRM_DEGREE_180: 447 case DRM_MODE_ROTATE_180:
537 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR | 448 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR |
538 EXYNOS_MSCTRL_FLIP_Y_MIRROR); 449 EXYNOS_MSCTRL_FLIP_Y_MIRROR);
539 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 450 if (rotation & DRM_MODE_REFLECT_X)
540 cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR; 451 cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR;
541 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 452 if (rotation & DRM_MODE_REFLECT_Y)
542 cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR; 453 cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR;
543 break; 454 break;
544 case EXYNOS_DRM_DEGREE_270: 455 case DRM_MODE_ROTATE_270:
545 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR | 456 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR |
546 EXYNOS_MSCTRL_FLIP_Y_MIRROR); 457 EXYNOS_MSCTRL_FLIP_Y_MIRROR);
547 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 458 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
548 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 459 if (rotation & DRM_MODE_REFLECT_X)
549 cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR; 460 cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR;
550 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 461 if (rotation & DRM_MODE_REFLECT_Y)
551 cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR; 462 cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR;
552 break; 463 break;
553 default:
554 dev_err(ippdrv->dev, "invalid degree value %d.\n", degree);
555 return -EINVAL;
556 } 464 }
557 465
558 fimc_write(ctx, cfg1, EXYNOS_MSCTRL); 466 fimc_write(ctx, cfg1, EXYNOS_MSCTRL);
559 fimc_write(ctx, cfg2, EXYNOS_CITRGFMT); 467 fimc_write(ctx, cfg2, EXYNOS_CITRGFMT);
560 *swap = (cfg2 & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) ? 1 : 0;
561
562 return 0;
563} 468}
564 469
565static int fimc_set_window(struct fimc_context *ctx, 470static void fimc_set_window(struct fimc_context *ctx,
566 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz) 471 struct exynos_drm_ipp_buffer *buf)
567{ 472{
568 u32 cfg, h1, h2, v1, v2; 473 u32 cfg, h1, h2, v1, v2;
569 474
570 /* cropped image */ 475 /* cropped image */
571 h1 = pos->x; 476 h1 = buf->rect.x;
572 h2 = sz->hsize - pos->w - pos->x; 477 h2 = buf->buf.width - buf->rect.w - buf->rect.x;
573 v1 = pos->y; 478 v1 = buf->rect.y;
574 v2 = sz->vsize - pos->h - pos->y; 479 v2 = buf->buf.height - buf->rect.h - buf->rect.y;
575 480
576 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n", 481 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n",
577 pos->x, pos->y, pos->w, pos->h, sz->hsize, sz->vsize); 482 buf->rect.x, buf->rect.y, buf->rect.w, buf->rect.h,
483 buf->buf.width, buf->buf.height);
578 DRM_DEBUG_KMS("h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, v2); 484 DRM_DEBUG_KMS("h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, v2);
579 485
580 /* 486 /*
@@ -592,42 +498,30 @@ static int fimc_set_window(struct fimc_context *ctx,
592 cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) | 498 cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) |
593 EXYNOS_CIWDOFST2_WINVEROFST2(v2)); 499 EXYNOS_CIWDOFST2_WINVEROFST2(v2));
594 fimc_write(ctx, cfg, EXYNOS_CIWDOFST2); 500 fimc_write(ctx, cfg, EXYNOS_CIWDOFST2);
595
596 return 0;
597} 501}
598 502
599static int fimc_src_set_size(struct device *dev, int swap, 503static void fimc_src_set_size(struct fimc_context *ctx,
600 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz) 504 struct exynos_drm_ipp_buffer *buf)
601{ 505{
602 struct fimc_context *ctx = get_fimc_context(dev);
603 struct drm_exynos_pos img_pos = *pos;
604 struct drm_exynos_sz img_sz = *sz;
605 u32 cfg; 506 u32 cfg;
606 507
607 DRM_DEBUG_KMS("swap[%d]hsize[%d]vsize[%d]\n", 508 DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", buf->buf.width, buf->buf.height);
608 swap, sz->hsize, sz->vsize);
609 509
610 /* original size */ 510 /* original size */
611 cfg = (EXYNOS_ORGISIZE_HORIZONTAL(img_sz.hsize) | 511 cfg = (EXYNOS_ORGISIZE_HORIZONTAL(buf->buf.width) |
612 EXYNOS_ORGISIZE_VERTICAL(img_sz.vsize)); 512 EXYNOS_ORGISIZE_VERTICAL(buf->buf.height));
613 513
614 fimc_write(ctx, cfg, EXYNOS_ORGISIZE); 514 fimc_write(ctx, cfg, EXYNOS_ORGISIZE);
615 515
616 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h); 516 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, buf->rect.y,
617 517 buf->rect.w, buf->rect.h);
618 if (swap) {
619 img_pos.w = pos->h;
620 img_pos.h = pos->w;
621 img_sz.hsize = sz->vsize;
622 img_sz.vsize = sz->hsize;
623 }
624 518
625 /* set input DMA image size */ 519 /* set input DMA image size */
626 cfg = fimc_read(ctx, EXYNOS_CIREAL_ISIZE); 520 cfg = fimc_read(ctx, EXYNOS_CIREAL_ISIZE);
627 cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK | 521 cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK |
628 EXYNOS_CIREAL_ISIZE_WIDTH_MASK); 522 EXYNOS_CIREAL_ISIZE_WIDTH_MASK);
629 cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(img_pos.w) | 523 cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(buf->rect.w) |
630 EXYNOS_CIREAL_ISIZE_HEIGHT(img_pos.h)); 524 EXYNOS_CIREAL_ISIZE_HEIGHT(buf->rect.h));
631 fimc_write(ctx, cfg, EXYNOS_CIREAL_ISIZE); 525 fimc_write(ctx, cfg, EXYNOS_CIREAL_ISIZE);
632 526
633 /* 527 /*
@@ -635,91 +529,34 @@ static int fimc_src_set_size(struct device *dev, int swap,
635 * for now, we support only ITU601 8 bit mode 529 * for now, we support only ITU601 8 bit mode
636 */ 530 */
637 cfg = (EXYNOS_CISRCFMT_ITU601_8BIT | 531 cfg = (EXYNOS_CISRCFMT_ITU601_8BIT |
638 EXYNOS_CISRCFMT_SOURCEHSIZE(img_sz.hsize) | 532 EXYNOS_CISRCFMT_SOURCEHSIZE(buf->buf.width) |
639 EXYNOS_CISRCFMT_SOURCEVSIZE(img_sz.vsize)); 533 EXYNOS_CISRCFMT_SOURCEVSIZE(buf->buf.height));
640 fimc_write(ctx, cfg, EXYNOS_CISRCFMT); 534 fimc_write(ctx, cfg, EXYNOS_CISRCFMT);
641 535
642 /* offset Y(RGB), Cb, Cr */ 536 /* offset Y(RGB), Cb, Cr */
643 cfg = (EXYNOS_CIIYOFF_HORIZONTAL(img_pos.x) | 537 cfg = (EXYNOS_CIIYOFF_HORIZONTAL(buf->rect.x) |
644 EXYNOS_CIIYOFF_VERTICAL(img_pos.y)); 538 EXYNOS_CIIYOFF_VERTICAL(buf->rect.y));
645 fimc_write(ctx, cfg, EXYNOS_CIIYOFF); 539 fimc_write(ctx, cfg, EXYNOS_CIIYOFF);
646 cfg = (EXYNOS_CIICBOFF_HORIZONTAL(img_pos.x) | 540 cfg = (EXYNOS_CIICBOFF_HORIZONTAL(buf->rect.x) |
647 EXYNOS_CIICBOFF_VERTICAL(img_pos.y)); 541 EXYNOS_CIICBOFF_VERTICAL(buf->rect.y));
648 fimc_write(ctx, cfg, EXYNOS_CIICBOFF); 542 fimc_write(ctx, cfg, EXYNOS_CIICBOFF);
649 cfg = (EXYNOS_CIICROFF_HORIZONTAL(img_pos.x) | 543 cfg = (EXYNOS_CIICROFF_HORIZONTAL(buf->rect.x) |
650 EXYNOS_CIICROFF_VERTICAL(img_pos.y)); 544 EXYNOS_CIICROFF_VERTICAL(buf->rect.y));
651 fimc_write(ctx, cfg, EXYNOS_CIICROFF); 545 fimc_write(ctx, cfg, EXYNOS_CIICROFF);
652 546
653 return fimc_set_window(ctx, &img_pos, &img_sz); 547 fimc_set_window(ctx, buf);
654} 548}
655 549
656static int fimc_src_set_addr(struct device *dev, 550static void fimc_src_set_addr(struct fimc_context *ctx,
657 struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id, 551 struct exynos_drm_ipp_buffer *buf)
658 enum drm_exynos_ipp_buf_type buf_type)
659{ 552{
660 struct fimc_context *ctx = get_fimc_context(dev); 553 fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIIYSA(0));
661 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 554 fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIICBSA(0));
662 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; 555 fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIICRSA(0));
663 struct drm_exynos_ipp_property *property;
664 struct drm_exynos_ipp_config *config;
665
666 if (!c_node) {
667 DRM_ERROR("failed to get c_node.\n");
668 return -EINVAL;
669 }
670
671 property = &c_node->property;
672
673 DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
674 property->prop_id, buf_id, buf_type);
675
676 if (buf_id > FIMC_MAX_SRC) {
677 dev_info(ippdrv->dev, "invalid buf_id %d.\n", buf_id);
678 return -ENOMEM;
679 }
680
681 /* address register set */
682 switch (buf_type) {
683 case IPP_BUF_ENQUEUE:
684 config = &property->config[EXYNOS_DRM_OPS_SRC];
685 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
686 EXYNOS_CIIYSA0);
687
688 if (config->fmt == DRM_FORMAT_YVU420) {
689 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
690 EXYNOS_CIICBSA0);
691 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
692 EXYNOS_CIICRSA0);
693 } else {
694 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
695 EXYNOS_CIICBSA0);
696 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
697 EXYNOS_CIICRSA0);
698 }
699 break;
700 case IPP_BUF_DEQUEUE:
701 fimc_write(ctx, 0x0, EXYNOS_CIIYSA0);
702 fimc_write(ctx, 0x0, EXYNOS_CIICBSA0);
703 fimc_write(ctx, 0x0, EXYNOS_CIICRSA0);
704 break;
705 default:
706 /* bypass */
707 break;
708 }
709
710 return 0;
711} 556}
712 557
713static struct exynos_drm_ipp_ops fimc_src_ops = { 558static void fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
714 .set_fmt = fimc_src_set_fmt,
715 .set_transf = fimc_src_set_transf,
716 .set_size = fimc_src_set_size,
717 .set_addr = fimc_src_set_addr,
718};
719
720static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
721{ 559{
722 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
723 u32 cfg; 560 u32 cfg;
724 561
725 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 562 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
@@ -732,11 +569,11 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
732 case DRM_FORMAT_RGB565: 569 case DRM_FORMAT_RGB565:
733 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565; 570 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565;
734 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 571 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
735 return 0; 572 return;
736 case DRM_FORMAT_RGB888: 573 case DRM_FORMAT_RGB888:
737 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888; 574 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888;
738 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 575 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
739 return 0; 576 return;
740 case DRM_FORMAT_XRGB8888: 577 case DRM_FORMAT_XRGB8888:
741 cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 | 578 cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 |
742 EXYNOS_CISCCTRL_EXTRGB_EXTENSION); 579 EXYNOS_CISCCTRL_EXTRGB_EXTENSION);
@@ -784,20 +621,13 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
784 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR; 621 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR;
785 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE; 622 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE;
786 break; 623 break;
787 default:
788 dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt);
789 return -EINVAL;
790 } 624 }
791 625
792 fimc_write(ctx, cfg, EXYNOS_CIOCTRL); 626 fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
793
794 return 0;
795} 627}
796 628
797static int fimc_dst_set_fmt(struct device *dev, u32 fmt) 629static void fimc_dst_set_fmt(struct fimc_context *ctx, u32 fmt, bool tiled)
798{ 630{
799 struct fimc_context *ctx = get_fimc_context(dev);
800 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
801 u32 cfg; 631 u32 cfg;
802 632
803 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 633 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
@@ -837,10 +667,6 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
837 case DRM_FORMAT_NV21: 667 case DRM_FORMAT_NV21:
838 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420; 668 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420;
839 break; 669 break;
840 default:
841 dev_err(ippdrv->dev, "invalid target format 0x%x.\n",
842 fmt);
843 return -EINVAL;
844 } 670 }
845 671
846 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 672 fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
@@ -849,73 +675,67 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
849 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM); 675 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
850 cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK; 676 cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK;
851 677
852 cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR; 678 if (tiled)
679 cfg |= EXYNOS_CIDMAPARAM_W_MODE_64X32;
680 else
681 cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR;
853 682
854 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM); 683 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
855 684
856 return fimc_dst_set_fmt_order(ctx, fmt); 685 fimc_dst_set_fmt_order(ctx, fmt);
857} 686}
858 687
859static int fimc_dst_set_transf(struct device *dev, 688static void fimc_dst_set_transf(struct fimc_context *ctx, unsigned int rotation)
860 enum drm_exynos_degree degree,
861 enum drm_exynos_flip flip, bool *swap)
862{ 689{
863 struct fimc_context *ctx = get_fimc_context(dev); 690 unsigned int degree = rotation & DRM_MODE_ROTATE_MASK;
864 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
865 u32 cfg; 691 u32 cfg;
866 692
867 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip); 693 DRM_DEBUG_KMS("rotation[0x%x]\n", rotation);
868 694
869 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 695 cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
870 cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK; 696 cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK;
871 cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE; 697 cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE;
872 698
873 switch (degree) { 699 switch (degree) {
874 case EXYNOS_DRM_DEGREE_0: 700 case DRM_MODE_ROTATE_0:
875 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 701 if (rotation & DRM_MODE_REFLECT_X)
876 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR; 702 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR;
877 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 703 if (rotation & DRM_MODE_REFLECT_Y)
878 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 704 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
879 break; 705 break;
880 case EXYNOS_DRM_DEGREE_90: 706 case DRM_MODE_ROTATE_90:
881 cfg |= EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE; 707 cfg |= EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE;
882 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 708 if (rotation & DRM_MODE_REFLECT_X)
883 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR; 709 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR;
884 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 710 if (rotation & DRM_MODE_REFLECT_Y)
885 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 711 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
886 break; 712 break;
887 case EXYNOS_DRM_DEGREE_180: 713 case DRM_MODE_ROTATE_180:
888 cfg |= (EXYNOS_CITRGFMT_FLIP_X_MIRROR | 714 cfg |= (EXYNOS_CITRGFMT_FLIP_X_MIRROR |
889 EXYNOS_CITRGFMT_FLIP_Y_MIRROR); 715 EXYNOS_CITRGFMT_FLIP_Y_MIRROR);
890 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 716 if (rotation & DRM_MODE_REFLECT_X)
891 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR; 717 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR;
892 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 718 if (rotation & DRM_MODE_REFLECT_Y)
893 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 719 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
894 break; 720 break;
895 case EXYNOS_DRM_DEGREE_270: 721 case DRM_MODE_ROTATE_270:
896 cfg |= (EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE | 722 cfg |= (EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE |
897 EXYNOS_CITRGFMT_FLIP_X_MIRROR | 723 EXYNOS_CITRGFMT_FLIP_X_MIRROR |
898 EXYNOS_CITRGFMT_FLIP_Y_MIRROR); 724 EXYNOS_CITRGFMT_FLIP_Y_MIRROR);
899 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 725 if (rotation & DRM_MODE_REFLECT_X)
900 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR; 726 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR;
901 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 727 if (rotation & DRM_MODE_REFLECT_Y)
902 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 728 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
903 break; 729 break;
904 default:
905 dev_err(ippdrv->dev, "invalid degree value %d.\n", degree);
906 return -EINVAL;
907 } 730 }
908 731
909 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 732 fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
910 *swap = (cfg & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) ? 1 : 0;
911
912 return 0;
913} 733}
914 734
915static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc, 735static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
916 struct drm_exynos_pos *src, struct drm_exynos_pos *dst) 736 struct drm_exynos_ipp_task_rect *src,
737 struct drm_exynos_ipp_task_rect *dst)
917{ 738{
918 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
919 u32 cfg, cfg_ext, shfactor; 739 u32 cfg, cfg_ext, shfactor;
920 u32 pre_dst_width, pre_dst_height; 740 u32 pre_dst_width, pre_dst_height;
921 u32 hfactor, vfactor; 741 u32 hfactor, vfactor;
@@ -942,13 +762,13 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
942 /* fimc_ippdrv_check_property assures that dividers are not null */ 762 /* fimc_ippdrv_check_property assures that dividers are not null */
943 hfactor = fls(src_w / dst_w / 2); 763 hfactor = fls(src_w / dst_w / 2);
944 if (hfactor > FIMC_SHFACTOR / 2) { 764 if (hfactor > FIMC_SHFACTOR / 2) {
945 dev_err(ippdrv->dev, "failed to get ratio horizontal.\n"); 765 dev_err(ctx->dev, "failed to get ratio horizontal.\n");
946 return -EINVAL; 766 return -EINVAL;
947 } 767 }
948 768
949 vfactor = fls(src_h / dst_h / 2); 769 vfactor = fls(src_h / dst_h / 2);
950 if (vfactor > FIMC_SHFACTOR / 2) { 770 if (vfactor > FIMC_SHFACTOR / 2) {
951 dev_err(ippdrv->dev, "failed to get ratio vertical.\n"); 771 dev_err(ctx->dev, "failed to get ratio vertical.\n");
952 return -EINVAL; 772 return -EINVAL;
953 } 773 }
954 774
@@ -1019,83 +839,77 @@ static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc)
1019 fimc_write(ctx, cfg_ext, EXYNOS_CIEXTEN); 839 fimc_write(ctx, cfg_ext, EXYNOS_CIEXTEN);
1020} 840}
1021 841
1022static int fimc_dst_set_size(struct device *dev, int swap, 842static void fimc_dst_set_size(struct fimc_context *ctx,
1023 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz) 843 struct exynos_drm_ipp_buffer *buf)
1024{ 844{
1025 struct fimc_context *ctx = get_fimc_context(dev); 845 u32 cfg, cfg_ext;
1026 struct drm_exynos_pos img_pos = *pos;
1027 struct drm_exynos_sz img_sz = *sz;
1028 u32 cfg;
1029 846
1030 DRM_DEBUG_KMS("swap[%d]hsize[%d]vsize[%d]\n", 847 DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", buf->buf.width, buf->buf.height);
1031 swap, sz->hsize, sz->vsize);
1032 848
1033 /* original size */ 849 /* original size */
1034 cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(img_sz.hsize) | 850 cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(buf->buf.width) |
1035 EXYNOS_ORGOSIZE_VERTICAL(img_sz.vsize)); 851 EXYNOS_ORGOSIZE_VERTICAL(buf->buf.height));
1036 852
1037 fimc_write(ctx, cfg, EXYNOS_ORGOSIZE); 853 fimc_write(ctx, cfg, EXYNOS_ORGOSIZE);
1038 854
1039 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h); 855 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, buf->rect.y,
856 buf->rect.w, buf->rect.h);
1040 857
1041 /* CSC ITU */ 858 /* CSC ITU */
1042 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 859 cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
1043 cfg &= ~EXYNOS_CIGCTRL_CSC_MASK; 860 cfg &= ~EXYNOS_CIGCTRL_CSC_MASK;
1044 861
1045 if (sz->hsize >= FIMC_WIDTH_ITU_709) 862 if (buf->buf.width >= FIMC_WIDTH_ITU_709)
1046 cfg |= EXYNOS_CIGCTRL_CSC_ITU709; 863 cfg |= EXYNOS_CIGCTRL_CSC_ITU709;
1047 else 864 else
1048 cfg |= EXYNOS_CIGCTRL_CSC_ITU601; 865 cfg |= EXYNOS_CIGCTRL_CSC_ITU601;
1049 866
1050 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 867 fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
1051 868
1052 if (swap) { 869 cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT);
1053 img_pos.w = pos->h;
1054 img_pos.h = pos->w;
1055 img_sz.hsize = sz->vsize;
1056 img_sz.vsize = sz->hsize;
1057 }
1058 870
1059 /* target image size */ 871 /* target image size */
1060 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 872 cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
1061 cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK | 873 cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK |
1062 EXYNOS_CITRGFMT_TARGETV_MASK); 874 EXYNOS_CITRGFMT_TARGETV_MASK);
1063 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(img_pos.w) | 875 if (cfg_ext & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE)
1064 EXYNOS_CITRGFMT_TARGETVSIZE(img_pos.h)); 876 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.h) |
877 EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.w));
878 else
879 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.w) |
880 EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.h));
1065 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 881 fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
1066 882
1067 /* target area */ 883 /* target area */
1068 cfg = EXYNOS_CITAREA_TARGET_AREA(img_pos.w * img_pos.h); 884 cfg = EXYNOS_CITAREA_TARGET_AREA(buf->rect.w * buf->rect.h);
1069 fimc_write(ctx, cfg, EXYNOS_CITAREA); 885 fimc_write(ctx, cfg, EXYNOS_CITAREA);
1070 886
1071 /* offset Y(RGB), Cb, Cr */ 887 /* offset Y(RGB), Cb, Cr */
1072 cfg = (EXYNOS_CIOYOFF_HORIZONTAL(img_pos.x) | 888 cfg = (EXYNOS_CIOYOFF_HORIZONTAL(buf->rect.x) |
1073 EXYNOS_CIOYOFF_VERTICAL(img_pos.y)); 889 EXYNOS_CIOYOFF_VERTICAL(buf->rect.y));
1074 fimc_write(ctx, cfg, EXYNOS_CIOYOFF); 890 fimc_write(ctx, cfg, EXYNOS_CIOYOFF);
1075 cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(img_pos.x) | 891 cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(buf->rect.x) |
1076 EXYNOS_CIOCBOFF_VERTICAL(img_pos.y)); 892 EXYNOS_CIOCBOFF_VERTICAL(buf->rect.y));
1077 fimc_write(ctx, cfg, EXYNOS_CIOCBOFF); 893 fimc_write(ctx, cfg, EXYNOS_CIOCBOFF);
1078 cfg = (EXYNOS_CIOCROFF_HORIZONTAL(img_pos.x) | 894 cfg = (EXYNOS_CIOCROFF_HORIZONTAL(buf->rect.x) |
1079 EXYNOS_CIOCROFF_VERTICAL(img_pos.y)); 895 EXYNOS_CIOCROFF_VERTICAL(buf->rect.y));
1080 fimc_write(ctx, cfg, EXYNOS_CIOCROFF); 896 fimc_write(ctx, cfg, EXYNOS_CIOCROFF);
1081
1082 return 0;
1083} 897}
1084 898
1085static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id, 899static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
1086 enum drm_exynos_ipp_buf_type buf_type) 900 bool enqueue)
1087{ 901{
1088 unsigned long flags; 902 unsigned long flags;
1089 u32 buf_num; 903 u32 buf_num;
1090 u32 cfg; 904 u32 cfg;
1091 905
1092 DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type); 906 DRM_DEBUG_KMS("buf_id[%d]enqueu[%d]\n", buf_id, enqueue);
1093 907
1094 spin_lock_irqsave(&ctx->lock, flags); 908 spin_lock_irqsave(&ctx->lock, flags);
1095 909
1096 cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ); 910 cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ);
1097 911
1098 if (buf_type == IPP_BUF_ENQUEUE) 912 if (enqueue)
1099 cfg |= (1 << buf_id); 913 cfg |= (1 << buf_id);
1100 else 914 else
1101 cfg &= ~(1 << buf_id); 915 cfg &= ~(1 << buf_id);
@@ -1104,88 +918,29 @@ static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
1104 918
1105 buf_num = hweight32(cfg); 919 buf_num = hweight32(cfg);
1106 920
1107 if (buf_type == IPP_BUF_ENQUEUE && buf_num >= FIMC_BUF_START) 921 if (enqueue && buf_num >= FIMC_BUF_START)
1108 fimc_mask_irq(ctx, true); 922 fimc_mask_irq(ctx, true);
1109 else if (buf_type == IPP_BUF_DEQUEUE && buf_num <= FIMC_BUF_STOP) 923 else if (!enqueue && buf_num <= FIMC_BUF_STOP)
1110 fimc_mask_irq(ctx, false); 924 fimc_mask_irq(ctx, false);
1111 925
1112 spin_unlock_irqrestore(&ctx->lock, flags); 926 spin_unlock_irqrestore(&ctx->lock, flags);
1113} 927}
1114 928
1115static int fimc_dst_set_addr(struct device *dev, 929static void fimc_dst_set_addr(struct fimc_context *ctx,
1116 struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id, 930 struct exynos_drm_ipp_buffer *buf)
1117 enum drm_exynos_ipp_buf_type buf_type)
1118{ 931{
1119 struct fimc_context *ctx = get_fimc_context(dev); 932 fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIOYSA(0));
1120 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 933 fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIOCBSA(0));
1121 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; 934 fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIOCRSA(0));
1122 struct drm_exynos_ipp_property *property;
1123 struct drm_exynos_ipp_config *config;
1124
1125 if (!c_node) {
1126 DRM_ERROR("failed to get c_node.\n");
1127 return -EINVAL;
1128 }
1129
1130 property = &c_node->property;
1131
1132 DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
1133 property->prop_id, buf_id, buf_type);
1134 935
1135 if (buf_id > FIMC_MAX_DST) { 936 fimc_dst_set_buf_seq(ctx, 0, true);
1136 dev_info(ippdrv->dev, "invalid buf_id %d.\n", buf_id);
1137 return -ENOMEM;
1138 }
1139
1140 /* address register set */
1141 switch (buf_type) {
1142 case IPP_BUF_ENQUEUE:
1143 config = &property->config[EXYNOS_DRM_OPS_DST];
1144
1145 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
1146 EXYNOS_CIOYSA(buf_id));
1147
1148 if (config->fmt == DRM_FORMAT_YVU420) {
1149 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
1150 EXYNOS_CIOCBSA(buf_id));
1151 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
1152 EXYNOS_CIOCRSA(buf_id));
1153 } else {
1154 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
1155 EXYNOS_CIOCBSA(buf_id));
1156 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
1157 EXYNOS_CIOCRSA(buf_id));
1158 }
1159 break;
1160 case IPP_BUF_DEQUEUE:
1161 fimc_write(ctx, 0x0, EXYNOS_CIOYSA(buf_id));
1162 fimc_write(ctx, 0x0, EXYNOS_CIOCBSA(buf_id));
1163 fimc_write(ctx, 0x0, EXYNOS_CIOCRSA(buf_id));
1164 break;
1165 default:
1166 /* bypass */
1167 break;
1168 }
1169
1170 fimc_dst_set_buf_seq(ctx, buf_id, buf_type);
1171
1172 return 0;
1173} 937}
1174 938
1175static struct exynos_drm_ipp_ops fimc_dst_ops = { 939static void fimc_stop(struct fimc_context *ctx);
1176 .set_fmt = fimc_dst_set_fmt,
1177 .set_transf = fimc_dst_set_transf,
1178 .set_size = fimc_dst_set_size,
1179 .set_addr = fimc_dst_set_addr,
1180};
1181 940
1182static irqreturn_t fimc_irq_handler(int irq, void *dev_id) 941static irqreturn_t fimc_irq_handler(int irq, void *dev_id)
1183{ 942{
1184 struct fimc_context *ctx = dev_id; 943 struct fimc_context *ctx = dev_id;
1185 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1186 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
1187 struct drm_exynos_ipp_event_work *event_work =
1188 c_node->event_work;
1189 int buf_id; 944 int buf_id;
1190 945
1191 DRM_DEBUG_KMS("fimc id[%d]\n", ctx->id); 946 DRM_DEBUG_KMS("fimc id[%d]\n", ctx->id);
@@ -1203,170 +958,19 @@ static irqreturn_t fimc_irq_handler(int irq, void *dev_id)
1203 958
1204 DRM_DEBUG_KMS("buf_id[%d]\n", buf_id); 959 DRM_DEBUG_KMS("buf_id[%d]\n", buf_id);
1205 960
1206 fimc_dst_set_buf_seq(ctx, buf_id, IPP_BUF_DEQUEUE); 961 if (ctx->task) {
1207 962 struct exynos_drm_ipp_task *task = ctx->task;
1208 event_work->ippdrv = ippdrv;
1209 event_work->buf_id[EXYNOS_DRM_OPS_DST] = buf_id;
1210 queue_work(ippdrv->event_workq, &event_work->work);
1211
1212 return IRQ_HANDLED;
1213}
1214
1215static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
1216{
1217 struct drm_exynos_ipp_prop_list *prop_list = &ippdrv->prop_list;
1218
1219 prop_list->version = 1;
1220 prop_list->writeback = 1;
1221 prop_list->refresh_min = FIMC_REFRESH_MIN;
1222 prop_list->refresh_max = FIMC_REFRESH_MAX;
1223 prop_list->flip = (1 << EXYNOS_DRM_FLIP_NONE) |
1224 (1 << EXYNOS_DRM_FLIP_VERTICAL) |
1225 (1 << EXYNOS_DRM_FLIP_HORIZONTAL);
1226 prop_list->degree = (1 << EXYNOS_DRM_DEGREE_0) |
1227 (1 << EXYNOS_DRM_DEGREE_90) |
1228 (1 << EXYNOS_DRM_DEGREE_180) |
1229 (1 << EXYNOS_DRM_DEGREE_270);
1230 prop_list->csc = 1;
1231 prop_list->crop = 1;
1232 prop_list->crop_max.hsize = FIMC_CROP_MAX;
1233 prop_list->crop_max.vsize = FIMC_CROP_MAX;
1234 prop_list->crop_min.hsize = FIMC_CROP_MIN;
1235 prop_list->crop_min.vsize = FIMC_CROP_MIN;
1236 prop_list->scale = 1;
1237 prop_list->scale_max.hsize = FIMC_SCALE_MAX;
1238 prop_list->scale_max.vsize = FIMC_SCALE_MAX;
1239 prop_list->scale_min.hsize = FIMC_SCALE_MIN;
1240 prop_list->scale_min.vsize = FIMC_SCALE_MIN;
1241
1242 return 0;
1243}
1244
1245static inline bool fimc_check_drm_flip(enum drm_exynos_flip flip)
1246{
1247 switch (flip) {
1248 case EXYNOS_DRM_FLIP_NONE:
1249 case EXYNOS_DRM_FLIP_VERTICAL:
1250 case EXYNOS_DRM_FLIP_HORIZONTAL:
1251 case EXYNOS_DRM_FLIP_BOTH:
1252 return true;
1253 default:
1254 DRM_DEBUG_KMS("invalid flip\n");
1255 return false;
1256 }
1257}
1258
1259static int fimc_ippdrv_check_property(struct device *dev,
1260 struct drm_exynos_ipp_property *property)
1261{
1262 struct fimc_context *ctx = get_fimc_context(dev);
1263 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1264 struct drm_exynos_ipp_prop_list *pp = &ippdrv->prop_list;
1265 struct drm_exynos_ipp_config *config;
1266 struct drm_exynos_pos *pos;
1267 struct drm_exynos_sz *sz;
1268 bool swap;
1269 int i;
1270
1271 for_each_ipp_ops(i) {
1272 if ((i == EXYNOS_DRM_OPS_SRC) &&
1273 (property->cmd == IPP_CMD_WB))
1274 continue;
1275
1276 config = &property->config[i];
1277 pos = &config->pos;
1278 sz = &config->sz;
1279
1280 /* check for flip */
1281 if (!fimc_check_drm_flip(config->flip)) {
1282 DRM_ERROR("invalid flip.\n");
1283 goto err_property;
1284 }
1285
1286 /* check for degree */
1287 switch (config->degree) {
1288 case EXYNOS_DRM_DEGREE_90:
1289 case EXYNOS_DRM_DEGREE_270:
1290 swap = true;
1291 break;
1292 case EXYNOS_DRM_DEGREE_0:
1293 case EXYNOS_DRM_DEGREE_180:
1294 swap = false;
1295 break;
1296 default:
1297 DRM_ERROR("invalid degree.\n");
1298 goto err_property;
1299 }
1300
1301 /* check for buffer bound */
1302 if ((pos->x + pos->w > sz->hsize) ||
1303 (pos->y + pos->h > sz->vsize)) {
1304 DRM_ERROR("out of buf bound.\n");
1305 goto err_property;
1306 }
1307 963
1308 /* check for crop */ 964 ctx->task = NULL;
1309 if ((i == EXYNOS_DRM_OPS_SRC) && (pp->crop)) { 965 pm_runtime_mark_last_busy(ctx->dev);
1310 if (swap) { 966 pm_runtime_put_autosuspend(ctx->dev);
1311 if ((pos->h < pp->crop_min.hsize) || 967 exynos_drm_ipp_task_done(task, 0);
1312 (sz->vsize > pp->crop_max.hsize) ||
1313 (pos->w < pp->crop_min.vsize) ||
1314 (sz->hsize > pp->crop_max.vsize)) {
1315 DRM_ERROR("out of crop size.\n");
1316 goto err_property;
1317 }
1318 } else {
1319 if ((pos->w < pp->crop_min.hsize) ||
1320 (sz->hsize > pp->crop_max.hsize) ||
1321 (pos->h < pp->crop_min.vsize) ||
1322 (sz->vsize > pp->crop_max.vsize)) {
1323 DRM_ERROR("out of crop size.\n");
1324 goto err_property;
1325 }
1326 }
1327 }
1328
1329 /* check for scale */
1330 if ((i == EXYNOS_DRM_OPS_DST) && (pp->scale)) {
1331 if (swap) {
1332 if ((pos->h < pp->scale_min.hsize) ||
1333 (sz->vsize > pp->scale_max.hsize) ||
1334 (pos->w < pp->scale_min.vsize) ||
1335 (sz->hsize > pp->scale_max.vsize)) {
1336 DRM_ERROR("out of scale size.\n");
1337 goto err_property;
1338 }
1339 } else {
1340 if ((pos->w < pp->scale_min.hsize) ||
1341 (sz->hsize > pp->scale_max.hsize) ||
1342 (pos->h < pp->scale_min.vsize) ||
1343 (sz->vsize > pp->scale_max.vsize)) {
1344 DRM_ERROR("out of scale size.\n");
1345 goto err_property;
1346 }
1347 }
1348 }
1349 } 968 }
1350 969
1351 return 0; 970 fimc_dst_set_buf_seq(ctx, buf_id, false);
971 fimc_stop(ctx);
1352 972
1353err_property: 973 return IRQ_HANDLED;
1354 for_each_ipp_ops(i) {
1355 if ((i == EXYNOS_DRM_OPS_SRC) &&
1356 (property->cmd == IPP_CMD_WB))
1357 continue;
1358
1359 config = &property->config[i];
1360 pos = &config->pos;
1361 sz = &config->sz;
1362
1363 DRM_ERROR("[%s]f[%d]r[%d]pos[%d %d %d %d]sz[%d %d]\n",
1364 i ? "dst" : "src", config->flip, config->degree,
1365 pos->x, pos->y, pos->w, pos->h,
1366 sz->hsize, sz->vsize);
1367 }
1368
1369 return -EINVAL;
1370} 974}
1371 975
1372static void fimc_clear_addr(struct fimc_context *ctx) 976static void fimc_clear_addr(struct fimc_context *ctx)
@@ -1386,10 +990,8 @@ static void fimc_clear_addr(struct fimc_context *ctx)
1386 } 990 }
1387} 991}
1388 992
1389static int fimc_ippdrv_reset(struct device *dev) 993static void fimc_reset(struct fimc_context *ctx)
1390{ 994{
1391 struct fimc_context *ctx = get_fimc_context(dev);
1392
1393 /* reset h/w block */ 995 /* reset h/w block */
1394 fimc_sw_reset(ctx); 996 fimc_sw_reset(ctx);
1395 997
@@ -1397,82 +999,26 @@ static int fimc_ippdrv_reset(struct device *dev)
1397 memset(&ctx->sc, 0x0, sizeof(ctx->sc)); 999 memset(&ctx->sc, 0x0, sizeof(ctx->sc));
1398 1000
1399 fimc_clear_addr(ctx); 1001 fimc_clear_addr(ctx);
1400
1401 return 0;
1402} 1002}
1403 1003
1404static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) 1004static void fimc_start(struct fimc_context *ctx)
1405{ 1005{
1406 struct fimc_context *ctx = get_fimc_context(dev);
1407 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1408 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
1409 struct drm_exynos_ipp_property *property;
1410 struct drm_exynos_ipp_config *config;
1411 struct drm_exynos_pos img_pos[EXYNOS_DRM_OPS_MAX];
1412 struct drm_exynos_ipp_set_wb set_wb;
1413 int ret, i;
1414 u32 cfg0, cfg1; 1006 u32 cfg0, cfg1;
1415 1007
1416 DRM_DEBUG_KMS("cmd[%d]\n", cmd);
1417
1418 if (!c_node) {
1419 DRM_ERROR("failed to get c_node.\n");
1420 return -EINVAL;
1421 }
1422
1423 property = &c_node->property;
1424
1425 fimc_mask_irq(ctx, true); 1008 fimc_mask_irq(ctx, true);
1426 1009
1427 for_each_ipp_ops(i) { 1010 /* If set true, we can save jpeg about screen */
1428 config = &property->config[i];
1429 img_pos[i] = config->pos;
1430 }
1431
1432 ret = fimc_set_prescaler(ctx, &ctx->sc,
1433 &img_pos[EXYNOS_DRM_OPS_SRC],
1434 &img_pos[EXYNOS_DRM_OPS_DST]);
1435 if (ret) {
1436 dev_err(dev, "failed to set prescaler.\n");
1437 return ret;
1438 }
1439
1440 /* If set ture, we can save jpeg about screen */
1441 fimc_handle_jpeg(ctx, false); 1011 fimc_handle_jpeg(ctx, false);
1442 fimc_set_scaler(ctx, &ctx->sc); 1012 fimc_set_scaler(ctx, &ctx->sc);
1443 1013
1444 switch (cmd) { 1014 fimc_set_type_ctrl(ctx);
1445 case IPP_CMD_M2M: 1015 fimc_handle_lastend(ctx, false);
1446 fimc_set_type_ctrl(ctx, FIMC_WB_NONE);
1447 fimc_handle_lastend(ctx, false);
1448
1449 /* setup dma */
1450 cfg0 = fimc_read(ctx, EXYNOS_MSCTRL);
1451 cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK;
1452 cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY;
1453 fimc_write(ctx, cfg0, EXYNOS_MSCTRL);
1454 break;
1455 case IPP_CMD_WB:
1456 fimc_set_type_ctrl(ctx, FIMC_WB_A);
1457 fimc_handle_lastend(ctx, true);
1458
1459 /* setup FIMD */
1460 ret = fimc_set_camblk_fimd0_wb(ctx);
1461 if (ret < 0) {
1462 dev_err(dev, "camblk setup failed.\n");
1463 return ret;
1464 }
1465 1016
1466 set_wb.enable = 1; 1017 /* setup dma */
1467 set_wb.refresh = property->refresh_rate; 1018 cfg0 = fimc_read(ctx, EXYNOS_MSCTRL);
1468 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb); 1019 cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK;
1469 break; 1020 cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY;
1470 case IPP_CMD_OUTPUT: 1021 fimc_write(ctx, cfg0, EXYNOS_MSCTRL);
1471 default:
1472 ret = -EINVAL;
1473 dev_err(dev, "invalid operations.\n");
1474 return ret;
1475 }
1476 1022
1477 /* Reset status */ 1023 /* Reset status */
1478 fimc_write(ctx, 0x0, EXYNOS_CISTATUS); 1024 fimc_write(ctx, 0x0, EXYNOS_CISTATUS);
@@ -1498,36 +1044,18 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
1498 1044
1499 fimc_clear_bits(ctx, EXYNOS_CIOCTRL, EXYNOS_CIOCTRL_WEAVE_MASK); 1045 fimc_clear_bits(ctx, EXYNOS_CIOCTRL, EXYNOS_CIOCTRL_WEAVE_MASK);
1500 1046
1501 if (cmd == IPP_CMD_M2M) 1047 fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
1502 fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
1503
1504 return 0;
1505} 1048}
1506 1049
1507static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd) 1050static void fimc_stop(struct fimc_context *ctx)
1508{ 1051{
1509 struct fimc_context *ctx = get_fimc_context(dev);
1510 struct drm_exynos_ipp_set_wb set_wb = {0, 0};
1511 u32 cfg; 1052 u32 cfg;
1512 1053
1513 DRM_DEBUG_KMS("cmd[%d]\n", cmd); 1054 /* Source clear */
1514 1055 cfg = fimc_read(ctx, EXYNOS_MSCTRL);
1515 switch (cmd) { 1056 cfg &= ~EXYNOS_MSCTRL_INPUT_MASK;
1516 case IPP_CMD_M2M: 1057 cfg &= ~EXYNOS_MSCTRL_ENVID;
1517 /* Source clear */ 1058 fimc_write(ctx, cfg, EXYNOS_MSCTRL);
1518 cfg = fimc_read(ctx, EXYNOS_MSCTRL);
1519 cfg &= ~EXYNOS_MSCTRL_INPUT_MASK;
1520 cfg &= ~EXYNOS_MSCTRL_ENVID;
1521 fimc_write(ctx, cfg, EXYNOS_MSCTRL);
1522 break;
1523 case IPP_CMD_WB:
1524 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb);
1525 break;
1526 case IPP_CMD_OUTPUT:
1527 default:
1528 dev_err(dev, "invalid operations.\n");
1529 break;
1530 }
1531 1059
1532 fimc_mask_irq(ctx, false); 1060 fimc_mask_irq(ctx, false);
1533 1061
@@ -1545,6 +1073,87 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
1545 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE); 1073 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE);
1546} 1074}
1547 1075
1076static int fimc_commit(struct exynos_drm_ipp *ipp,
1077 struct exynos_drm_ipp_task *task)
1078{
1079 struct fimc_context *ctx =
1080 container_of(ipp, struct fimc_context, ipp);
1081
1082 pm_runtime_get_sync(ctx->dev);
1083 ctx->task = task;
1084
1085 fimc_src_set_fmt(ctx, task->src.buf.fourcc, task->src.buf.modifier);
1086 fimc_src_set_size(ctx, &task->src);
1087 fimc_src_set_transf(ctx, DRM_MODE_ROTATE_0);
1088 fimc_src_set_addr(ctx, &task->src);
1089 fimc_dst_set_fmt(ctx, task->dst.buf.fourcc, task->dst.buf.modifier);
1090 fimc_dst_set_transf(ctx, task->transform.rotation);
1091 fimc_dst_set_size(ctx, &task->dst);
1092 fimc_dst_set_addr(ctx, &task->dst);
1093 fimc_set_prescaler(ctx, &ctx->sc, &task->src.rect, &task->dst.rect);
1094 fimc_start(ctx);
1095
1096 return 0;
1097}
1098
1099static void fimc_abort(struct exynos_drm_ipp *ipp,
1100 struct exynos_drm_ipp_task *task)
1101{
1102 struct fimc_context *ctx =
1103 container_of(ipp, struct fimc_context, ipp);
1104
1105 fimc_reset(ctx);
1106
1107 if (ctx->task) {
1108 struct exynos_drm_ipp_task *task = ctx->task;
1109
1110 ctx->task = NULL;
1111 pm_runtime_mark_last_busy(ctx->dev);
1112 pm_runtime_put_autosuspend(ctx->dev);
1113 exynos_drm_ipp_task_done(task, -EIO);
1114 }
1115}
1116
1117static struct exynos_drm_ipp_funcs ipp_funcs = {
1118 .commit = fimc_commit,
1119 .abort = fimc_abort,
1120};
1121
1122static int fimc_bind(struct device *dev, struct device *master, void *data)
1123{
1124 struct fimc_context *ctx = dev_get_drvdata(dev);
1125 struct drm_device *drm_dev = data;
1126 struct exynos_drm_ipp *ipp = &ctx->ipp;
1127
1128 ctx->drm_dev = drm_dev;
1129 drm_iommu_attach_device(drm_dev, dev);
1130
1131 exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs,
1132 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
1133 DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT,
1134 ctx->formats, ctx->num_formats, "fimc");
1135
1136 dev_info(dev, "The exynos fimc has been probed successfully\n");
1137
1138 return 0;
1139}
1140
1141static void fimc_unbind(struct device *dev, struct device *master,
1142 void *data)
1143{
1144 struct fimc_context *ctx = dev_get_drvdata(dev);
1145 struct drm_device *drm_dev = data;
1146 struct exynos_drm_ipp *ipp = &ctx->ipp;
1147
1148 exynos_drm_ipp_unregister(drm_dev, ipp);
1149 drm_iommu_detach_device(drm_dev, dev);
1150}
1151
1152static const struct component_ops fimc_component_ops = {
1153 .bind = fimc_bind,
1154 .unbind = fimc_unbind,
1155};
1156
1548static void fimc_put_clocks(struct fimc_context *ctx) 1157static void fimc_put_clocks(struct fimc_context *ctx)
1549{ 1158{
1550 int i; 1159 int i;
@@ -1559,7 +1168,7 @@ static void fimc_put_clocks(struct fimc_context *ctx)
1559 1168
1560static int fimc_setup_clocks(struct fimc_context *ctx) 1169static int fimc_setup_clocks(struct fimc_context *ctx)
1561{ 1170{
1562 struct device *fimc_dev = ctx->ippdrv.dev; 1171 struct device *fimc_dev = ctx->dev;
1563 struct device *dev; 1172 struct device *dev;
1564 int ret, i; 1173 int ret, i;
1565 1174
@@ -1574,8 +1183,6 @@ static int fimc_setup_clocks(struct fimc_context *ctx)
1574 1183
1575 ctx->clocks[i] = clk_get(dev, fimc_clock_names[i]); 1184 ctx->clocks[i] = clk_get(dev, fimc_clock_names[i]);
1576 if (IS_ERR(ctx->clocks[i])) { 1185 if (IS_ERR(ctx->clocks[i])) {
1577 if (i >= FIMC_CLK_MUX)
1578 break;
1579 ret = PTR_ERR(ctx->clocks[i]); 1186 ret = PTR_ERR(ctx->clocks[i]);
1580 dev_err(fimc_dev, "failed to get clock: %s\n", 1187 dev_err(fimc_dev, "failed to get clock: %s\n",
1581 fimc_clock_names[i]); 1188 fimc_clock_names[i]);
@@ -1583,20 +1190,6 @@ static int fimc_setup_clocks(struct fimc_context *ctx)
1583 } 1190 }
1584 } 1191 }
1585 1192
1586 /* Optional FIMC LCLK parent clock setting */
1587 if (!IS_ERR(ctx->clocks[FIMC_CLK_PARENT])) {
1588 ret = clk_set_parent(ctx->clocks[FIMC_CLK_MUX],
1589 ctx->clocks[FIMC_CLK_PARENT]);
1590 if (ret < 0) {
1591 dev_err(fimc_dev, "failed to set parent.\n");
1592 goto e_clk_free;
1593 }
1594 }
1595
1596 ret = clk_set_rate(ctx->clocks[FIMC_CLK_LCLK], ctx->clk_frequency);
1597 if (ret < 0)
1598 goto e_clk_free;
1599
1600 ret = clk_prepare_enable(ctx->clocks[FIMC_CLK_LCLK]); 1193 ret = clk_prepare_enable(ctx->clocks[FIMC_CLK_LCLK]);
1601 if (!ret) 1194 if (!ret)
1602 return ret; 1195 return ret;
@@ -1605,57 +1198,118 @@ e_clk_free:
1605 return ret; 1198 return ret;
1606} 1199}
1607 1200
1608static int fimc_parse_dt(struct fimc_context *ctx) 1201int exynos_drm_check_fimc_device(struct device *dev)
1609{ 1202{
1610 struct device_node *node = ctx->ippdrv.dev->of_node; 1203 int id = of_alias_get_id(dev->of_node, "fimc");
1611 1204
1612 /* Handle only devices that support the LCD Writeback data path */ 1205 if (id >= 0 && (BIT(id) & fimc_mask))
1613 if (!of_property_read_bool(node, "samsung,lcd-wb")) 1206 return 0;
1614 return -ENODEV; 1207 return -ENODEV;
1208}
1615 1209
1616 if (of_property_read_u32(node, "clock-frequency", 1210static const unsigned int fimc_formats[] = {
1617 &ctx->clk_frequency)) 1211 DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB565,
1618 ctx->clk_frequency = FIMC_DEFAULT_LCLK_FREQUENCY; 1212 DRM_FORMAT_NV12, DRM_FORMAT_NV16, DRM_FORMAT_NV21, DRM_FORMAT_NV61,
1213 DRM_FORMAT_UYVY, DRM_FORMAT_VYUY, DRM_FORMAT_YUYV, DRM_FORMAT_YVYU,
1214 DRM_FORMAT_YUV420, DRM_FORMAT_YVU420, DRM_FORMAT_YUV422,
1215 DRM_FORMAT_YUV444,
1216};
1619 1217
1620 ctx->id = of_alias_get_id(node, "fimc"); 1218static const unsigned int fimc_tiled_formats[] = {
1219 DRM_FORMAT_NV12, DRM_FORMAT_NV21,
1220};
1621 1221
1622 if (ctx->id < 0) { 1222static const struct drm_exynos_ipp_limit fimc_4210_limits_v1[] = {
1623 dev_err(ctx->ippdrv.dev, "failed to get node alias id.\n"); 1223 { IPP_SIZE_LIMIT(BUFFER, .h = { 16, 8192, 8 }, .v = { 16, 8192, 2 }) },
1624 return -EINVAL; 1224 { IPP_SIZE_LIMIT(AREA, .h = { 16, 4224, 2 }, .v = { 16, 0, 2 }) },
1625 } 1225 { IPP_SIZE_LIMIT(ROTATED, .h = { 128, 1920 }, .v = { 128, 0 }) },
1226 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 },
1227 .v = { (1 << 16) / 64, (1 << 16) * 64 }) },
1228};
1626 1229
1627 return 0; 1230static const struct drm_exynos_ipp_limit fimc_4210_limits_v2[] = {
1628} 1231 { IPP_SIZE_LIMIT(BUFFER, .h = { 16, 8192, 8 }, .v = { 16, 8192, 2 }) },
1232 { IPP_SIZE_LIMIT(AREA, .h = { 16, 1920, 2 }, .v = { 16, 0, 2 }) },
1233 { IPP_SIZE_LIMIT(ROTATED, .h = { 128, 1366 }, .v = { 128, 0 }) },
1234 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 },
1235 .v = { (1 << 16) / 64, (1 << 16) * 64 }) },
1236};
1237
1238static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v1[] = {
1239 { IPP_SIZE_LIMIT(BUFFER, .h = { 128, 1920, 128 }, .v = { 32, 1920, 32 }) },
1240 { IPP_SIZE_LIMIT(AREA, .h = { 128, 1920, 2 }, .v = { 128, 0, 2 }) },
1241 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 },
1242 .v = { (1 << 16) / 64, (1 << 16) * 64 }) },
1243};
1244
1245static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v2[] = {
1246 { IPP_SIZE_LIMIT(BUFFER, .h = { 128, 1920, 128 }, .v = { 32, 1920, 32 }) },
1247 { IPP_SIZE_LIMIT(AREA, .h = { 128, 1366, 2 }, .v = { 128, 0, 2 }) },
1248 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 },
1249 .v = { (1 << 16) / 64, (1 << 16) * 64 }) },
1250};
1629 1251
1630static int fimc_probe(struct platform_device *pdev) 1252static int fimc_probe(struct platform_device *pdev)
1631{ 1253{
1254 const struct drm_exynos_ipp_limit *limits;
1255 struct exynos_drm_ipp_formats *formats;
1632 struct device *dev = &pdev->dev; 1256 struct device *dev = &pdev->dev;
1633 struct fimc_context *ctx; 1257 struct fimc_context *ctx;
1634 struct resource *res; 1258 struct resource *res;
1635 struct exynos_drm_ippdrv *ippdrv;
1636 int ret; 1259 int ret;
1260 int i, j, num_limits, num_formats;
1637 1261
1638 if (!dev->of_node) { 1262 if (exynos_drm_check_fimc_device(dev) != 0)
1639 dev_err(dev, "device tree node not found.\n");
1640 return -ENODEV; 1263 return -ENODEV;
1641 }
1642 1264
1643 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 1265 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
1644 if (!ctx) 1266 if (!ctx)
1645 return -ENOMEM; 1267 return -ENOMEM;
1646 1268
1647 ctx->ippdrv.dev = dev; 1269 ctx->dev = dev;
1270 ctx->id = of_alias_get_id(dev->of_node, "fimc");
1648 1271
1649 ret = fimc_parse_dt(ctx); 1272 /* construct formats/limits array */
1650 if (ret < 0) 1273 num_formats = ARRAY_SIZE(fimc_formats) + ARRAY_SIZE(fimc_tiled_formats);
1651 return ret; 1274 formats = devm_kzalloc(dev, sizeof(*formats) * num_formats, GFP_KERNEL);
1275 if (!formats)
1276 return -ENOMEM;
1277
1278 /* linear formats */
1279 if (ctx->id < 3) {
1280 limits = fimc_4210_limits_v1;
1281 num_limits = ARRAY_SIZE(fimc_4210_limits_v1);
1282 } else {
1283 limits = fimc_4210_limits_v2;
1284 num_limits = ARRAY_SIZE(fimc_4210_limits_v2);
1285 }
1286 for (i = 0; i < ARRAY_SIZE(fimc_formats); i++) {
1287 formats[i].fourcc = fimc_formats[i];
1288 formats[i].type = DRM_EXYNOS_IPP_FORMAT_SOURCE |
1289 DRM_EXYNOS_IPP_FORMAT_DESTINATION;
1290 formats[i].limits = limits;
1291 formats[i].num_limits = num_limits;
1292 }
1652 1293
1653 ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, 1294 /* tiled formats */
1654 "samsung,sysreg"); 1295 if (ctx->id < 3) {
1655 if (IS_ERR(ctx->sysreg)) { 1296 limits = fimc_4210_limits_tiled_v1;
1656 dev_err(dev, "syscon regmap lookup failed.\n"); 1297 num_limits = ARRAY_SIZE(fimc_4210_limits_tiled_v1);
1657 return PTR_ERR(ctx->sysreg); 1298 } else {
1299 limits = fimc_4210_limits_tiled_v2;
1300 num_limits = ARRAY_SIZE(fimc_4210_limits_tiled_v2);
1658 } 1301 }
1302 for (j = i, i = 0; i < ARRAY_SIZE(fimc_tiled_formats); j++, i++) {
1303 formats[j].fourcc = fimc_tiled_formats[i];
1304 formats[j].modifier = DRM_FORMAT_MOD_SAMSUNG_64_32_TILE;
1305 formats[j].type = DRM_EXYNOS_IPP_FORMAT_SOURCE |
1306 DRM_EXYNOS_IPP_FORMAT_DESTINATION;
1307 formats[j].limits = limits;
1308 formats[j].num_limits = num_limits;
1309 }
1310
1311 ctx->formats = formats;
1312 ctx->num_formats = num_formats;
1659 1313
1660 /* resource memory */ 1314 /* resource memory */
1661 ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1315 ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1670,9 +1324,8 @@ static int fimc_probe(struct platform_device *pdev)
1670 return -ENOENT; 1324 return -ENOENT;
1671 } 1325 }
1672 1326
1673 ctx->irq = res->start; 1327 ret = devm_request_irq(dev, res->start, fimc_irq_handler,
1674 ret = devm_request_threaded_irq(dev, ctx->irq, NULL, fimc_irq_handler, 1328 0, dev_name(dev), ctx);
1675 IRQF_ONESHOT, "drm_fimc", ctx);
1676 if (ret < 0) { 1329 if (ret < 0) {
1677 dev_err(dev, "failed to request irq.\n"); 1330 dev_err(dev, "failed to request irq.\n");
1678 return ret; 1331 return ret;
@@ -1682,39 +1335,24 @@ static int fimc_probe(struct platform_device *pdev)
1682 if (ret < 0) 1335 if (ret < 0)
1683 return ret; 1336 return ret;
1684 1337
1685 ippdrv = &ctx->ippdrv;
1686 ippdrv->ops[EXYNOS_DRM_OPS_SRC] = &fimc_src_ops;
1687 ippdrv->ops[EXYNOS_DRM_OPS_DST] = &fimc_dst_ops;
1688 ippdrv->check_property = fimc_ippdrv_check_property;
1689 ippdrv->reset = fimc_ippdrv_reset;
1690 ippdrv->start = fimc_ippdrv_start;
1691 ippdrv->stop = fimc_ippdrv_stop;
1692 ret = fimc_init_prop_list(ippdrv);
1693 if (ret < 0) {
1694 dev_err(dev, "failed to init property list.\n");
1695 goto err_put_clk;
1696 }
1697
1698 DRM_DEBUG_KMS("id[%d]ippdrv[%pK]\n", ctx->id, ippdrv);
1699
1700 spin_lock_init(&ctx->lock); 1338 spin_lock_init(&ctx->lock);
1701 platform_set_drvdata(pdev, ctx); 1339 platform_set_drvdata(pdev, ctx);
1702 1340
1341 pm_runtime_use_autosuspend(dev);
1342 pm_runtime_set_autosuspend_delay(dev, FIMC_AUTOSUSPEND_DELAY);
1703 pm_runtime_enable(dev); 1343 pm_runtime_enable(dev);
1704 1344
1705 ret = exynos_drm_ippdrv_register(ippdrv); 1345 ret = component_add(dev, &fimc_component_ops);
1706 if (ret < 0) { 1346 if (ret)
1707 dev_err(dev, "failed to register drm fimc device.\n");
1708 goto err_pm_dis; 1347 goto err_pm_dis;
1709 }
1710 1348
1711 dev_info(dev, "drm fimc registered successfully.\n"); 1349 dev_info(dev, "drm fimc registered successfully.\n");
1712 1350
1713 return 0; 1351 return 0;
1714 1352
1715err_pm_dis: 1353err_pm_dis:
1354 pm_runtime_dont_use_autosuspend(dev);
1716 pm_runtime_disable(dev); 1355 pm_runtime_disable(dev);
1717err_put_clk:
1718 fimc_put_clocks(ctx); 1356 fimc_put_clocks(ctx);
1719 1357
1720 return ret; 1358 return ret;
@@ -1724,42 +1362,24 @@ static int fimc_remove(struct platform_device *pdev)
1724{ 1362{
1725 struct device *dev = &pdev->dev; 1363 struct device *dev = &pdev->dev;
1726 struct fimc_context *ctx = get_fimc_context(dev); 1364 struct fimc_context *ctx = get_fimc_context(dev);
1727 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1728 1365
1729 exynos_drm_ippdrv_unregister(ippdrv); 1366 component_del(dev, &fimc_component_ops);
1367 pm_runtime_dont_use_autosuspend(dev);
1368 pm_runtime_disable(dev);
1730 1369
1731 fimc_put_clocks(ctx); 1370 fimc_put_clocks(ctx);
1732 pm_runtime_set_suspended(dev);
1733 pm_runtime_disable(dev);
1734 1371
1735 return 0; 1372 return 0;
1736} 1373}
1737 1374
1738#ifdef CONFIG_PM 1375#ifdef CONFIG_PM
1739static int fimc_clk_ctrl(struct fimc_context *ctx, bool enable)
1740{
1741 DRM_DEBUG_KMS("enable[%d]\n", enable);
1742
1743 if (enable) {
1744 clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]);
1745 clk_prepare_enable(ctx->clocks[FIMC_CLK_WB_A]);
1746 ctx->suspended = false;
1747 } else {
1748 clk_disable_unprepare(ctx->clocks[FIMC_CLK_GATE]);
1749 clk_disable_unprepare(ctx->clocks[FIMC_CLK_WB_A]);
1750 ctx->suspended = true;
1751 }
1752
1753 return 0;
1754}
1755
1756static int fimc_runtime_suspend(struct device *dev) 1376static int fimc_runtime_suspend(struct device *dev)
1757{ 1377{
1758 struct fimc_context *ctx = get_fimc_context(dev); 1378 struct fimc_context *ctx = get_fimc_context(dev);
1759 1379
1760 DRM_DEBUG_KMS("id[%d]\n", ctx->id); 1380 DRM_DEBUG_KMS("id[%d]\n", ctx->id);
1761 1381 clk_disable_unprepare(ctx->clocks[FIMC_CLK_GATE]);
1762 return fimc_clk_ctrl(ctx, false); 1382 return 0;
1763} 1383}
1764 1384
1765static int fimc_runtime_resume(struct device *dev) 1385static int fimc_runtime_resume(struct device *dev)
@@ -1767,8 +1387,7 @@ static int fimc_runtime_resume(struct device *dev)
1767 struct fimc_context *ctx = get_fimc_context(dev); 1387 struct fimc_context *ctx = get_fimc_context(dev);
1768 1388
1769 DRM_DEBUG_KMS("id[%d]\n", ctx->id); 1389 DRM_DEBUG_KMS("id[%d]\n", ctx->id);
1770 1390 return clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]);
1771 return fimc_clk_ctrl(ctx, true);
1772} 1391}
1773#endif 1392#endif
1774 1393
@@ -1795,4 +1414,3 @@ struct platform_driver fimc_driver = {
1795 .pm = &fimc_pm_ops, 1414 .pm = &fimc_pm_ops,
1796 }, 1415 },
1797}; 1416};
1798
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.h b/drivers/gpu/drm/exynos/exynos_drm_fimc.h
deleted file mode 100644
index 127a424c5fdf..000000000000
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 *
4 * Authors:
5 * Eunchul Kim <chulspro.kim@samsung.com>
6 * Jinyoung Jeon <jy0.jeon@samsung.com>
7 * Sangmin Lee <lsmin.lee@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#ifndef _EXYNOS_DRM_FIMC_H_
16#define _EXYNOS_DRM_FIMC_H_
17
18/*
19 * TODO
20 * FIMD output interface notifier callback.
21 */
22
23#endif /* _EXYNOS_DRM_FIMC_H_ */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index d42ae2bc3e56..01b1570d0c3a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -121,6 +121,12 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {
121 .has_limited_fmt = 1, 121 .has_limited_fmt = 1,
122}; 122};
123 123
124static struct fimd_driver_data s5pv210_fimd_driver_data = {
125 .timing_base = 0x0,
126 .has_shadowcon = 1,
127 .has_clksel = 1,
128};
129
124static struct fimd_driver_data exynos3_fimd_driver_data = { 130static struct fimd_driver_data exynos3_fimd_driver_data = {
125 .timing_base = 0x20000, 131 .timing_base = 0x20000,
126 .lcdblk_offset = 0x210, 132 .lcdblk_offset = 0x210,
@@ -193,6 +199,8 @@ struct fimd_context {
193static const struct of_device_id fimd_driver_dt_match[] = { 199static const struct of_device_id fimd_driver_dt_match[] = {
194 { .compatible = "samsung,s3c6400-fimd", 200 { .compatible = "samsung,s3c6400-fimd",
195 .data = &s3c64xx_fimd_driver_data }, 201 .data = &s3c64xx_fimd_driver_data },
202 { .compatible = "samsung,s5pv210-fimd",
203 .data = &s5pv210_fimd_driver_data },
196 { .compatible = "samsung,exynos3250-fimd", 204 { .compatible = "samsung,exynos3250-fimd",
197 .data = &exynos3_fimd_driver_data }, 205 .data = &exynos3_fimd_driver_data },
198 { .compatible = "samsung,exynos4210-fimd", 206 { .compatible = "samsung,exynos4210-fimd",
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 11cc01b47bc0..6e1494fa71b4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -431,37 +431,24 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
431 return 0; 431 return 0;
432} 432}
433 433
434int exynos_drm_gem_fault(struct vm_fault *vmf) 434vm_fault_t exynos_drm_gem_fault(struct vm_fault *vmf)
435{ 435{
436 struct vm_area_struct *vma = vmf->vma; 436 struct vm_area_struct *vma = vmf->vma;
437 struct drm_gem_object *obj = vma->vm_private_data; 437 struct drm_gem_object *obj = vma->vm_private_data;
438 struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj); 438 struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
439 unsigned long pfn; 439 unsigned long pfn;
440 pgoff_t page_offset; 440 pgoff_t page_offset;
441 int ret;
442 441
443 page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT; 442 page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
444 443
445 if (page_offset >= (exynos_gem->size >> PAGE_SHIFT)) { 444 if (page_offset >= (exynos_gem->size >> PAGE_SHIFT)) {
446 DRM_ERROR("invalid page offset\n"); 445 DRM_ERROR("invalid page offset\n");
447 ret = -EINVAL; 446 return VM_FAULT_SIGBUS;
448 goto out;
449 } 447 }
450 448
451 pfn = page_to_pfn(exynos_gem->pages[page_offset]); 449 pfn = page_to_pfn(exynos_gem->pages[page_offset]);
452 ret = vm_insert_mixed(vma, vmf->address, __pfn_to_pfn_t(pfn, PFN_DEV)); 450 return vmf_insert_mixed(vma, vmf->address,
453 451 __pfn_to_pfn_t(pfn, PFN_DEV));
454out:
455 switch (ret) {
456 case 0:
457 case -ERESTARTSYS:
458 case -EINTR:
459 return VM_FAULT_NOPAGE;
460 case -ENOMEM:
461 return VM_FAULT_OOM;
462 default:
463 return VM_FAULT_SIGBUS;
464 }
465} 452}
466 453
467static int exynos_drm_gem_mmap_obj(struct drm_gem_object *obj, 454static int exynos_drm_gem_mmap_obj(struct drm_gem_object *obj,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 5a4c7de80f65..9057d7f1d6ed 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -13,6 +13,7 @@
13#define _EXYNOS_DRM_GEM_H_ 13#define _EXYNOS_DRM_GEM_H_
14 14
15#include <drm/drm_gem.h> 15#include <drm/drm_gem.h>
16#include <linux/mm_types.h>
16 17
17#define to_exynos_gem(x) container_of(x, struct exynos_drm_gem, base) 18#define to_exynos_gem(x) container_of(x, struct exynos_drm_gem, base)
18 19
@@ -111,7 +112,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
111 struct drm_mode_create_dumb *args); 112 struct drm_mode_create_dumb *args);
112 113
113/* page fault handler and mmap fault address(virtual) to physical memory. */ 114/* page fault handler and mmap fault address(virtual) to physical memory. */
114int exynos_drm_gem_fault(struct vm_fault *vmf); 115vm_fault_t exynos_drm_gem_fault(struct vm_fault *vmf);
115 116
116/* set vm_flags and we can change the vm attribute to other one at here. */ 117/* set vm_flags and we can change the vm attribute to other one at here. */
117int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); 118int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 0506b2b17ac1..e99dd1e4ba65 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -12,18 +12,20 @@
12 * 12 *
13 */ 13 */
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/component.h>
15#include <linux/platform_device.h> 16#include <linux/platform_device.h>
16#include <linux/clk.h> 17#include <linux/clk.h>
17#include <linux/pm_runtime.h> 18#include <linux/pm_runtime.h>
18#include <linux/mfd/syscon.h> 19#include <linux/mfd/syscon.h>
20#include <linux/of_device.h>
19#include <linux/regmap.h> 21#include <linux/regmap.h>
20 22
21#include <drm/drmP.h> 23#include <drm/drmP.h>
22#include <drm/exynos_drm.h> 24#include <drm/exynos_drm.h>
23#include "regs-gsc.h" 25#include "regs-gsc.h"
24#include "exynos_drm_drv.h" 26#include "exynos_drm_drv.h"
27#include "exynos_drm_iommu.h"
25#include "exynos_drm_ipp.h" 28#include "exynos_drm_ipp.h"
26#include "exynos_drm_gsc.h"
27 29
28/* 30/*
29 * GSC stands for General SCaler and 31 * GSC stands for General SCaler and
@@ -31,26 +33,10 @@
31 * input DMA reads image data from the memory. 33 * input DMA reads image data from the memory.
32 * output DMA writes image data to memory. 34 * output DMA writes image data to memory.
33 * GSC supports image rotation and image effect functions. 35 * GSC supports image rotation and image effect functions.
34 *
35 * M2M operation : supports crop/scale/rotation/csc so on.
36 * Memory ----> GSC H/W ----> Memory.
37 * Writeback operation : supports cloned screen with FIMD.
38 * FIMD ----> GSC H/W ----> Memory.
39 * Output operation : supports direct display using local path.
40 * Memory ----> GSC H/W ----> FIMD, Mixer.
41 */ 36 */
42 37
43/*
44 * TODO
45 * 1. check suspend/resume api if needed.
46 * 2. need to check use case platform_device_id.
47 * 3. check src/dst size with, height.
48 * 4. added check_prepare api for right register.
49 * 5. need to add supported list in prop_list.
50 * 6. check prescaler/scaler optimization.
51 */
52 38
53#define GSC_MAX_DEVS 4 39#define GSC_MAX_CLOCKS 8
54#define GSC_MAX_SRC 4 40#define GSC_MAX_SRC 4
55#define GSC_MAX_DST 16 41#define GSC_MAX_DST 16
56#define GSC_RESET_TIMEOUT 50 42#define GSC_RESET_TIMEOUT 50
@@ -65,8 +51,6 @@
65#define GSC_SC_DOWN_RATIO_4_8 131072 51#define GSC_SC_DOWN_RATIO_4_8 131072
66#define GSC_SC_DOWN_RATIO_3_8 174762 52#define GSC_SC_DOWN_RATIO_3_8 174762
67#define GSC_SC_DOWN_RATIO_2_8 262144 53#define GSC_SC_DOWN_RATIO_2_8 262144
68#define GSC_REFRESH_MIN 12
69#define GSC_REFRESH_MAX 60
70#define GSC_CROP_MAX 8192 54#define GSC_CROP_MAX 8192
71#define GSC_CROP_MIN 32 55#define GSC_CROP_MIN 32
72#define GSC_SCALE_MAX 4224 56#define GSC_SCALE_MAX 4224
@@ -77,10 +61,9 @@
77#define GSC_COEF_H_8T 8 61#define GSC_COEF_H_8T 8
78#define GSC_COEF_V_4T 4 62#define GSC_COEF_V_4T 4
79#define GSC_COEF_DEPTH 3 63#define GSC_COEF_DEPTH 3
64#define GSC_AUTOSUSPEND_DELAY 2000
80 65
81#define get_gsc_context(dev) platform_get_drvdata(to_platform_device(dev)) 66#define get_gsc_context(dev) platform_get_drvdata(to_platform_device(dev))
82#define get_ctx_from_ippdrv(ippdrv) container_of(ippdrv,\
83 struct gsc_context, ippdrv);
84#define gsc_read(offset) readl(ctx->regs + (offset)) 67#define gsc_read(offset) readl(ctx->regs + (offset))
85#define gsc_write(cfg, offset) writel(cfg, ctx->regs + (offset)) 68#define gsc_write(cfg, offset) writel(cfg, ctx->regs + (offset))
86 69
@@ -104,50 +87,47 @@ struct gsc_scaler {
104}; 87};
105 88
106/* 89/*
107 * A structure of scaler capability.
108 *
109 * find user manual 49.2 features.
110 * @tile_w: tile mode or rotation width.
111 * @tile_h: tile mode or rotation height.
112 * @w: other cases width.
113 * @h: other cases height.
114 */
115struct gsc_capability {
116 /* tile or rotation */
117 u32 tile_w;
118 u32 tile_h;
119 /* other cases */
120 u32 w;
121 u32 h;
122};
123
124/*
125 * A structure of gsc context. 90 * A structure of gsc context.
126 * 91 *
127 * @ippdrv: prepare initialization using ippdrv.
128 * @regs_res: register resources. 92 * @regs_res: register resources.
129 * @regs: memory mapped io registers. 93 * @regs: memory mapped io registers.
130 * @sysreg: handle to SYSREG block regmap.
131 * @lock: locking of operations.
132 * @gsc_clk: gsc gate clock. 94 * @gsc_clk: gsc gate clock.
133 * @sc: scaler infomations. 95 * @sc: scaler infomations.
134 * @id: gsc id. 96 * @id: gsc id.
135 * @irq: irq number. 97 * @irq: irq number.
136 * @rotation: supports rotation of src. 98 * @rotation: supports rotation of src.
137 * @suspended: qos operations.
138 */ 99 */
139struct gsc_context { 100struct gsc_context {
140 struct exynos_drm_ippdrv ippdrv; 101 struct exynos_drm_ipp ipp;
102 struct drm_device *drm_dev;
103 struct device *dev;
104 struct exynos_drm_ipp_task *task;
105 struct exynos_drm_ipp_formats *formats;
106 unsigned int num_formats;
107
141 struct resource *regs_res; 108 struct resource *regs_res;
142 void __iomem *regs; 109 void __iomem *regs;
143 struct regmap *sysreg; 110 const char **clk_names;
144 struct mutex lock; 111 struct clk *clocks[GSC_MAX_CLOCKS];
145 struct clk *gsc_clk; 112 int num_clocks;
146 struct gsc_scaler sc; 113 struct gsc_scaler sc;
147 int id; 114 int id;
148 int irq; 115 int irq;
149 bool rotation; 116 bool rotation;
150 bool suspended; 117};
118
119/**
120 * struct gsc_driverdata - per device type driver data for init time.
121 *
122 * @limits: picture size limits array
123 * @clk_names: names of clocks needed by this variant
124 * @num_clocks: the number of clocks needed by this variant
125 */
126struct gsc_driverdata {
127 const struct drm_exynos_ipp_limit *limits;
128 int num_limits;
129 const char *clk_names[GSC_MAX_CLOCKS];
130 int num_clocks;
151}; 131};
152 132
153/* 8-tap Filter Coefficient */ 133/* 8-tap Filter Coefficient */
@@ -438,25 +418,6 @@ static int gsc_sw_reset(struct gsc_context *ctx)
438 return 0; 418 return 0;
439} 419}
440 420
441static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
442{
443 unsigned int gscblk_cfg;
444
445 if (!ctx->sysreg)
446 return;
447
448 regmap_read(ctx->sysreg, SYSREG_GSCBLK_CFG1, &gscblk_cfg);
449
450 if (enable)
451 gscblk_cfg |= GSC_BLK_DISP1WB_DEST(ctx->id) |
452 GSC_BLK_GSCL_WB_IN_SRC_SEL(ctx->id) |
453 GSC_BLK_SW_RESET_WB_DEST(ctx->id);
454 else
455 gscblk_cfg |= GSC_BLK_PXLASYNC_LO_MASK_WB(ctx->id);
456
457 regmap_write(ctx->sysreg, SYSREG_GSCBLK_CFG1, gscblk_cfg);
458}
459
460static void gsc_handle_irq(struct gsc_context *ctx, bool enable, 421static void gsc_handle_irq(struct gsc_context *ctx, bool enable,
461 bool overflow, bool done) 422 bool overflow, bool done)
462{ 423{
@@ -487,10 +448,8 @@ static void gsc_handle_irq(struct gsc_context *ctx, bool enable,
487} 448}
488 449
489 450
490static int gsc_src_set_fmt(struct device *dev, u32 fmt) 451static void gsc_src_set_fmt(struct gsc_context *ctx, u32 fmt)
491{ 452{
492 struct gsc_context *ctx = get_gsc_context(dev);
493 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
494 u32 cfg; 453 u32 cfg;
495 454
496 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 455 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
@@ -506,6 +465,7 @@ static int gsc_src_set_fmt(struct device *dev, u32 fmt)
506 cfg |= GSC_IN_RGB565; 465 cfg |= GSC_IN_RGB565;
507 break; 466 break;
508 case DRM_FORMAT_XRGB8888: 467 case DRM_FORMAT_XRGB8888:
468 case DRM_FORMAT_ARGB8888:
509 cfg |= GSC_IN_XRGB8888; 469 cfg |= GSC_IN_XRGB8888;
510 break; 470 break;
511 case DRM_FORMAT_BGRX8888: 471 case DRM_FORMAT_BGRX8888:
@@ -548,115 +508,84 @@ static int gsc_src_set_fmt(struct device *dev, u32 fmt)
548 cfg |= (GSC_IN_CHROMA_ORDER_CBCR | 508 cfg |= (GSC_IN_CHROMA_ORDER_CBCR |
549 GSC_IN_YUV420_2P); 509 GSC_IN_YUV420_2P);
550 break; 510 break;
551 default:
552 dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt);
553 return -EINVAL;
554 } 511 }
555 512
556 gsc_write(cfg, GSC_IN_CON); 513 gsc_write(cfg, GSC_IN_CON);
557
558 return 0;
559} 514}
560 515
561static int gsc_src_set_transf(struct device *dev, 516static void gsc_src_set_transf(struct gsc_context *ctx, unsigned int rotation)
562 enum drm_exynos_degree degree,
563 enum drm_exynos_flip flip, bool *swap)
564{ 517{
565 struct gsc_context *ctx = get_gsc_context(dev); 518 unsigned int degree = rotation & DRM_MODE_ROTATE_MASK;
566 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
567 u32 cfg; 519 u32 cfg;
568 520
569 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
570
571 cfg = gsc_read(GSC_IN_CON); 521 cfg = gsc_read(GSC_IN_CON);
572 cfg &= ~GSC_IN_ROT_MASK; 522 cfg &= ~GSC_IN_ROT_MASK;
573 523
574 switch (degree) { 524 switch (degree) {
575 case EXYNOS_DRM_DEGREE_0: 525 case DRM_MODE_ROTATE_0:
576 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 526 if (rotation & DRM_MODE_REFLECT_Y)
577 cfg |= GSC_IN_ROT_XFLIP; 527 cfg |= GSC_IN_ROT_XFLIP;
578 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 528 if (rotation & DRM_MODE_REFLECT_X)
579 cfg |= GSC_IN_ROT_YFLIP; 529 cfg |= GSC_IN_ROT_YFLIP;
580 break; 530 break;
581 case EXYNOS_DRM_DEGREE_90: 531 case DRM_MODE_ROTATE_90:
582 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 532 cfg |= GSC_IN_ROT_90;
583 cfg |= GSC_IN_ROT_90_XFLIP; 533 if (rotation & DRM_MODE_REFLECT_Y)
584 else if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 534 cfg |= GSC_IN_ROT_XFLIP;
585 cfg |= GSC_IN_ROT_90_YFLIP; 535 if (rotation & DRM_MODE_REFLECT_X)
586 else 536 cfg |= GSC_IN_ROT_YFLIP;
587 cfg |= GSC_IN_ROT_90;
588 break; 537 break;
589 case EXYNOS_DRM_DEGREE_180: 538 case DRM_MODE_ROTATE_180:
590 cfg |= GSC_IN_ROT_180; 539 cfg |= GSC_IN_ROT_180;
591 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 540 if (rotation & DRM_MODE_REFLECT_Y)
592 cfg &= ~GSC_IN_ROT_XFLIP; 541 cfg &= ~GSC_IN_ROT_XFLIP;
593 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 542 if (rotation & DRM_MODE_REFLECT_X)
594 cfg &= ~GSC_IN_ROT_YFLIP; 543 cfg &= ~GSC_IN_ROT_YFLIP;
595 break; 544 break;
596 case EXYNOS_DRM_DEGREE_270: 545 case DRM_MODE_ROTATE_270:
597 cfg |= GSC_IN_ROT_270; 546 cfg |= GSC_IN_ROT_270;
598 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 547 if (rotation & DRM_MODE_REFLECT_Y)
599 cfg &= ~GSC_IN_ROT_XFLIP; 548 cfg &= ~GSC_IN_ROT_XFLIP;
600 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 549 if (rotation & DRM_MODE_REFLECT_X)
601 cfg &= ~GSC_IN_ROT_YFLIP; 550 cfg &= ~GSC_IN_ROT_YFLIP;
602 break; 551 break;
603 default:
604 dev_err(ippdrv->dev, "invalid degree value %d.\n", degree);
605 return -EINVAL;
606 } 552 }
607 553
608 gsc_write(cfg, GSC_IN_CON); 554 gsc_write(cfg, GSC_IN_CON);
609 555
610 ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0; 556 ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0;
611 *swap = ctx->rotation;
612
613 return 0;
614} 557}
615 558
616static int gsc_src_set_size(struct device *dev, int swap, 559static void gsc_src_set_size(struct gsc_context *ctx,
617 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz) 560 struct exynos_drm_ipp_buffer *buf)
618{ 561{
619 struct gsc_context *ctx = get_gsc_context(dev);
620 struct drm_exynos_pos img_pos = *pos;
621 struct gsc_scaler *sc = &ctx->sc; 562 struct gsc_scaler *sc = &ctx->sc;
622 u32 cfg; 563 u32 cfg;
623 564
624 DRM_DEBUG_KMS("swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
625 swap, pos->x, pos->y, pos->w, pos->h);
626
627 if (swap) {
628 img_pos.w = pos->h;
629 img_pos.h = pos->w;
630 }
631
632 /* pixel offset */ 565 /* pixel offset */
633 cfg = (GSC_SRCIMG_OFFSET_X(img_pos.x) | 566 cfg = (GSC_SRCIMG_OFFSET_X(buf->rect.x) |
634 GSC_SRCIMG_OFFSET_Y(img_pos.y)); 567 GSC_SRCIMG_OFFSET_Y(buf->rect.y));
635 gsc_write(cfg, GSC_SRCIMG_OFFSET); 568 gsc_write(cfg, GSC_SRCIMG_OFFSET);
636 569
637 /* cropped size */ 570 /* cropped size */
638 cfg = (GSC_CROPPED_WIDTH(img_pos.w) | 571 cfg = (GSC_CROPPED_WIDTH(buf->rect.w) |
639 GSC_CROPPED_HEIGHT(img_pos.h)); 572 GSC_CROPPED_HEIGHT(buf->rect.h));
640 gsc_write(cfg, GSC_CROPPED_SIZE); 573 gsc_write(cfg, GSC_CROPPED_SIZE);
641 574
642 DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", sz->hsize, sz->vsize);
643
644 /* original size */ 575 /* original size */
645 cfg = gsc_read(GSC_SRCIMG_SIZE); 576 cfg = gsc_read(GSC_SRCIMG_SIZE);
646 cfg &= ~(GSC_SRCIMG_HEIGHT_MASK | 577 cfg &= ~(GSC_SRCIMG_HEIGHT_MASK |
647 GSC_SRCIMG_WIDTH_MASK); 578 GSC_SRCIMG_WIDTH_MASK);
648 579
649 cfg |= (GSC_SRCIMG_WIDTH(sz->hsize) | 580 cfg |= (GSC_SRCIMG_WIDTH(buf->buf.width) |
650 GSC_SRCIMG_HEIGHT(sz->vsize)); 581 GSC_SRCIMG_HEIGHT(buf->buf.height));
651 582
652 gsc_write(cfg, GSC_SRCIMG_SIZE); 583 gsc_write(cfg, GSC_SRCIMG_SIZE);
653 584
654 cfg = gsc_read(GSC_IN_CON); 585 cfg = gsc_read(GSC_IN_CON);
655 cfg &= ~GSC_IN_RGB_TYPE_MASK; 586 cfg &= ~GSC_IN_RGB_TYPE_MASK;
656 587
657 DRM_DEBUG_KMS("width[%d]range[%d]\n", pos->w, sc->range); 588 if (buf->rect.w >= GSC_WIDTH_ITU_709)
658
659 if (pos->w >= GSC_WIDTH_ITU_709)
660 if (sc->range) 589 if (sc->range)
661 cfg |= GSC_IN_RGB_HD_WIDE; 590 cfg |= GSC_IN_RGB_HD_WIDE;
662 else 591 else
@@ -668,103 +597,39 @@ static int gsc_src_set_size(struct device *dev, int swap,
668 cfg |= GSC_IN_RGB_SD_NARROW; 597 cfg |= GSC_IN_RGB_SD_NARROW;
669 598
670 gsc_write(cfg, GSC_IN_CON); 599 gsc_write(cfg, GSC_IN_CON);
671
672 return 0;
673} 600}
674 601
675static int gsc_src_set_buf_seq(struct gsc_context *ctx, u32 buf_id, 602static void gsc_src_set_buf_seq(struct gsc_context *ctx, u32 buf_id,
676 enum drm_exynos_ipp_buf_type buf_type) 603 bool enqueue)
677{ 604{
678 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 605 bool masked = !enqueue;
679 bool masked;
680 u32 cfg; 606 u32 cfg;
681 u32 mask = 0x00000001 << buf_id; 607 u32 mask = 0x00000001 << buf_id;
682 608
683 DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
684
685 /* mask register set */ 609 /* mask register set */
686 cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK); 610 cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK);
687 611
688 switch (buf_type) {
689 case IPP_BUF_ENQUEUE:
690 masked = false;
691 break;
692 case IPP_BUF_DEQUEUE:
693 masked = true;
694 break;
695 default:
696 dev_err(ippdrv->dev, "invalid buf ctrl parameter.\n");
697 return -EINVAL;
698 }
699
700 /* sequence id */ 612 /* sequence id */
701 cfg &= ~mask; 613 cfg &= ~mask;
702 cfg |= masked << buf_id; 614 cfg |= masked << buf_id;
703 gsc_write(cfg, GSC_IN_BASE_ADDR_Y_MASK); 615 gsc_write(cfg, GSC_IN_BASE_ADDR_Y_MASK);
704 gsc_write(cfg, GSC_IN_BASE_ADDR_CB_MASK); 616 gsc_write(cfg, GSC_IN_BASE_ADDR_CB_MASK);
705 gsc_write(cfg, GSC_IN_BASE_ADDR_CR_MASK); 617 gsc_write(cfg, GSC_IN_BASE_ADDR_CR_MASK);
706
707 return 0;
708} 618}
709 619
710static int gsc_src_set_addr(struct device *dev, 620static void gsc_src_set_addr(struct gsc_context *ctx, u32 buf_id,
711 struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id, 621 struct exynos_drm_ipp_buffer *buf)
712 enum drm_exynos_ipp_buf_type buf_type)
713{ 622{
714 struct gsc_context *ctx = get_gsc_context(dev);
715 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
716 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
717 struct drm_exynos_ipp_property *property;
718
719 if (!c_node) {
720 DRM_ERROR("failed to get c_node.\n");
721 return -EFAULT;
722 }
723
724 property = &c_node->property;
725
726 DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
727 property->prop_id, buf_id, buf_type);
728
729 if (buf_id > GSC_MAX_SRC) {
730 dev_info(ippdrv->dev, "invalid buf_id %d.\n", buf_id);
731 return -EINVAL;
732 }
733
734 /* address register set */ 623 /* address register set */
735 switch (buf_type) { 624 gsc_write(buf->dma_addr[0], GSC_IN_BASE_ADDR_Y(buf_id));
736 case IPP_BUF_ENQUEUE: 625 gsc_write(buf->dma_addr[1], GSC_IN_BASE_ADDR_CB(buf_id));
737 gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y], 626 gsc_write(buf->dma_addr[2], GSC_IN_BASE_ADDR_CR(buf_id));
738 GSC_IN_BASE_ADDR_Y(buf_id));
739 gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
740 GSC_IN_BASE_ADDR_CB(buf_id));
741 gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
742 GSC_IN_BASE_ADDR_CR(buf_id));
743 break;
744 case IPP_BUF_DEQUEUE:
745 gsc_write(0x0, GSC_IN_BASE_ADDR_Y(buf_id));
746 gsc_write(0x0, GSC_IN_BASE_ADDR_CB(buf_id));
747 gsc_write(0x0, GSC_IN_BASE_ADDR_CR(buf_id));
748 break;
749 default:
750 /* bypass */
751 break;
752 }
753 627
754 return gsc_src_set_buf_seq(ctx, buf_id, buf_type); 628 gsc_src_set_buf_seq(ctx, buf_id, true);
755} 629}
756 630
757static struct exynos_drm_ipp_ops gsc_src_ops = { 631static void gsc_dst_set_fmt(struct gsc_context *ctx, u32 fmt)
758 .set_fmt = gsc_src_set_fmt,
759 .set_transf = gsc_src_set_transf,
760 .set_size = gsc_src_set_size,
761 .set_addr = gsc_src_set_addr,
762};
763
764static int gsc_dst_set_fmt(struct device *dev, u32 fmt)
765{ 632{
766 struct gsc_context *ctx = get_gsc_context(dev);
767 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
768 u32 cfg; 633 u32 cfg;
769 634
770 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 635 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
@@ -779,8 +644,9 @@ static int gsc_dst_set_fmt(struct device *dev, u32 fmt)
779 case DRM_FORMAT_RGB565: 644 case DRM_FORMAT_RGB565:
780 cfg |= GSC_OUT_RGB565; 645 cfg |= GSC_OUT_RGB565;
781 break; 646 break;
647 case DRM_FORMAT_ARGB8888:
782 case DRM_FORMAT_XRGB8888: 648 case DRM_FORMAT_XRGB8888:
783 cfg |= GSC_OUT_XRGB8888; 649 cfg |= (GSC_OUT_XRGB8888 | GSC_OUT_GLOBAL_ALPHA(0xff));
784 break; 650 break;
785 case DRM_FORMAT_BGRX8888: 651 case DRM_FORMAT_BGRX8888:
786 cfg |= (GSC_OUT_XRGB8888 | GSC_OUT_RB_SWAP); 652 cfg |= (GSC_OUT_XRGB8888 | GSC_OUT_RB_SWAP);
@@ -819,69 +685,9 @@ static int gsc_dst_set_fmt(struct device *dev, u32 fmt)
819 cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | 685 cfg |= (GSC_OUT_CHROMA_ORDER_CBCR |
820 GSC_OUT_YUV420_2P); 686 GSC_OUT_YUV420_2P);
821 break; 687 break;
822 default:
823 dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt);
824 return -EINVAL;
825 } 688 }
826 689
827 gsc_write(cfg, GSC_OUT_CON); 690 gsc_write(cfg, GSC_OUT_CON);
828
829 return 0;
830}
831
832static int gsc_dst_set_transf(struct device *dev,
833 enum drm_exynos_degree degree,
834 enum drm_exynos_flip flip, bool *swap)
835{
836 struct gsc_context *ctx = get_gsc_context(dev);
837 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
838 u32 cfg;
839
840 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
841
842 cfg = gsc_read(GSC_IN_CON);
843 cfg &= ~GSC_IN_ROT_MASK;
844
845 switch (degree) {
846 case EXYNOS_DRM_DEGREE_0:
847 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
848 cfg |= GSC_IN_ROT_XFLIP;
849 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
850 cfg |= GSC_IN_ROT_YFLIP;
851 break;
852 case EXYNOS_DRM_DEGREE_90:
853 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
854 cfg |= GSC_IN_ROT_90_XFLIP;
855 else if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
856 cfg |= GSC_IN_ROT_90_YFLIP;
857 else
858 cfg |= GSC_IN_ROT_90;
859 break;
860 case EXYNOS_DRM_DEGREE_180:
861 cfg |= GSC_IN_ROT_180;
862 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
863 cfg &= ~GSC_IN_ROT_XFLIP;
864 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
865 cfg &= ~GSC_IN_ROT_YFLIP;
866 break;
867 case EXYNOS_DRM_DEGREE_270:
868 cfg |= GSC_IN_ROT_270;
869 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
870 cfg &= ~GSC_IN_ROT_XFLIP;
871 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
872 cfg &= ~GSC_IN_ROT_YFLIP;
873 break;
874 default:
875 dev_err(ippdrv->dev, "invalid degree value %d.\n", degree);
876 return -EINVAL;
877 }
878
879 gsc_write(cfg, GSC_IN_CON);
880
881 ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0;
882 *swap = ctx->rotation;
883
884 return 0;
885} 691}
886 692
887static int gsc_get_ratio_shift(u32 src, u32 dst, u32 *ratio) 693static int gsc_get_ratio_shift(u32 src, u32 dst, u32 *ratio)
@@ -919,9 +725,9 @@ static void gsc_get_prescaler_shfactor(u32 hratio, u32 vratio, u32 *shfactor)
919} 725}
920 726
921static int gsc_set_prescaler(struct gsc_context *ctx, struct gsc_scaler *sc, 727static int gsc_set_prescaler(struct gsc_context *ctx, struct gsc_scaler *sc,
922 struct drm_exynos_pos *src, struct drm_exynos_pos *dst) 728 struct drm_exynos_ipp_task_rect *src,
729 struct drm_exynos_ipp_task_rect *dst)
923{ 730{
924 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
925 u32 cfg; 731 u32 cfg;
926 u32 src_w, src_h, dst_w, dst_h; 732 u32 src_w, src_h, dst_w, dst_h;
927 int ret = 0; 733 int ret = 0;
@@ -939,13 +745,13 @@ static int gsc_set_prescaler(struct gsc_context *ctx, struct gsc_scaler *sc,
939 745
940 ret = gsc_get_ratio_shift(src_w, dst_w, &sc->pre_hratio); 746 ret = gsc_get_ratio_shift(src_w, dst_w, &sc->pre_hratio);
941 if (ret) { 747 if (ret) {
942 dev_err(ippdrv->dev, "failed to get ratio horizontal.\n"); 748 dev_err(ctx->dev, "failed to get ratio horizontal.\n");
943 return ret; 749 return ret;
944 } 750 }
945 751
946 ret = gsc_get_ratio_shift(src_h, dst_h, &sc->pre_vratio); 752 ret = gsc_get_ratio_shift(src_h, dst_h, &sc->pre_vratio);
947 if (ret) { 753 if (ret) {
948 dev_err(ippdrv->dev, "failed to get ratio vertical.\n"); 754 dev_err(ctx->dev, "failed to get ratio vertical.\n");
949 return ret; 755 return ret;
950 } 756 }
951 757
@@ -1039,47 +845,37 @@ static void gsc_set_scaler(struct gsc_context *ctx, struct gsc_scaler *sc)
1039 gsc_write(cfg, GSC_MAIN_V_RATIO); 845 gsc_write(cfg, GSC_MAIN_V_RATIO);
1040} 846}
1041 847
1042static int gsc_dst_set_size(struct device *dev, int swap, 848static void gsc_dst_set_size(struct gsc_context *ctx,
1043 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz) 849 struct exynos_drm_ipp_buffer *buf)
1044{ 850{
1045 struct gsc_context *ctx = get_gsc_context(dev);
1046 struct drm_exynos_pos img_pos = *pos;
1047 struct gsc_scaler *sc = &ctx->sc; 851 struct gsc_scaler *sc = &ctx->sc;
1048 u32 cfg; 852 u32 cfg;
1049 853
1050 DRM_DEBUG_KMS("swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
1051 swap, pos->x, pos->y, pos->w, pos->h);
1052
1053 if (swap) {
1054 img_pos.w = pos->h;
1055 img_pos.h = pos->w;
1056 }
1057
1058 /* pixel offset */ 854 /* pixel offset */
1059 cfg = (GSC_DSTIMG_OFFSET_X(pos->x) | 855 cfg = (GSC_DSTIMG_OFFSET_X(buf->rect.x) |
1060 GSC_DSTIMG_OFFSET_Y(pos->y)); 856 GSC_DSTIMG_OFFSET_Y(buf->rect.y));
1061 gsc_write(cfg, GSC_DSTIMG_OFFSET); 857 gsc_write(cfg, GSC_DSTIMG_OFFSET);
1062 858
1063 /* scaled size */ 859 /* scaled size */
1064 cfg = (GSC_SCALED_WIDTH(img_pos.w) | GSC_SCALED_HEIGHT(img_pos.h)); 860 if (ctx->rotation)
861 cfg = (GSC_SCALED_WIDTH(buf->rect.h) |
862 GSC_SCALED_HEIGHT(buf->rect.w));
863 else
864 cfg = (GSC_SCALED_WIDTH(buf->rect.w) |
865 GSC_SCALED_HEIGHT(buf->rect.h));
1065 gsc_write(cfg, GSC_SCALED_SIZE); 866 gsc_write(cfg, GSC_SCALED_SIZE);
1066 867
1067 DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", sz->hsize, sz->vsize);
1068
1069 /* original size */ 868 /* original size */
1070 cfg = gsc_read(GSC_DSTIMG_SIZE); 869 cfg = gsc_read(GSC_DSTIMG_SIZE);
1071 cfg &= ~(GSC_DSTIMG_HEIGHT_MASK | 870 cfg &= ~(GSC_DSTIMG_HEIGHT_MASK | GSC_DSTIMG_WIDTH_MASK);
1072 GSC_DSTIMG_WIDTH_MASK); 871 cfg |= GSC_DSTIMG_WIDTH(buf->buf.width) |
1073 cfg |= (GSC_DSTIMG_WIDTH(sz->hsize) | 872 GSC_DSTIMG_HEIGHT(buf->buf.height);
1074 GSC_DSTIMG_HEIGHT(sz->vsize));
1075 gsc_write(cfg, GSC_DSTIMG_SIZE); 873 gsc_write(cfg, GSC_DSTIMG_SIZE);
1076 874
1077 cfg = gsc_read(GSC_OUT_CON); 875 cfg = gsc_read(GSC_OUT_CON);
1078 cfg &= ~GSC_OUT_RGB_TYPE_MASK; 876 cfg &= ~GSC_OUT_RGB_TYPE_MASK;
1079 877
1080 DRM_DEBUG_KMS("width[%d]range[%d]\n", pos->w, sc->range); 878 if (buf->rect.w >= GSC_WIDTH_ITU_709)
1081
1082 if (pos->w >= GSC_WIDTH_ITU_709)
1083 if (sc->range) 879 if (sc->range)
1084 cfg |= GSC_OUT_RGB_HD_WIDE; 880 cfg |= GSC_OUT_RGB_HD_WIDE;
1085 else 881 else
@@ -1091,8 +887,6 @@ static int gsc_dst_set_size(struct device *dev, int swap,
1091 cfg |= GSC_OUT_RGB_SD_NARROW; 887 cfg |= GSC_OUT_RGB_SD_NARROW;
1092 888
1093 gsc_write(cfg, GSC_OUT_CON); 889 gsc_write(cfg, GSC_OUT_CON);
1094
1095 return 0;
1096} 890}
1097 891
1098static int gsc_dst_get_buf_seq(struct gsc_context *ctx) 892static int gsc_dst_get_buf_seq(struct gsc_context *ctx)
@@ -1111,35 +905,16 @@ static int gsc_dst_get_buf_seq(struct gsc_context *ctx)
1111 return buf_num; 905 return buf_num;
1112} 906}
1113 907
1114static int gsc_dst_set_buf_seq(struct gsc_context *ctx, u32 buf_id, 908static void gsc_dst_set_buf_seq(struct gsc_context *ctx, u32 buf_id,
1115 enum drm_exynos_ipp_buf_type buf_type) 909 bool enqueue)
1116{ 910{
1117 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 911 bool masked = !enqueue;
1118 bool masked;
1119 u32 cfg; 912 u32 cfg;
1120 u32 mask = 0x00000001 << buf_id; 913 u32 mask = 0x00000001 << buf_id;
1121 int ret = 0;
1122
1123 DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
1124
1125 mutex_lock(&ctx->lock);
1126 914
1127 /* mask register set */ 915 /* mask register set */
1128 cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK); 916 cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK);
1129 917
1130 switch (buf_type) {
1131 case IPP_BUF_ENQUEUE:
1132 masked = false;
1133 break;
1134 case IPP_BUF_DEQUEUE:
1135 masked = true;
1136 break;
1137 default:
1138 dev_err(ippdrv->dev, "invalid buf ctrl parameter.\n");
1139 ret = -EINVAL;
1140 goto err_unlock;
1141 }
1142
1143 /* sequence id */ 918 /* sequence id */
1144 cfg &= ~mask; 919 cfg &= ~mask;
1145 cfg |= masked << buf_id; 920 cfg |= masked << buf_id;
@@ -1148,94 +923,29 @@ static int gsc_dst_set_buf_seq(struct gsc_context *ctx, u32 buf_id,
1148 gsc_write(cfg, GSC_OUT_BASE_ADDR_CR_MASK); 923 gsc_write(cfg, GSC_OUT_BASE_ADDR_CR_MASK);
1149 924
1150 /* interrupt enable */ 925 /* interrupt enable */
1151 if (buf_type == IPP_BUF_ENQUEUE && 926 if (enqueue && gsc_dst_get_buf_seq(ctx) >= GSC_BUF_START)
1152 gsc_dst_get_buf_seq(ctx) >= GSC_BUF_START)
1153 gsc_handle_irq(ctx, true, false, true); 927 gsc_handle_irq(ctx, true, false, true);
1154 928
1155 /* interrupt disable */ 929 /* interrupt disable */
1156 if (buf_type == IPP_BUF_DEQUEUE && 930 if (!enqueue && gsc_dst_get_buf_seq(ctx) <= GSC_BUF_STOP)
1157 gsc_dst_get_buf_seq(ctx) <= GSC_BUF_STOP)
1158 gsc_handle_irq(ctx, false, false, true); 931 gsc_handle_irq(ctx, false, false, true);
1159
1160err_unlock:
1161 mutex_unlock(&ctx->lock);
1162 return ret;
1163} 932}
1164 933
1165static int gsc_dst_set_addr(struct device *dev, 934static void gsc_dst_set_addr(struct gsc_context *ctx,
1166 struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id, 935 u32 buf_id, struct exynos_drm_ipp_buffer *buf)
1167 enum drm_exynos_ipp_buf_type buf_type)
1168{ 936{
1169 struct gsc_context *ctx = get_gsc_context(dev);
1170 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1171 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
1172 struct drm_exynos_ipp_property *property;
1173
1174 if (!c_node) {
1175 DRM_ERROR("failed to get c_node.\n");
1176 return -EFAULT;
1177 }
1178
1179 property = &c_node->property;
1180
1181 DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
1182 property->prop_id, buf_id, buf_type);
1183
1184 if (buf_id > GSC_MAX_DST) {
1185 dev_info(ippdrv->dev, "invalid buf_id %d.\n", buf_id);
1186 return -EINVAL;
1187 }
1188
1189 /* address register set */ 937 /* address register set */
1190 switch (buf_type) { 938 gsc_write(buf->dma_addr[0], GSC_OUT_BASE_ADDR_Y(buf_id));
1191 case IPP_BUF_ENQUEUE: 939 gsc_write(buf->dma_addr[1], GSC_OUT_BASE_ADDR_CB(buf_id));
1192 gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y], 940 gsc_write(buf->dma_addr[2], GSC_OUT_BASE_ADDR_CR(buf_id));
1193 GSC_OUT_BASE_ADDR_Y(buf_id));
1194 gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
1195 GSC_OUT_BASE_ADDR_CB(buf_id));
1196 gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
1197 GSC_OUT_BASE_ADDR_CR(buf_id));
1198 break;
1199 case IPP_BUF_DEQUEUE:
1200 gsc_write(0x0, GSC_OUT_BASE_ADDR_Y(buf_id));
1201 gsc_write(0x0, GSC_OUT_BASE_ADDR_CB(buf_id));
1202 gsc_write(0x0, GSC_OUT_BASE_ADDR_CR(buf_id));
1203 break;
1204 default:
1205 /* bypass */
1206 break;
1207 }
1208 941
1209 return gsc_dst_set_buf_seq(ctx, buf_id, buf_type); 942 gsc_dst_set_buf_seq(ctx, buf_id, true);
1210}
1211
1212static struct exynos_drm_ipp_ops gsc_dst_ops = {
1213 .set_fmt = gsc_dst_set_fmt,
1214 .set_transf = gsc_dst_set_transf,
1215 .set_size = gsc_dst_set_size,
1216 .set_addr = gsc_dst_set_addr,
1217};
1218
1219static int gsc_clk_ctrl(struct gsc_context *ctx, bool enable)
1220{
1221 DRM_DEBUG_KMS("enable[%d]\n", enable);
1222
1223 if (enable) {
1224 clk_prepare_enable(ctx->gsc_clk);
1225 ctx->suspended = false;
1226 } else {
1227 clk_disable_unprepare(ctx->gsc_clk);
1228 ctx->suspended = true;
1229 }
1230
1231 return 0;
1232} 943}
1233 944
1234static int gsc_get_src_buf_index(struct gsc_context *ctx) 945static int gsc_get_src_buf_index(struct gsc_context *ctx)
1235{ 946{
1236 u32 cfg, curr_index, i; 947 u32 cfg, curr_index, i;
1237 u32 buf_id = GSC_MAX_SRC; 948 u32 buf_id = GSC_MAX_SRC;
1238 int ret;
1239 949
1240 DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id); 950 DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id);
1241 951
@@ -1249,19 +959,15 @@ static int gsc_get_src_buf_index(struct gsc_context *ctx)
1249 } 959 }
1250 } 960 }
1251 961
962 DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg,
963 curr_index, buf_id);
964
1252 if (buf_id == GSC_MAX_SRC) { 965 if (buf_id == GSC_MAX_SRC) {
1253 DRM_ERROR("failed to get in buffer index.\n"); 966 DRM_ERROR("failed to get in buffer index.\n");
1254 return -EINVAL; 967 return -EINVAL;
1255 } 968 }
1256 969
1257 ret = gsc_src_set_buf_seq(ctx, buf_id, IPP_BUF_DEQUEUE); 970 gsc_src_set_buf_seq(ctx, buf_id, false);
1258 if (ret < 0) {
1259 DRM_ERROR("failed to dequeue.\n");
1260 return ret;
1261 }
1262
1263 DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg,
1264 curr_index, buf_id);
1265 971
1266 return buf_id; 972 return buf_id;
1267} 973}
@@ -1270,7 +976,6 @@ static int gsc_get_dst_buf_index(struct gsc_context *ctx)
1270{ 976{
1271 u32 cfg, curr_index, i; 977 u32 cfg, curr_index, i;
1272 u32 buf_id = GSC_MAX_DST; 978 u32 buf_id = GSC_MAX_DST;
1273 int ret;
1274 979
1275 DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id); 980 DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id);
1276 981
@@ -1289,11 +994,7 @@ static int gsc_get_dst_buf_index(struct gsc_context *ctx)
1289 return -EINVAL; 994 return -EINVAL;
1290 } 995 }
1291 996
1292 ret = gsc_dst_set_buf_seq(ctx, buf_id, IPP_BUF_DEQUEUE); 997 gsc_dst_set_buf_seq(ctx, buf_id, false);
1293 if (ret < 0) {
1294 DRM_ERROR("failed to dequeue.\n");
1295 return ret;
1296 }
1297 998
1298 DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg, 999 DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg,
1299 curr_index, buf_id); 1000 curr_index, buf_id);
@@ -1304,215 +1005,55 @@ static int gsc_get_dst_buf_index(struct gsc_context *ctx)
1304static irqreturn_t gsc_irq_handler(int irq, void *dev_id) 1005static irqreturn_t gsc_irq_handler(int irq, void *dev_id)
1305{ 1006{
1306 struct gsc_context *ctx = dev_id; 1007 struct gsc_context *ctx = dev_id;
1307 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1308 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
1309 struct drm_exynos_ipp_event_work *event_work =
1310 c_node->event_work;
1311 u32 status; 1008 u32 status;
1312 int buf_id[EXYNOS_DRM_OPS_MAX]; 1009 int err = 0;
1313 1010
1314 DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id); 1011 DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id);
1315 1012
1316 status = gsc_read(GSC_IRQ); 1013 status = gsc_read(GSC_IRQ);
1317 if (status & GSC_IRQ_STATUS_OR_IRQ) { 1014 if (status & GSC_IRQ_STATUS_OR_IRQ) {
1318 dev_err(ippdrv->dev, "occurred overflow at %d, status 0x%x.\n", 1015 dev_err(ctx->dev, "occurred overflow at %d, status 0x%x.\n",
1319 ctx->id, status); 1016 ctx->id, status);
1320 return IRQ_NONE; 1017 err = -EINVAL;
1321 } 1018 }
1322 1019
1323 if (status & GSC_IRQ_STATUS_OR_FRM_DONE) { 1020 if (status & GSC_IRQ_STATUS_OR_FRM_DONE) {
1324 dev_dbg(ippdrv->dev, "occurred frame done at %d, status 0x%x.\n", 1021 int src_buf_id, dst_buf_id;
1325 ctx->id, status);
1326
1327 buf_id[EXYNOS_DRM_OPS_SRC] = gsc_get_src_buf_index(ctx);
1328 if (buf_id[EXYNOS_DRM_OPS_SRC] < 0)
1329 return IRQ_HANDLED;
1330
1331 buf_id[EXYNOS_DRM_OPS_DST] = gsc_get_dst_buf_index(ctx);
1332 if (buf_id[EXYNOS_DRM_OPS_DST] < 0)
1333 return IRQ_HANDLED;
1334
1335 DRM_DEBUG_KMS("buf_id_src[%d]buf_id_dst[%d]\n",
1336 buf_id[EXYNOS_DRM_OPS_SRC], buf_id[EXYNOS_DRM_OPS_DST]);
1337
1338 event_work->ippdrv = ippdrv;
1339 event_work->buf_id[EXYNOS_DRM_OPS_SRC] =
1340 buf_id[EXYNOS_DRM_OPS_SRC];
1341 event_work->buf_id[EXYNOS_DRM_OPS_DST] =
1342 buf_id[EXYNOS_DRM_OPS_DST];
1343 queue_work(ippdrv->event_workq, &event_work->work);
1344 }
1345
1346 return IRQ_HANDLED;
1347}
1348
1349static int gsc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
1350{
1351 struct drm_exynos_ipp_prop_list *prop_list = &ippdrv->prop_list;
1352
1353 prop_list->version = 1;
1354 prop_list->writeback = 1;
1355 prop_list->refresh_min = GSC_REFRESH_MIN;
1356 prop_list->refresh_max = GSC_REFRESH_MAX;
1357 prop_list->flip = (1 << EXYNOS_DRM_FLIP_VERTICAL) |
1358 (1 << EXYNOS_DRM_FLIP_HORIZONTAL);
1359 prop_list->degree = (1 << EXYNOS_DRM_DEGREE_0) |
1360 (1 << EXYNOS_DRM_DEGREE_90) |
1361 (1 << EXYNOS_DRM_DEGREE_180) |
1362 (1 << EXYNOS_DRM_DEGREE_270);
1363 prop_list->csc = 1;
1364 prop_list->crop = 1;
1365 prop_list->crop_max.hsize = GSC_CROP_MAX;
1366 prop_list->crop_max.vsize = GSC_CROP_MAX;
1367 prop_list->crop_min.hsize = GSC_CROP_MIN;
1368 prop_list->crop_min.vsize = GSC_CROP_MIN;
1369 prop_list->scale = 1;
1370 prop_list->scale_max.hsize = GSC_SCALE_MAX;
1371 prop_list->scale_max.vsize = GSC_SCALE_MAX;
1372 prop_list->scale_min.hsize = GSC_SCALE_MIN;
1373 prop_list->scale_min.vsize = GSC_SCALE_MIN;
1374
1375 return 0;
1376}
1377
1378static inline bool gsc_check_drm_flip(enum drm_exynos_flip flip)
1379{
1380 switch (flip) {
1381 case EXYNOS_DRM_FLIP_NONE:
1382 case EXYNOS_DRM_FLIP_VERTICAL:
1383 case EXYNOS_DRM_FLIP_HORIZONTAL:
1384 case EXYNOS_DRM_FLIP_BOTH:
1385 return true;
1386 default:
1387 DRM_DEBUG_KMS("invalid flip\n");
1388 return false;
1389 }
1390}
1391
1392static int gsc_ippdrv_check_property(struct device *dev,
1393 struct drm_exynos_ipp_property *property)
1394{
1395 struct gsc_context *ctx = get_gsc_context(dev);
1396 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1397 struct drm_exynos_ipp_prop_list *pp = &ippdrv->prop_list;
1398 struct drm_exynos_ipp_config *config;
1399 struct drm_exynos_pos *pos;
1400 struct drm_exynos_sz *sz;
1401 bool swap;
1402 int i;
1403
1404 for_each_ipp_ops(i) {
1405 if ((i == EXYNOS_DRM_OPS_SRC) &&
1406 (property->cmd == IPP_CMD_WB))
1407 continue;
1408 1022
1409 config = &property->config[i]; 1023 dev_dbg(ctx->dev, "occurred frame done at %d, status 0x%x.\n",
1410 pos = &config->pos; 1024 ctx->id, status);
1411 sz = &config->sz;
1412
1413 /* check for flip */
1414 if (!gsc_check_drm_flip(config->flip)) {
1415 DRM_ERROR("invalid flip.\n");
1416 goto err_property;
1417 }
1418
1419 /* check for degree */
1420 switch (config->degree) {
1421 case EXYNOS_DRM_DEGREE_90:
1422 case EXYNOS_DRM_DEGREE_270:
1423 swap = true;
1424 break;
1425 case EXYNOS_DRM_DEGREE_0:
1426 case EXYNOS_DRM_DEGREE_180:
1427 swap = false;
1428 break;
1429 default:
1430 DRM_ERROR("invalid degree.\n");
1431 goto err_property;
1432 }
1433 1025
1434 /* check for buffer bound */ 1026 src_buf_id = gsc_get_src_buf_index(ctx);
1435 if ((pos->x + pos->w > sz->hsize) || 1027 dst_buf_id = gsc_get_dst_buf_index(ctx);
1436 (pos->y + pos->h > sz->vsize)) {
1437 DRM_ERROR("out of buf bound.\n");
1438 goto err_property;
1439 }
1440 1028
1441 /* check for crop */ 1029 DRM_DEBUG_KMS("buf_id_src[%d]buf_id_dst[%d]\n", src_buf_id,
1442 if ((i == EXYNOS_DRM_OPS_SRC) && (pp->crop)) { 1030 dst_buf_id);
1443 if (swap) {
1444 if ((pos->h < pp->crop_min.hsize) ||
1445 (sz->vsize > pp->crop_max.hsize) ||
1446 (pos->w < pp->crop_min.vsize) ||
1447 (sz->hsize > pp->crop_max.vsize)) {
1448 DRM_ERROR("out of crop size.\n");
1449 goto err_property;
1450 }
1451 } else {
1452 if ((pos->w < pp->crop_min.hsize) ||
1453 (sz->hsize > pp->crop_max.hsize) ||
1454 (pos->h < pp->crop_min.vsize) ||
1455 (sz->vsize > pp->crop_max.vsize)) {
1456 DRM_ERROR("out of crop size.\n");
1457 goto err_property;
1458 }
1459 }
1460 }
1461 1031
1462 /* check for scale */ 1032 if (src_buf_id < 0 || dst_buf_id < 0)
1463 if ((i == EXYNOS_DRM_OPS_DST) && (pp->scale)) { 1033 err = -EINVAL;
1464 if (swap) {
1465 if ((pos->h < pp->scale_min.hsize) ||
1466 (sz->vsize > pp->scale_max.hsize) ||
1467 (pos->w < pp->scale_min.vsize) ||
1468 (sz->hsize > pp->scale_max.vsize)) {
1469 DRM_ERROR("out of scale size.\n");
1470 goto err_property;
1471 }
1472 } else {
1473 if ((pos->w < pp->scale_min.hsize) ||
1474 (sz->hsize > pp->scale_max.hsize) ||
1475 (pos->h < pp->scale_min.vsize) ||
1476 (sz->vsize > pp->scale_max.vsize)) {
1477 DRM_ERROR("out of scale size.\n");
1478 goto err_property;
1479 }
1480 }
1481 }
1482 } 1034 }
1483 1035
1484 return 0; 1036 if (ctx->task) {
1485 1037 struct exynos_drm_ipp_task *task = ctx->task;
1486err_property:
1487 for_each_ipp_ops(i) {
1488 if ((i == EXYNOS_DRM_OPS_SRC) &&
1489 (property->cmd == IPP_CMD_WB))
1490 continue;
1491 1038
1492 config = &property->config[i]; 1039 ctx->task = NULL;
1493 pos = &config->pos; 1040 pm_runtime_mark_last_busy(ctx->dev);
1494 sz = &config->sz; 1041 pm_runtime_put_autosuspend(ctx->dev);
1495 1042 exynos_drm_ipp_task_done(task, err);
1496 DRM_ERROR("[%s]f[%d]r[%d]pos[%d %d %d %d]sz[%d %d]\n",
1497 i ? "dst" : "src", config->flip, config->degree,
1498 pos->x, pos->y, pos->w, pos->h,
1499 sz->hsize, sz->vsize);
1500 } 1043 }
1501 1044
1502 return -EINVAL; 1045 return IRQ_HANDLED;
1503} 1046}
1504 1047
1505 1048static int gsc_reset(struct gsc_context *ctx)
1506static int gsc_ippdrv_reset(struct device *dev)
1507{ 1049{
1508 struct gsc_context *ctx = get_gsc_context(dev);
1509 struct gsc_scaler *sc = &ctx->sc; 1050 struct gsc_scaler *sc = &ctx->sc;
1510 int ret; 1051 int ret;
1511 1052
1512 /* reset h/w block */ 1053 /* reset h/w block */
1513 ret = gsc_sw_reset(ctx); 1054 ret = gsc_sw_reset(ctx);
1514 if (ret < 0) { 1055 if (ret < 0) {
1515 dev_err(dev, "failed to reset hardware.\n"); 1056 dev_err(ctx->dev, "failed to reset hardware.\n");
1516 return ret; 1057 return ret;
1517 } 1058 }
1518 1059
@@ -1523,166 +1064,172 @@ static int gsc_ippdrv_reset(struct device *dev)
1523 return 0; 1064 return 0;
1524} 1065}
1525 1066
1526static int gsc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) 1067static void gsc_start(struct gsc_context *ctx)
1527{ 1068{
1528 struct gsc_context *ctx = get_gsc_context(dev);
1529 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1530 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
1531 struct drm_exynos_ipp_property *property;
1532 struct drm_exynos_ipp_config *config;
1533 struct drm_exynos_pos img_pos[EXYNOS_DRM_OPS_MAX];
1534 struct drm_exynos_ipp_set_wb set_wb;
1535 u32 cfg; 1069 u32 cfg;
1536 int ret, i;
1537
1538 DRM_DEBUG_KMS("cmd[%d]\n", cmd);
1539
1540 if (!c_node) {
1541 DRM_ERROR("failed to get c_node.\n");
1542 return -EINVAL;
1543 }
1544
1545 property = &c_node->property;
1546 1070
1547 gsc_handle_irq(ctx, true, false, true); 1071 gsc_handle_irq(ctx, true, false, true);
1548 1072
1549 for_each_ipp_ops(i) { 1073 /* enable one shot */
1550 config = &property->config[i]; 1074 cfg = gsc_read(GSC_ENABLE);
1551 img_pos[i] = config->pos; 1075 cfg &= ~(GSC_ENABLE_ON_CLEAR_MASK |
1552 } 1076 GSC_ENABLE_CLK_GATE_MODE_MASK);
1077 cfg |= GSC_ENABLE_ON_CLEAR_ONESHOT;
1078 gsc_write(cfg, GSC_ENABLE);
1553 1079
1554 switch (cmd) { 1080 /* src dma memory */
1555 case IPP_CMD_M2M: 1081 cfg = gsc_read(GSC_IN_CON);
1556 /* enable one shot */ 1082 cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK);
1557 cfg = gsc_read(GSC_ENABLE); 1083 cfg |= GSC_IN_PATH_MEMORY;
1558 cfg &= ~(GSC_ENABLE_ON_CLEAR_MASK | 1084 gsc_write(cfg, GSC_IN_CON);
1559 GSC_ENABLE_CLK_GATE_MODE_MASK);
1560 cfg |= GSC_ENABLE_ON_CLEAR_ONESHOT;
1561 gsc_write(cfg, GSC_ENABLE);
1562
1563 /* src dma memory */
1564 cfg = gsc_read(GSC_IN_CON);
1565 cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK);
1566 cfg |= GSC_IN_PATH_MEMORY;
1567 gsc_write(cfg, GSC_IN_CON);
1568
1569 /* dst dma memory */
1570 cfg = gsc_read(GSC_OUT_CON);
1571 cfg |= GSC_OUT_PATH_MEMORY;
1572 gsc_write(cfg, GSC_OUT_CON);
1573 break;
1574 case IPP_CMD_WB:
1575 set_wb.enable = 1;
1576 set_wb.refresh = property->refresh_rate;
1577 gsc_set_gscblk_fimd_wb(ctx, set_wb.enable);
1578 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb);
1579
1580 /* src local path */
1581 cfg = gsc_read(GSC_IN_CON);
1582 cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK);
1583 cfg |= (GSC_IN_PATH_LOCAL | GSC_IN_LOCAL_FIMD_WB);
1584 gsc_write(cfg, GSC_IN_CON);
1585
1586 /* dst dma memory */
1587 cfg = gsc_read(GSC_OUT_CON);
1588 cfg |= GSC_OUT_PATH_MEMORY;
1589 gsc_write(cfg, GSC_OUT_CON);
1590 break;
1591 case IPP_CMD_OUTPUT:
1592 /* src dma memory */
1593 cfg = gsc_read(GSC_IN_CON);
1594 cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK);
1595 cfg |= GSC_IN_PATH_MEMORY;
1596 gsc_write(cfg, GSC_IN_CON);
1597
1598 /* dst local path */
1599 cfg = gsc_read(GSC_OUT_CON);
1600 cfg |= GSC_OUT_PATH_MEMORY;
1601 gsc_write(cfg, GSC_OUT_CON);
1602 break;
1603 default:
1604 ret = -EINVAL;
1605 dev_err(dev, "invalid operations.\n");
1606 return ret;
1607 }
1608 1085
1609 ret = gsc_set_prescaler(ctx, &ctx->sc, 1086 /* dst dma memory */
1610 &img_pos[EXYNOS_DRM_OPS_SRC], 1087 cfg = gsc_read(GSC_OUT_CON);
1611 &img_pos[EXYNOS_DRM_OPS_DST]); 1088 cfg |= GSC_OUT_PATH_MEMORY;
1612 if (ret) { 1089 gsc_write(cfg, GSC_OUT_CON);
1613 dev_err(dev, "failed to set prescaler.\n");
1614 return ret;
1615 }
1616 1090
1617 gsc_set_scaler(ctx, &ctx->sc); 1091 gsc_set_scaler(ctx, &ctx->sc);
1618 1092
1619 cfg = gsc_read(GSC_ENABLE); 1093 cfg = gsc_read(GSC_ENABLE);
1620 cfg |= GSC_ENABLE_ON; 1094 cfg |= GSC_ENABLE_ON;
1621 gsc_write(cfg, GSC_ENABLE); 1095 gsc_write(cfg, GSC_ENABLE);
1096}
1097
1098static int gsc_commit(struct exynos_drm_ipp *ipp,
1099 struct exynos_drm_ipp_task *task)
1100{
1101 struct gsc_context *ctx = container_of(ipp, struct gsc_context, ipp);
1102 int ret;
1103
1104 pm_runtime_get_sync(ctx->dev);
1105 ctx->task = task;
1106
1107 ret = gsc_reset(ctx);
1108 if (ret) {
1109 pm_runtime_put_autosuspend(ctx->dev);
1110 ctx->task = NULL;
1111 return ret;
1112 }
1113
1114 gsc_src_set_fmt(ctx, task->src.buf.fourcc);
1115 gsc_src_set_transf(ctx, task->transform.rotation);
1116 gsc_src_set_size(ctx, &task->src);
1117 gsc_src_set_addr(ctx, 0, &task->src);
1118 gsc_dst_set_fmt(ctx, task->dst.buf.fourcc);
1119 gsc_dst_set_size(ctx, &task->dst);
1120 gsc_dst_set_addr(ctx, 0, &task->dst);
1121 gsc_set_prescaler(ctx, &ctx->sc, &task->src.rect, &task->dst.rect);
1122 gsc_start(ctx);
1622 1123
1623 return 0; 1124 return 0;
1624} 1125}
1625 1126
1626static void gsc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd) 1127static void gsc_abort(struct exynos_drm_ipp *ipp,
1128 struct exynos_drm_ipp_task *task)
1627{ 1129{
1628 struct gsc_context *ctx = get_gsc_context(dev); 1130 struct gsc_context *ctx =
1629 struct drm_exynos_ipp_set_wb set_wb = {0, 0}; 1131 container_of(ipp, struct gsc_context, ipp);
1630 u32 cfg;
1631 1132
1632 DRM_DEBUG_KMS("cmd[%d]\n", cmd); 1133 gsc_reset(ctx);
1134 if (ctx->task) {
1135 struct exynos_drm_ipp_task *task = ctx->task;
1633 1136
1634 switch (cmd) { 1137 ctx->task = NULL;
1635 case IPP_CMD_M2M: 1138 pm_runtime_mark_last_busy(ctx->dev);
1636 /* bypass */ 1139 pm_runtime_put_autosuspend(ctx->dev);
1637 break; 1140 exynos_drm_ipp_task_done(task, -EIO);
1638 case IPP_CMD_WB:
1639 gsc_set_gscblk_fimd_wb(ctx, set_wb.enable);
1640 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb);
1641 break;
1642 case IPP_CMD_OUTPUT:
1643 default:
1644 dev_err(dev, "invalid operations.\n");
1645 break;
1646 } 1141 }
1142}
1647 1143
1648 gsc_handle_irq(ctx, false, false, true); 1144static struct exynos_drm_ipp_funcs ipp_funcs = {
1145 .commit = gsc_commit,
1146 .abort = gsc_abort,
1147};
1649 1148
1650 /* reset sequence */ 1149static int gsc_bind(struct device *dev, struct device *master, void *data)
1651 gsc_write(0xff, GSC_OUT_BASE_ADDR_Y_MASK); 1150{
1652 gsc_write(0xff, GSC_OUT_BASE_ADDR_CB_MASK); 1151 struct gsc_context *ctx = dev_get_drvdata(dev);
1653 gsc_write(0xff, GSC_OUT_BASE_ADDR_CR_MASK); 1152 struct drm_device *drm_dev = data;
1153 struct exynos_drm_ipp *ipp = &ctx->ipp;
1654 1154
1655 cfg = gsc_read(GSC_ENABLE); 1155 ctx->drm_dev = drm_dev;
1656 cfg &= ~GSC_ENABLE_ON; 1156 drm_iommu_attach_device(drm_dev, dev);
1657 gsc_write(cfg, GSC_ENABLE); 1157
1158 exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs,
1159 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
1160 DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT,
1161 ctx->formats, ctx->num_formats, "gsc");
1162
1163 dev_info(dev, "The exynos gscaler has been probed successfully\n");
1164
1165 return 0;
1166}
1167
1168static void gsc_unbind(struct device *dev, struct device *master,
1169 void *data)
1170{
1171 struct gsc_context *ctx = dev_get_drvdata(dev);
1172 struct drm_device *drm_dev = data;
1173 struct exynos_drm_ipp *ipp = &ctx->ipp;
1174
1175 exynos_drm_ipp_unregister(drm_dev, ipp);
1176 drm_iommu_detach_device(drm_dev, dev);
1658} 1177}
1659 1178
1179static const struct component_ops gsc_component_ops = {
1180 .bind = gsc_bind,
1181 .unbind = gsc_unbind,
1182};
1183
1184static const unsigned int gsc_formats[] = {
1185 DRM_FORMAT_ARGB8888,
1186 DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_BGRX8888,
1187 DRM_FORMAT_NV12, DRM_FORMAT_NV16, DRM_FORMAT_NV21, DRM_FORMAT_NV61,
1188 DRM_FORMAT_UYVY, DRM_FORMAT_VYUY, DRM_FORMAT_YUYV, DRM_FORMAT_YVYU,
1189 DRM_FORMAT_YUV420, DRM_FORMAT_YVU420, DRM_FORMAT_YUV422,
1190};
1191
1660static int gsc_probe(struct platform_device *pdev) 1192static int gsc_probe(struct platform_device *pdev)
1661{ 1193{
1662 struct device *dev = &pdev->dev; 1194 struct device *dev = &pdev->dev;
1195 struct gsc_driverdata *driver_data;
1196 struct exynos_drm_ipp_formats *formats;
1663 struct gsc_context *ctx; 1197 struct gsc_context *ctx;
1664 struct resource *res; 1198 struct resource *res;
1665 struct exynos_drm_ippdrv *ippdrv; 1199 int ret, i;
1666 int ret;
1667 1200
1668 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 1201 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
1669 if (!ctx) 1202 if (!ctx)
1670 return -ENOMEM; 1203 return -ENOMEM;
1671 1204
1672 if (dev->of_node) { 1205 formats = devm_kzalloc(dev, sizeof(*formats) *
1673 ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, 1206 (ARRAY_SIZE(gsc_formats)), GFP_KERNEL);
1674 "samsung,sysreg"); 1207 if (!formats)
1675 if (IS_ERR(ctx->sysreg)) { 1208 return -ENOMEM;
1676 dev_warn(dev, "failed to get system register.\n"); 1209
1677 ctx->sysreg = NULL; 1210 driver_data = (struct gsc_driverdata *)of_device_get_match_data(dev);
1678 } 1211 ctx->dev = dev;
1212 ctx->num_clocks = driver_data->num_clocks;
1213 ctx->clk_names = driver_data->clk_names;
1214
1215 for (i = 0; i < ARRAY_SIZE(gsc_formats); i++) {
1216 formats[i].fourcc = gsc_formats[i];
1217 formats[i].type = DRM_EXYNOS_IPP_FORMAT_SOURCE |
1218 DRM_EXYNOS_IPP_FORMAT_DESTINATION;
1219 formats[i].limits = driver_data->limits;
1220 formats[i].num_limits = driver_data->num_limits;
1679 } 1221 }
1222 ctx->formats = formats;
1223 ctx->num_formats = ARRAY_SIZE(gsc_formats);
1680 1224
1681 /* clock control */ 1225 /* clock control */
1682 ctx->gsc_clk = devm_clk_get(dev, "gscl"); 1226 for (i = 0; i < ctx->num_clocks; i++) {
1683 if (IS_ERR(ctx->gsc_clk)) { 1227 ctx->clocks[i] = devm_clk_get(dev, ctx->clk_names[i]);
1684 dev_err(dev, "failed to get gsc clock.\n"); 1228 if (IS_ERR(ctx->clocks[i])) {
1685 return PTR_ERR(ctx->gsc_clk); 1229 dev_err(dev, "failed to get clock: %s\n",
1230 ctx->clk_names[i]);
1231 return PTR_ERR(ctx->clocks[i]);
1232 }
1686 } 1233 }
1687 1234
1688 /* resource memory */ 1235 /* resource memory */
@@ -1699,8 +1246,8 @@ static int gsc_probe(struct platform_device *pdev)
1699 } 1246 }
1700 1247
1701 ctx->irq = res->start; 1248 ctx->irq = res->start;
1702 ret = devm_request_threaded_irq(dev, ctx->irq, NULL, gsc_irq_handler, 1249 ret = devm_request_irq(dev, ctx->irq, gsc_irq_handler, 0,
1703 IRQF_ONESHOT, "drm_gsc", ctx); 1250 dev_name(dev), ctx);
1704 if (ret < 0) { 1251 if (ret < 0) {
1705 dev_err(dev, "failed to request irq.\n"); 1252 dev_err(dev, "failed to request irq.\n");
1706 return ret; 1253 return ret;
@@ -1709,38 +1256,22 @@ static int gsc_probe(struct platform_device *pdev)
1709 /* context initailization */ 1256 /* context initailization */
1710 ctx->id = pdev->id; 1257 ctx->id = pdev->id;
1711 1258
1712 ippdrv = &ctx->ippdrv;
1713 ippdrv->dev = dev;
1714 ippdrv->ops[EXYNOS_DRM_OPS_SRC] = &gsc_src_ops;
1715 ippdrv->ops[EXYNOS_DRM_OPS_DST] = &gsc_dst_ops;
1716 ippdrv->check_property = gsc_ippdrv_check_property;
1717 ippdrv->reset = gsc_ippdrv_reset;
1718 ippdrv->start = gsc_ippdrv_start;
1719 ippdrv->stop = gsc_ippdrv_stop;
1720 ret = gsc_init_prop_list(ippdrv);
1721 if (ret < 0) {
1722 dev_err(dev, "failed to init property list.\n");
1723 return ret;
1724 }
1725
1726 DRM_DEBUG_KMS("id[%d]ippdrv[%pK]\n", ctx->id, ippdrv);
1727
1728 mutex_init(&ctx->lock);
1729 platform_set_drvdata(pdev, ctx); 1259 platform_set_drvdata(pdev, ctx);
1730 1260
1261 pm_runtime_use_autosuspend(dev);
1262 pm_runtime_set_autosuspend_delay(dev, GSC_AUTOSUSPEND_DELAY);
1731 pm_runtime_enable(dev); 1263 pm_runtime_enable(dev);
1732 1264
1733 ret = exynos_drm_ippdrv_register(ippdrv); 1265 ret = component_add(dev, &gsc_component_ops);
1734 if (ret < 0) { 1266 if (ret)
1735 dev_err(dev, "failed to register drm gsc device.\n"); 1267 goto err_pm_dis;
1736 goto err_ippdrv_register;
1737 }
1738 1268
1739 dev_info(dev, "drm gsc registered successfully.\n"); 1269 dev_info(dev, "drm gsc registered successfully.\n");
1740 1270
1741 return 0; 1271 return 0;
1742 1272
1743err_ippdrv_register: 1273err_pm_dis:
1274 pm_runtime_dont_use_autosuspend(dev);
1744 pm_runtime_disable(dev); 1275 pm_runtime_disable(dev);
1745 return ret; 1276 return ret;
1746} 1277}
@@ -1748,13 +1279,8 @@ err_ippdrv_register:
1748static int gsc_remove(struct platform_device *pdev) 1279static int gsc_remove(struct platform_device *pdev)
1749{ 1280{
1750 struct device *dev = &pdev->dev; 1281 struct device *dev = &pdev->dev;
1751 struct gsc_context *ctx = get_gsc_context(dev);
1752 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1753 1282
1754 exynos_drm_ippdrv_unregister(ippdrv); 1283 pm_runtime_dont_use_autosuspend(dev);
1755 mutex_destroy(&ctx->lock);
1756
1757 pm_runtime_set_suspended(dev);
1758 pm_runtime_disable(dev); 1284 pm_runtime_disable(dev);
1759 1285
1760 return 0; 1286 return 0;
@@ -1763,19 +1289,32 @@ static int gsc_remove(struct platform_device *pdev)
1763static int __maybe_unused gsc_runtime_suspend(struct device *dev) 1289static int __maybe_unused gsc_runtime_suspend(struct device *dev)
1764{ 1290{
1765 struct gsc_context *ctx = get_gsc_context(dev); 1291 struct gsc_context *ctx = get_gsc_context(dev);
1292 int i;
1766 1293
1767 DRM_DEBUG_KMS("id[%d]\n", ctx->id); 1294 DRM_DEBUG_KMS("id[%d]\n", ctx->id);
1768 1295
1769 return gsc_clk_ctrl(ctx, false); 1296 for (i = ctx->num_clocks - 1; i >= 0; i--)
1297 clk_disable_unprepare(ctx->clocks[i]);
1298
1299 return 0;
1770} 1300}
1771 1301
1772static int __maybe_unused gsc_runtime_resume(struct device *dev) 1302static int __maybe_unused gsc_runtime_resume(struct device *dev)
1773{ 1303{
1774 struct gsc_context *ctx = get_gsc_context(dev); 1304 struct gsc_context *ctx = get_gsc_context(dev);
1305 int i, ret;
1775 1306
1776 DRM_DEBUG_KMS("id[%d]\n", ctx->id); 1307 DRM_DEBUG_KMS("id[%d]\n", ctx->id);
1777 1308
1778 return gsc_clk_ctrl(ctx, true); 1309 for (i = 0; i < ctx->num_clocks; i++) {
1310 ret = clk_prepare_enable(ctx->clocks[i]);
1311 if (ret) {
1312 while (--i > 0)
1313 clk_disable_unprepare(ctx->clocks[i]);
1314 return ret;
1315 }
1316 }
1317 return 0;
1779} 1318}
1780 1319
1781static const struct dev_pm_ops gsc_pm_ops = { 1320static const struct dev_pm_ops gsc_pm_ops = {
@@ -1784,9 +1323,66 @@ static const struct dev_pm_ops gsc_pm_ops = {
1784 SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL) 1323 SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL)
1785}; 1324};
1786 1325
1326static const struct drm_exynos_ipp_limit gsc_5250_limits[] = {
1327 { IPP_SIZE_LIMIT(BUFFER, .h = { 32, 4800, 8 }, .v = { 16, 3344, 8 }) },
1328 { IPP_SIZE_LIMIT(AREA, .h = { 16, 4800, 2 }, .v = { 8, 3344, 2 }) },
1329 { IPP_SIZE_LIMIT(ROTATED, .h = { 32, 2048 }, .v = { 16, 2048 }) },
1330 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 16, (1 << 16) * 8 },
1331 .v = { (1 << 16) / 16, (1 << 16) * 8 }) },
1332};
1333
1334static const struct drm_exynos_ipp_limit gsc_5420_limits[] = {
1335 { IPP_SIZE_LIMIT(BUFFER, .h = { 32, 4800, 8 }, .v = { 16, 3344, 8 }) },
1336 { IPP_SIZE_LIMIT(AREA, .h = { 16, 4800, 2 }, .v = { 8, 3344, 2 }) },
1337 { IPP_SIZE_LIMIT(ROTATED, .h = { 16, 2016 }, .v = { 8, 2016 }) },
1338 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 16, (1 << 16) * 8 },
1339 .v = { (1 << 16) / 16, (1 << 16) * 8 }) },
1340};
1341
1342static const struct drm_exynos_ipp_limit gsc_5433_limits[] = {
1343 { IPP_SIZE_LIMIT(BUFFER, .h = { 32, 8191, 2 }, .v = { 16, 8191, 2 }) },
1344 { IPP_SIZE_LIMIT(AREA, .h = { 16, 4800, 1 }, .v = { 8, 3344, 1 }) },
1345 { IPP_SIZE_LIMIT(ROTATED, .h = { 32, 2047 }, .v = { 8, 8191 }) },
1346 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 16, (1 << 16) * 8 },
1347 .v = { (1 << 16) / 16, (1 << 16) * 8 }) },
1348};
1349
1350static struct gsc_driverdata gsc_exynos5250_drvdata = {
1351 .clk_names = {"gscl"},
1352 .num_clocks = 1,
1353 .limits = gsc_5250_limits,
1354 .num_limits = ARRAY_SIZE(gsc_5250_limits),
1355};
1356
1357static struct gsc_driverdata gsc_exynos5420_drvdata = {
1358 .clk_names = {"gscl"},
1359 .num_clocks = 1,
1360 .limits = gsc_5420_limits,
1361 .num_limits = ARRAY_SIZE(gsc_5420_limits),
1362};
1363
1364static struct gsc_driverdata gsc_exynos5433_drvdata = {
1365 .clk_names = {"pclk", "aclk", "aclk_xiu", "aclk_gsclbend"},
1366 .num_clocks = 4,
1367 .limits = gsc_5433_limits,
1368 .num_limits = ARRAY_SIZE(gsc_5433_limits),
1369};
1370
1787static const struct of_device_id exynos_drm_gsc_of_match[] = { 1371static const struct of_device_id exynos_drm_gsc_of_match[] = {
1788 { .compatible = "samsung,exynos5-gsc" }, 1372 {
1789 { }, 1373 .compatible = "samsung,exynos5-gsc",
1374 .data = &gsc_exynos5250_drvdata,
1375 }, {
1376 .compatible = "samsung,exynos5250-gsc",
1377 .data = &gsc_exynos5250_drvdata,
1378 }, {
1379 .compatible = "samsung,exynos5420-gsc",
1380 .data = &gsc_exynos5420_drvdata,
1381 }, {
1382 .compatible = "samsung,exynos5433-gsc",
1383 .data = &gsc_exynos5433_drvdata,
1384 }, {
1385 },
1790}; 1386};
1791MODULE_DEVICE_TABLE(of, exynos_drm_gsc_of_match); 1387MODULE_DEVICE_TABLE(of, exynos_drm_gsc_of_match);
1792 1388
@@ -1800,4 +1396,3 @@ struct platform_driver gsc_driver = {
1800 .of_match_table = of_match_ptr(exynos_drm_gsc_of_match), 1396 .of_match_table = of_match_ptr(exynos_drm_gsc_of_match),
1801 }, 1397 },
1802}; 1398};
1803
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.h b/drivers/gpu/drm/exynos/exynos_drm_gsc.h
deleted file mode 100644
index 29ec1c5efcf2..000000000000
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 *
4 * Authors:
5 * Eunchul Kim <chulspro.kim@samsung.com>
6 * Jinyoung Jeon <jy0.jeon@samsung.com>
7 * Sangmin Lee <lsmin.lee@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#ifndef _EXYNOS_DRM_GSC_H_
16#define _EXYNOS_DRM_GSC_H_
17
18/*
19 * TODO
20 * FIMD output interface notifier callback.
21 * Mixer output interface notifier callback.
22 */
23
24#endif /* _EXYNOS_DRM_GSC_H_ */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
new file mode 100644
index 000000000000..26374e58c557
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -0,0 +1,916 @@
1/*
2 * Copyright (C) 2017 Samsung Electronics Co.Ltd
3 * Authors:
4 * Marek Szyprowski <m.szyprowski@samsung.com>
5 *
6 * Exynos DRM Image Post Processing (IPP) related functions
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19
20#include <drm/drmP.h>
21#include <drm/drm_mode.h>
22#include <uapi/drm/exynos_drm.h>
23
24#include "exynos_drm_drv.h"
25#include "exynos_drm_gem.h"
26#include "exynos_drm_ipp.h"
27
28static int num_ipp;
29static LIST_HEAD(ipp_list);
30
31/**
32 * exynos_drm_ipp_register - Register a new picture processor hardware module
33 * @dev: DRM device
34 * @ipp: ipp module to init
35 * @funcs: callbacks for the new ipp object
36 * @caps: bitmask of ipp capabilities (%DRM_EXYNOS_IPP_CAP_*)
37 * @formats: array of supported formats
38 * @num_formats: size of the supported formats array
39 * @name: name (for debugging purposes)
40 *
41 * Initializes a ipp module.
42 *
43 * Returns:
44 * Zero on success, error code on failure.
45 */
46int exynos_drm_ipp_register(struct drm_device *dev, struct exynos_drm_ipp *ipp,
47 const struct exynos_drm_ipp_funcs *funcs, unsigned int caps,
48 const struct exynos_drm_ipp_formats *formats,
49 unsigned int num_formats, const char *name)
50{
51 WARN_ON(!ipp);
52 WARN_ON(!funcs);
53 WARN_ON(!formats);
54 WARN_ON(!num_formats);
55
56 spin_lock_init(&ipp->lock);
57 INIT_LIST_HEAD(&ipp->todo_list);
58 init_waitqueue_head(&ipp->done_wq);
59 ipp->dev = dev;
60 ipp->funcs = funcs;
61 ipp->capabilities = caps;
62 ipp->name = name;
63 ipp->formats = formats;
64 ipp->num_formats = num_formats;
65
66 /* ipp_list modification is serialized by component framework */
67 list_add_tail(&ipp->head, &ipp_list);
68 ipp->id = num_ipp++;
69
70 DRM_DEBUG_DRIVER("Registered ipp %d\n", ipp->id);
71
72 return 0;
73}
74
75/**
76 * exynos_drm_ipp_unregister - Unregister the picture processor module
77 * @dev: DRM device
78 * @ipp: ipp module
79 */
80void exynos_drm_ipp_unregister(struct drm_device *dev,
81 struct exynos_drm_ipp *ipp)
82{
83 WARN_ON(ipp->task);
84 WARN_ON(!list_empty(&ipp->todo_list));
85 list_del(&ipp->head);
86}
87
88/**
89 * exynos_drm_ipp_ioctl_get_res_ioctl - enumerate all ipp modules
90 * @dev: DRM device
91 * @data: ioctl data
92 * @file_priv: DRM file info
93 *
94 * Construct a list of ipp ids.
95 *
96 * Called by the user via ioctl.
97 *
98 * Returns:
99 * Zero on success, negative errno on failure.
100 */
101int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data,
102 struct drm_file *file_priv)
103{
104 struct drm_exynos_ioctl_ipp_get_res *resp = data;
105 struct exynos_drm_ipp *ipp;
106 uint32_t __user *ipp_ptr = (uint32_t __user *)
107 (unsigned long)resp->ipp_id_ptr;
108 unsigned int count = num_ipp, copied = 0;
109
110 /*
111 * This ioctl is called twice, once to determine how much space is
112 * needed, and the 2nd time to fill it.
113 */
114 if (count && resp->count_ipps >= count) {
115 list_for_each_entry(ipp, &ipp_list, head) {
116 if (put_user(ipp->id, ipp_ptr + copied))
117 return -EFAULT;
118 copied++;
119 }
120 }
121 resp->count_ipps = count;
122
123 return 0;
124}
125
126static inline struct exynos_drm_ipp *__ipp_get(uint32_t id)
127{
128 struct exynos_drm_ipp *ipp;
129
130 list_for_each_entry(ipp, &ipp_list, head)
131 if (ipp->id == id)
132 return ipp;
133 return NULL;
134}
135
136/**
137 * exynos_drm_ipp_ioctl_get_caps - get ipp module capabilities and formats
138 * @dev: DRM device
139 * @data: ioctl data
140 * @file_priv: DRM file info
141 *
142 * Construct a structure describing ipp module capabilities.
143 *
144 * Called by the user via ioctl.
145 *
146 * Returns:
147 * Zero on success, negative errno on failure.
148 */
149int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data,
150 struct drm_file *file_priv)
151{
152 struct drm_exynos_ioctl_ipp_get_caps *resp = data;
153 void __user *ptr = (void __user *)(unsigned long)resp->formats_ptr;
154 struct exynos_drm_ipp *ipp;
155 int i;
156
157 ipp = __ipp_get(resp->ipp_id);
158 if (!ipp)
159 return -ENOENT;
160
161 resp->ipp_id = ipp->id;
162 resp->capabilities = ipp->capabilities;
163
164 /*
165 * This ioctl is called twice, once to determine how much space is
166 * needed, and the 2nd time to fill it.
167 */
168 if (resp->formats_count >= ipp->num_formats) {
169 for (i = 0; i < ipp->num_formats; i++) {
170 struct drm_exynos_ipp_format tmp = {
171 .fourcc = ipp->formats[i].fourcc,
172 .type = ipp->formats[i].type,
173 .modifier = ipp->formats[i].modifier,
174 };
175
176 if (copy_to_user(ptr, &tmp, sizeof(tmp)))
177 return -EFAULT;
178 ptr += sizeof(tmp);
179 }
180 }
181 resp->formats_count = ipp->num_formats;
182
183 return 0;
184}
185
186static inline const struct exynos_drm_ipp_formats *__ipp_format_get(
187 struct exynos_drm_ipp *ipp, uint32_t fourcc,
188 uint64_t mod, unsigned int type)
189{
190 int i;
191
192 for (i = 0; i < ipp->num_formats; i++) {
193 if ((ipp->formats[i].type & type) &&
194 ipp->formats[i].fourcc == fourcc &&
195 ipp->formats[i].modifier == mod)
196 return &ipp->formats[i];
197 }
198 return NULL;
199}
200
201/**
202 * exynos_drm_ipp_get_limits_ioctl - get ipp module limits
203 * @dev: DRM device
204 * @data: ioctl data
205 * @file_priv: DRM file info
206 *
207 * Construct a structure describing ipp module limitations for provided
208 * picture format.
209 *
210 * Called by the user via ioctl.
211 *
212 * Returns:
213 * Zero on success, negative errno on failure.
214 */
215int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data,
216 struct drm_file *file_priv)
217{
218 struct drm_exynos_ioctl_ipp_get_limits *resp = data;
219 void __user *ptr = (void __user *)(unsigned long)resp->limits_ptr;
220 const struct exynos_drm_ipp_formats *format;
221 struct exynos_drm_ipp *ipp;
222
223 if (resp->type != DRM_EXYNOS_IPP_FORMAT_SOURCE &&
224 resp->type != DRM_EXYNOS_IPP_FORMAT_DESTINATION)
225 return -EINVAL;
226
227 ipp = __ipp_get(resp->ipp_id);
228 if (!ipp)
229 return -ENOENT;
230
231 format = __ipp_format_get(ipp, resp->fourcc, resp->modifier,
232 resp->type);
233 if (!format)
234 return -EINVAL;
235
236 /*
237 * This ioctl is called twice, once to determine how much space is
238 * needed, and the 2nd time to fill it.
239 */
240 if (format->num_limits && resp->limits_count >= format->num_limits)
241 if (copy_to_user((void __user *)ptr, format->limits,
242 sizeof(*format->limits) * format->num_limits))
243 return -EFAULT;
244 resp->limits_count = format->num_limits;
245
246 return 0;
247}
248
249struct drm_pending_exynos_ipp_event {
250 struct drm_pending_event base;
251 struct drm_exynos_ipp_event event;
252};
253
254static inline struct exynos_drm_ipp_task *
255 exynos_drm_ipp_task_alloc(struct exynos_drm_ipp *ipp)
256{
257 struct exynos_drm_ipp_task *task;
258
259 task = kzalloc(sizeof(*task), GFP_KERNEL);
260 if (!task)
261 return NULL;
262
263 task->dev = ipp->dev;
264 task->ipp = ipp;
265
266 /* some defaults */
267 task->src.rect.w = task->dst.rect.w = UINT_MAX;
268 task->src.rect.h = task->dst.rect.h = UINT_MAX;
269 task->transform.rotation = DRM_MODE_ROTATE_0;
270
271 DRM_DEBUG_DRIVER("Allocated task %pK\n", task);
272
273 return task;
274}
275
276static const struct exynos_drm_param_map {
277 unsigned int id;
278 unsigned int size;
279 unsigned int offset;
280} exynos_drm_ipp_params_maps[] = {
281 {
282 DRM_EXYNOS_IPP_TASK_BUFFER | DRM_EXYNOS_IPP_TASK_TYPE_SOURCE,
283 sizeof(struct drm_exynos_ipp_task_buffer),
284 offsetof(struct exynos_drm_ipp_task, src.buf),
285 }, {
286 DRM_EXYNOS_IPP_TASK_BUFFER |
287 DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION,
288 sizeof(struct drm_exynos_ipp_task_buffer),
289 offsetof(struct exynos_drm_ipp_task, dst.buf),
290 }, {
291 DRM_EXYNOS_IPP_TASK_RECTANGLE | DRM_EXYNOS_IPP_TASK_TYPE_SOURCE,
292 sizeof(struct drm_exynos_ipp_task_rect),
293 offsetof(struct exynos_drm_ipp_task, src.rect),
294 }, {
295 DRM_EXYNOS_IPP_TASK_RECTANGLE |
296 DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION,
297 sizeof(struct drm_exynos_ipp_task_rect),
298 offsetof(struct exynos_drm_ipp_task, dst.rect),
299 }, {
300 DRM_EXYNOS_IPP_TASK_TRANSFORM,
301 sizeof(struct drm_exynos_ipp_task_transform),
302 offsetof(struct exynos_drm_ipp_task, transform),
303 }, {
304 DRM_EXYNOS_IPP_TASK_ALPHA,
305 sizeof(struct drm_exynos_ipp_task_alpha),
306 offsetof(struct exynos_drm_ipp_task, alpha),
307 },
308};
309
310static int exynos_drm_ipp_task_set(struct exynos_drm_ipp_task *task,
311 struct drm_exynos_ioctl_ipp_commit *arg)
312{
313 const struct exynos_drm_param_map *map = exynos_drm_ipp_params_maps;
314 void __user *params = (void __user *)(unsigned long)arg->params_ptr;
315 unsigned int size = arg->params_size;
316 uint32_t id;
317 int i;
318
319 while (size) {
320 if (get_user(id, (uint32_t __user *)params))
321 return -EFAULT;
322
323 for (i = 0; i < ARRAY_SIZE(exynos_drm_ipp_params_maps); i++)
324 if (map[i].id == id)
325 break;
326 if (i == ARRAY_SIZE(exynos_drm_ipp_params_maps) ||
327 map[i].size > size)
328 return -EINVAL;
329
330 if (copy_from_user((void *)task + map[i].offset, params,
331 map[i].size))
332 return -EFAULT;
333
334 params += map[i].size;
335 size -= map[i].size;
336 }
337
338 DRM_DEBUG_DRIVER("Got task %pK configuration from userspace\n", task);
339 return 0;
340}
341
342static int exynos_drm_ipp_task_setup_buffer(struct exynos_drm_ipp_buffer *buf,
343 struct drm_file *filp)
344{
345 int ret = 0;
346 int i;
347
348 /* basic checks */
349 if (buf->buf.width == 0 || buf->buf.height == 0)
350 return -EINVAL;
351 buf->format = drm_format_info(buf->buf.fourcc);
352 for (i = 0; i < buf->format->num_planes; i++) {
353 unsigned int width = (i == 0) ? buf->buf.width :
354 DIV_ROUND_UP(buf->buf.width, buf->format->hsub);
355
356 if (buf->buf.pitch[i] == 0)
357 buf->buf.pitch[i] = width * buf->format->cpp[i];
358 if (buf->buf.pitch[i] < width * buf->format->cpp[i])
359 return -EINVAL;
360 if (!buf->buf.gem_id[i])
361 return -ENOENT;
362 }
363
364 /* pitch for additional planes must match */
365 if (buf->format->num_planes > 2 &&
366 buf->buf.pitch[1] != buf->buf.pitch[2])
367 return -EINVAL;
368
369 /* get GEM buffers and check their size */
370 for (i = 0; i < buf->format->num_planes; i++) {
371 unsigned int height = (i == 0) ? buf->buf.height :
372 DIV_ROUND_UP(buf->buf.height, buf->format->vsub);
373 unsigned long size = height * buf->buf.pitch[i];
374 struct drm_gem_object *obj = drm_gem_object_lookup(filp,
375 buf->buf.gem_id[i]);
376 if (!obj) {
377 ret = -ENOENT;
378 goto gem_free;
379 }
380 buf->exynos_gem[i] = to_exynos_gem(obj);
381
382 if (size + buf->buf.offset[i] > buf->exynos_gem[i]->size) {
383 i++;
384 ret = -EINVAL;
385 goto gem_free;
386 }
387 buf->dma_addr[i] = buf->exynos_gem[i]->dma_addr +
388 buf->buf.offset[i];
389 }
390
391 return 0;
392gem_free:
393 while (i--) {
394 drm_gem_object_put_unlocked(&buf->exynos_gem[i]->base);
395 buf->exynos_gem[i] = NULL;
396 }
397 return ret;
398}
399
400static void exynos_drm_ipp_task_release_buf(struct exynos_drm_ipp_buffer *buf)
401{
402 int i;
403
404 if (!buf->exynos_gem[0])
405 return;
406 for (i = 0; i < buf->format->num_planes; i++)
407 drm_gem_object_put_unlocked(&buf->exynos_gem[i]->base);
408}
409
410static void exynos_drm_ipp_task_free(struct exynos_drm_ipp *ipp,
411 struct exynos_drm_ipp_task *task)
412{
413 DRM_DEBUG_DRIVER("Freeing task %pK\n", task);
414
415 exynos_drm_ipp_task_release_buf(&task->src);
416 exynos_drm_ipp_task_release_buf(&task->dst);
417 if (task->event)
418 drm_event_cancel_free(ipp->dev, &task->event->base);
419 kfree(task);
420}
421
422struct drm_ipp_limit {
423 struct drm_exynos_ipp_limit_val h;
424 struct drm_exynos_ipp_limit_val v;
425};
426
427enum drm_ipp_size_id {
428 IPP_LIMIT_BUFFER, IPP_LIMIT_AREA, IPP_LIMIT_ROTATED, IPP_LIMIT_MAX
429};
430
431static const enum drm_ipp_size_id limit_id_fallback[IPP_LIMIT_MAX][4] = {
432 [IPP_LIMIT_BUFFER] = { DRM_EXYNOS_IPP_LIMIT_SIZE_BUFFER },
433 [IPP_LIMIT_AREA] = { DRM_EXYNOS_IPP_LIMIT_SIZE_AREA,
434 DRM_EXYNOS_IPP_LIMIT_SIZE_BUFFER },
435 [IPP_LIMIT_ROTATED] = { DRM_EXYNOS_IPP_LIMIT_SIZE_ROTATED,
436 DRM_EXYNOS_IPP_LIMIT_SIZE_AREA,
437 DRM_EXYNOS_IPP_LIMIT_SIZE_BUFFER },
438};
439
440static inline void __limit_set_val(unsigned int *ptr, unsigned int val)
441{
442 if (!*ptr)
443 *ptr = val;
444}
445
446static void __get_size_limit(const struct drm_exynos_ipp_limit *limits,
447 unsigned int num_limits, enum drm_ipp_size_id id,
448 struct drm_ipp_limit *res)
449{
450 const struct drm_exynos_ipp_limit *l = limits;
451 int i = 0;
452
453 memset(res, 0, sizeof(*res));
454 for (i = 0; limit_id_fallback[id][i]; i++)
455 for (l = limits; l - limits < num_limits; l++) {
456 if (((l->type & DRM_EXYNOS_IPP_LIMIT_TYPE_MASK) !=
457 DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE) ||
458 ((l->type & DRM_EXYNOS_IPP_LIMIT_SIZE_MASK) !=
459 limit_id_fallback[id][i]))
460 continue;
461 __limit_set_val(&res->h.min, l->h.min);
462 __limit_set_val(&res->h.max, l->h.max);
463 __limit_set_val(&res->h.align, l->h.align);
464 __limit_set_val(&res->v.min, l->v.min);
465 __limit_set_val(&res->v.max, l->v.max);
466 __limit_set_val(&res->v.align, l->v.align);
467 }
468}
469
470static inline bool __align_check(unsigned int val, unsigned int align)
471{
472 if (align && (val & (align - 1))) {
473 DRM_DEBUG_DRIVER("Value %d exceeds HW limits (align %d)\n",
474 val, align);
475 return false;
476 }
477 return true;
478}
479
480static inline bool __size_limit_check(unsigned int val,
481 struct drm_exynos_ipp_limit_val *l)
482{
483 if ((l->min && val < l->min) || (l->max && val > l->max)) {
484 DRM_DEBUG_DRIVER("Value %d exceeds HW limits (min %d, max %d)\n",
485 val, l->min, l->max);
486 return false;
487 }
488 return __align_check(val, l->align);
489}
490
491static int exynos_drm_ipp_check_size_limits(struct exynos_drm_ipp_buffer *buf,
492 const struct drm_exynos_ipp_limit *limits, unsigned int num_limits,
493 bool rotate, bool swap)
494{
495 enum drm_ipp_size_id id = rotate ? IPP_LIMIT_ROTATED : IPP_LIMIT_AREA;
496 struct drm_ipp_limit l;
497 struct drm_exynos_ipp_limit_val *lh = &l.h, *lv = &l.v;
498
499 if (!limits)
500 return 0;
501
502 __get_size_limit(limits, num_limits, IPP_LIMIT_BUFFER, &l);
503 if (!__size_limit_check(buf->buf.width, &l.h) ||
504 !__size_limit_check(buf->buf.height, &l.v))
505 return -EINVAL;
506
507 if (swap) {
508 lv = &l.h;
509 lh = &l.v;
510 }
511 __get_size_limit(limits, num_limits, id, &l);
512 if (!__size_limit_check(buf->rect.w, lh) ||
513 !__align_check(buf->rect.x, lh->align) ||
514 !__size_limit_check(buf->rect.h, lv) ||
515 !__align_check(buf->rect.y, lv->align))
516 return -EINVAL;
517
518 return 0;
519}
520
521static inline bool __scale_limit_check(unsigned int src, unsigned int dst,
522 unsigned int min, unsigned int max)
523{
524 if ((max && (dst << 16) > src * max) ||
525 (min && (dst << 16) < src * min)) {
526 DRM_DEBUG_DRIVER("Scale from %d to %d exceeds HW limits (ratio min %d.%05d, max %d.%05d)\n",
527 src, dst,
528 min >> 16, 100000 * (min & 0xffff) / (1 << 16),
529 max >> 16, 100000 * (max & 0xffff) / (1 << 16));
530 return false;
531 }
532 return true;
533}
534
535static int exynos_drm_ipp_check_scale_limits(
536 struct drm_exynos_ipp_task_rect *src,
537 struct drm_exynos_ipp_task_rect *dst,
538 const struct drm_exynos_ipp_limit *limits,
539 unsigned int num_limits, bool swap)
540{
541 const struct drm_exynos_ipp_limit_val *lh, *lv;
542 int dw, dh;
543
544 for (; num_limits; limits++, num_limits--)
545 if ((limits->type & DRM_EXYNOS_IPP_LIMIT_TYPE_MASK) ==
546 DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE)
547 break;
548 if (!num_limits)
549 return 0;
550
551 lh = (!swap) ? &limits->h : &limits->v;
552 lv = (!swap) ? &limits->v : &limits->h;
553 dw = (!swap) ? dst->w : dst->h;
554 dh = (!swap) ? dst->h : dst->w;
555
556 if (!__scale_limit_check(src->w, dw, lh->min, lh->max) ||
557 !__scale_limit_check(src->h, dh, lv->min, lv->max))
558 return -EINVAL;
559
560 return 0;
561}
562
563static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task)
564{
565 struct exynos_drm_ipp *ipp = task->ipp;
566 const struct exynos_drm_ipp_formats *src_fmt, *dst_fmt;
567 struct exynos_drm_ipp_buffer *src = &task->src, *dst = &task->dst;
568 unsigned int rotation = task->transform.rotation;
569 int ret = 0;
570 bool swap = drm_rotation_90_or_270(rotation);
571 bool rotate = (rotation != DRM_MODE_ROTATE_0);
572 bool scale = false;
573
574 DRM_DEBUG_DRIVER("Checking task %pK\n", task);
575
576 if (src->rect.w == UINT_MAX)
577 src->rect.w = src->buf.width;
578 if (src->rect.h == UINT_MAX)
579 src->rect.h = src->buf.height;
580 if (dst->rect.w == UINT_MAX)
581 dst->rect.w = dst->buf.width;
582 if (dst->rect.h == UINT_MAX)
583 dst->rect.h = dst->buf.height;
584
585 if (src->rect.x + src->rect.w > (src->buf.width) ||
586 src->rect.y + src->rect.h > (src->buf.height) ||
587 dst->rect.x + dst->rect.w > (dst->buf.width) ||
588 dst->rect.y + dst->rect.h > (dst->buf.height)) {
589 DRM_DEBUG_DRIVER("Task %pK: defined area is outside provided buffers\n",
590 task);
591 return -EINVAL;
592 }
593
594 if ((!swap && (src->rect.w != dst->rect.w ||
595 src->rect.h != dst->rect.h)) ||
596 (swap && (src->rect.w != dst->rect.h ||
597 src->rect.h != dst->rect.w)))
598 scale = true;
599
600 if ((!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_CROP) &&
601 (src->rect.x || src->rect.y || dst->rect.x || dst->rect.y)) ||
602 (!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_ROTATE) && rotate) ||
603 (!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_SCALE) && scale) ||
604 (!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_CONVERT) &&
605 src->buf.fourcc != dst->buf.fourcc)) {
606 DRM_DEBUG_DRIVER("Task %pK: hw capabilities exceeded\n", task);
607 return -EINVAL;
608 }
609
610 src_fmt = __ipp_format_get(ipp, src->buf.fourcc, src->buf.modifier,
611 DRM_EXYNOS_IPP_FORMAT_SOURCE);
612 if (!src_fmt) {
613 DRM_DEBUG_DRIVER("Task %pK: src format not supported\n", task);
614 return -EINVAL;
615 }
616 ret = exynos_drm_ipp_check_size_limits(src, src_fmt->limits,
617 src_fmt->num_limits,
618 rotate, false);
619 if (ret)
620 return ret;
621 ret = exynos_drm_ipp_check_scale_limits(&src->rect, &dst->rect,
622 src_fmt->limits,
623 src_fmt->num_limits, swap);
624 if (ret)
625 return ret;
626
627 dst_fmt = __ipp_format_get(ipp, dst->buf.fourcc, dst->buf.modifier,
628 DRM_EXYNOS_IPP_FORMAT_DESTINATION);
629 if (!dst_fmt) {
630 DRM_DEBUG_DRIVER("Task %pK: dst format not supported\n", task);
631 return -EINVAL;
632 }
633 ret = exynos_drm_ipp_check_size_limits(dst, dst_fmt->limits,
634 dst_fmt->num_limits,
635 false, swap);
636 if (ret)
637 return ret;
638 ret = exynos_drm_ipp_check_scale_limits(&src->rect, &dst->rect,
639 dst_fmt->limits,
640 dst_fmt->num_limits, swap);
641 if (ret)
642 return ret;
643
644 DRM_DEBUG_DRIVER("Task %pK: all checks done.\n", task);
645
646 return ret;
647}
648
649static int exynos_drm_ipp_task_setup_buffers(struct exynos_drm_ipp_task *task,
650 struct drm_file *filp)
651{
652 struct exynos_drm_ipp_buffer *src = &task->src, *dst = &task->dst;
653 int ret = 0;
654
655 DRM_DEBUG_DRIVER("Setting buffer for task %pK\n", task);
656
657 ret = exynos_drm_ipp_task_setup_buffer(src, filp);
658 if (ret) {
659 DRM_DEBUG_DRIVER("Task %pK: src buffer setup failed\n", task);
660 return ret;
661 }
662 ret = exynos_drm_ipp_task_setup_buffer(dst, filp);
663 if (ret) {
664 DRM_DEBUG_DRIVER("Task %pK: dst buffer setup failed\n", task);
665 return ret;
666 }
667
668 DRM_DEBUG_DRIVER("Task %pK: buffers prepared.\n", task);
669
670 return ret;
671}
672
673
674static int exynos_drm_ipp_event_create(struct exynos_drm_ipp_task *task,
675 struct drm_file *file_priv, uint64_t user_data)
676{
677 struct drm_pending_exynos_ipp_event *e = NULL;
678 int ret;
679
680 e = kzalloc(sizeof(*e), GFP_KERNEL);
681 if (!e)
682 return -ENOMEM;
683
684 e->event.base.type = DRM_EXYNOS_IPP_EVENT;
685 e->event.base.length = sizeof(e->event);
686 e->event.user_data = user_data;
687
688 ret = drm_event_reserve_init(task->dev, file_priv, &e->base,
689 &e->event.base);
690 if (ret)
691 goto free;
692
693 task->event = e;
694 return 0;
695free:
696 kfree(e);
697 return ret;
698}
699
700static void exynos_drm_ipp_event_send(struct exynos_drm_ipp_task *task)
701{
702 struct timespec64 now;
703
704 ktime_get_ts64(&now);
705 task->event->event.tv_sec = now.tv_sec;
706 task->event->event.tv_usec = now.tv_nsec / NSEC_PER_USEC;
707 task->event->event.sequence = atomic_inc_return(&task->ipp->sequence);
708
709 drm_send_event(task->dev, &task->event->base);
710}
711
712static int exynos_drm_ipp_task_cleanup(struct exynos_drm_ipp_task *task)
713{
714 int ret = task->ret;
715
716 if (ret == 0 && task->event) {
717 exynos_drm_ipp_event_send(task);
718 /* ensure event won't be canceled on task free */
719 task->event = NULL;
720 }
721
722 exynos_drm_ipp_task_free(task->ipp, task);
723 return ret;
724}
725
726static void exynos_drm_ipp_cleanup_work(struct work_struct *work)
727{
728 struct exynos_drm_ipp_task *task = container_of(work,
729 struct exynos_drm_ipp_task, cleanup_work);
730
731 exynos_drm_ipp_task_cleanup(task);
732}
733
734static void exynos_drm_ipp_next_task(struct exynos_drm_ipp *ipp);
735
736/**
737 * exynos_drm_ipp_task_done - finish given task and set return code
738 * @task: ipp task to finish
739 * @ret: error code or 0 if operation has been performed successfully
740 */
741void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret)
742{
743 struct exynos_drm_ipp *ipp = task->ipp;
744 unsigned long flags;
745
746 DRM_DEBUG_DRIVER("ipp: %d, task %pK done: %d\n", ipp->id, task, ret);
747
748 spin_lock_irqsave(&ipp->lock, flags);
749 if (ipp->task == task)
750 ipp->task = NULL;
751 task->flags |= DRM_EXYNOS_IPP_TASK_DONE;
752 task->ret = ret;
753 spin_unlock_irqrestore(&ipp->lock, flags);
754
755 exynos_drm_ipp_next_task(ipp);
756 wake_up(&ipp->done_wq);
757
758 if (task->flags & DRM_EXYNOS_IPP_TASK_ASYNC) {
759 INIT_WORK(&task->cleanup_work, exynos_drm_ipp_cleanup_work);
760 schedule_work(&task->cleanup_work);
761 }
762}
763
764static void exynos_drm_ipp_next_task(struct exynos_drm_ipp *ipp)
765{
766 struct exynos_drm_ipp_task *task;
767 unsigned long flags;
768 int ret;
769
770 DRM_DEBUG_DRIVER("ipp: %d, try to run new task\n", ipp->id);
771
772 spin_lock_irqsave(&ipp->lock, flags);
773
774 if (ipp->task || list_empty(&ipp->todo_list)) {
775 spin_unlock_irqrestore(&ipp->lock, flags);
776 return;
777 }
778
779 task = list_first_entry(&ipp->todo_list, struct exynos_drm_ipp_task,
780 head);
781 list_del_init(&task->head);
782 ipp->task = task;
783
784 spin_unlock_irqrestore(&ipp->lock, flags);
785
786 DRM_DEBUG_DRIVER("ipp: %d, selected task %pK to run\n", ipp->id, task);
787
788 ret = ipp->funcs->commit(ipp, task);
789 if (ret)
790 exynos_drm_ipp_task_done(task, ret);
791}
792
793static void exynos_drm_ipp_schedule_task(struct exynos_drm_ipp *ipp,
794 struct exynos_drm_ipp_task *task)
795{
796 unsigned long flags;
797
798 spin_lock_irqsave(&ipp->lock, flags);
799 list_add(&task->head, &ipp->todo_list);
800 spin_unlock_irqrestore(&ipp->lock, flags);
801
802 exynos_drm_ipp_next_task(ipp);
803}
804
805static void exynos_drm_ipp_task_abort(struct exynos_drm_ipp *ipp,
806 struct exynos_drm_ipp_task *task)
807{
808 unsigned long flags;
809
810 spin_lock_irqsave(&ipp->lock, flags);
811 if (task->flags & DRM_EXYNOS_IPP_TASK_DONE) {
812 /* already completed task */
813 exynos_drm_ipp_task_cleanup(task);
814 } else if (ipp->task != task) {
815 /* task has not been scheduled for execution yet */
816 list_del_init(&task->head);
817 exynos_drm_ipp_task_cleanup(task);
818 } else {
819 /*
820 * currently processed task, call abort() and perform
821 * cleanup with async worker
822 */
823 task->flags |= DRM_EXYNOS_IPP_TASK_ASYNC;
824 spin_unlock_irqrestore(&ipp->lock, flags);
825 if (ipp->funcs->abort)
826 ipp->funcs->abort(ipp, task);
827 return;
828 }
829 spin_unlock_irqrestore(&ipp->lock, flags);
830}
831
832/**
833 * exynos_drm_ipp_commit_ioctl - perform image processing operation
834 * @dev: DRM device
835 * @data: ioctl data
836 * @file_priv: DRM file info
837 *
838 * Construct a ipp task from the set of properties provided from the user
839 * and try to schedule it to framebuffer processor hardware.
840 *
841 * Called by the user via ioctl.
842 *
843 * Returns:
844 * Zero on success, negative errno on failure.
845 */
846int exynos_drm_ipp_commit_ioctl(struct drm_device *dev, void *data,
847 struct drm_file *file_priv)
848{
849 struct drm_exynos_ioctl_ipp_commit *arg = data;
850 struct exynos_drm_ipp *ipp;
851 struct exynos_drm_ipp_task *task;
852 int ret = 0;
853
854 if ((arg->flags & ~DRM_EXYNOS_IPP_FLAGS) || arg->reserved)
855 return -EINVAL;
856
857 /* can't test and expect an event at the same time */
858 if ((arg->flags & DRM_EXYNOS_IPP_FLAG_TEST_ONLY) &&
859 (arg->flags & DRM_EXYNOS_IPP_FLAG_EVENT))
860 return -EINVAL;
861
862 ipp = __ipp_get(arg->ipp_id);
863 if (!ipp)
864 return -ENOENT;
865
866 task = exynos_drm_ipp_task_alloc(ipp);
867 if (!task)
868 return -ENOMEM;
869
870 ret = exynos_drm_ipp_task_set(task, arg);
871 if (ret)
872 goto free;
873
874 ret = exynos_drm_ipp_task_check(task);
875 if (ret)
876 goto free;
877
878 ret = exynos_drm_ipp_task_setup_buffers(task, file_priv);
879 if (ret || arg->flags & DRM_EXYNOS_IPP_FLAG_TEST_ONLY)
880 goto free;
881
882 if (arg->flags & DRM_EXYNOS_IPP_FLAG_EVENT) {
883 ret = exynos_drm_ipp_event_create(task, file_priv,
884 arg->user_data);
885 if (ret)
886 goto free;
887 }
888
889 /*
890 * Queue task for processing on the hardware. task object will be
891 * then freed after exynos_drm_ipp_task_done()
892 */
893 if (arg->flags & DRM_EXYNOS_IPP_FLAG_NONBLOCK) {
894 DRM_DEBUG_DRIVER("ipp: %d, nonblocking processing task %pK\n",
895 ipp->id, task);
896
897 task->flags |= DRM_EXYNOS_IPP_TASK_ASYNC;
898 exynos_drm_ipp_schedule_task(task->ipp, task);
899 ret = 0;
900 } else {
901 DRM_DEBUG_DRIVER("ipp: %d, processing task %pK\n", ipp->id,
902 task);
903 exynos_drm_ipp_schedule_task(ipp, task);
904 ret = wait_event_interruptible(ipp->done_wq,
905 task->flags & DRM_EXYNOS_IPP_TASK_DONE);
906 if (ret)
907 exynos_drm_ipp_task_abort(ipp, task);
908 else
909 ret = exynos_drm_ipp_task_cleanup(task);
910 }
911 return ret;
912free:
913 exynos_drm_ipp_task_free(ipp, task);
914
915 return ret;
916}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
new file mode 100644
index 000000000000..0b27d4a9bf94
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
@@ -0,0 +1,175 @@
1/*
2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#ifndef _EXYNOS_DRM_IPP_H_
11#define _EXYNOS_DRM_IPP_H_
12
13#include <drm/drmP.h>
14
15struct exynos_drm_ipp;
16struct exynos_drm_ipp_task;
17
18/**
19 * struct exynos_drm_ipp_funcs - exynos_drm_ipp control functions
20 */
21struct exynos_drm_ipp_funcs {
22 /**
23 * @commit:
24 *
25 * This is the main entry point to start framebuffer processing
26 * in the hardware. The exynos_drm_ipp_task has been already validated.
27 * This function must not wait until the device finishes processing.
28 * When the driver finishes processing, it has to call
29 * exynos_exynos_drm_ipp_task_done() function.
30 *
31 * RETURNS:
32 *
33 * 0 on success or negative error codes in case of failure.
34 */
35 int (*commit)(struct exynos_drm_ipp *ipp,
36 struct exynos_drm_ipp_task *task);
37
38 /**
39 * @abort:
40 *
41 * Informs the driver that it has to abort the currently running
42 * task as soon as possible (i.e. as soon as it can stop the device
43 * safely), even if the task would not have been finished by then.
44 * After the driver performs the necessary steps, it has to call
45 * exynos_drm_ipp_task_done() (as if the task ended normally).
46 * This function does not have to (and will usually not) wait
47 * until the device enters a state when it can be stopped.
48 */
49 void (*abort)(struct exynos_drm_ipp *ipp,
50 struct exynos_drm_ipp_task *task);
51};
52
53/**
54 * struct exynos_drm_ipp - central picture processor module structure
55 */
56struct exynos_drm_ipp {
57 struct drm_device *dev;
58 struct list_head head;
59 unsigned int id;
60
61 const char *name;
62 const struct exynos_drm_ipp_funcs *funcs;
63 unsigned int capabilities;
64 const struct exynos_drm_ipp_formats *formats;
65 unsigned int num_formats;
66 atomic_t sequence;
67
68 spinlock_t lock;
69 struct exynos_drm_ipp_task *task;
70 struct list_head todo_list;
71 wait_queue_head_t done_wq;
72};
73
74struct exynos_drm_ipp_buffer {
75 struct drm_exynos_ipp_task_buffer buf;
76 struct drm_exynos_ipp_task_rect rect;
77
78 struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
79 const struct drm_format_info *format;
80 dma_addr_t dma_addr[MAX_FB_BUFFER];
81};
82
83/**
84 * struct exynos_drm_ipp_task - a structure describing transformation that
85 * has to be performed by the picture processor hardware module
86 */
87struct exynos_drm_ipp_task {
88 struct drm_device *dev;
89 struct exynos_drm_ipp *ipp;
90 struct list_head head;
91
92 struct exynos_drm_ipp_buffer src;
93 struct exynos_drm_ipp_buffer dst;
94
95 struct drm_exynos_ipp_task_transform transform;
96 struct drm_exynos_ipp_task_alpha alpha;
97
98 struct work_struct cleanup_work;
99 unsigned int flags;
100 int ret;
101
102 struct drm_pending_exynos_ipp_event *event;
103};
104
105#define DRM_EXYNOS_IPP_TASK_DONE (1 << 0)
106#define DRM_EXYNOS_IPP_TASK_ASYNC (1 << 1)
107
108struct exynos_drm_ipp_formats {
109 uint32_t fourcc;
110 uint32_t type;
111 uint64_t modifier;
112 const struct drm_exynos_ipp_limit *limits;
113 unsigned int num_limits;
114};
115
116/* helper macros to set exynos_drm_ipp_formats structure and limits*/
117#define IPP_SRCDST_MFORMAT(f, m, l) \
118 .fourcc = DRM_FORMAT_##f, .modifier = m, .limits = l, \
119 .num_limits = ARRAY_SIZE(l), \
120 .type = (DRM_EXYNOS_IPP_FORMAT_SOURCE | \
121 DRM_EXYNOS_IPP_FORMAT_DESTINATION)
122
123#define IPP_SRCDST_FORMAT(f, l) IPP_SRCDST_MFORMAT(f, 0, l)
124
125#define IPP_SIZE_LIMIT(l, val...) \
126 .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE | \
127 DRM_EXYNOS_IPP_LIMIT_SIZE_##l), val
128
129#define IPP_SCALE_LIMIT(val...) \
130 .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val
131
132int exynos_drm_ipp_register(struct drm_device *dev, struct exynos_drm_ipp *ipp,
133 const struct exynos_drm_ipp_funcs *funcs, unsigned int caps,
134 const struct exynos_drm_ipp_formats *formats,
135 unsigned int num_formats, const char *name);
136void exynos_drm_ipp_unregister(struct drm_device *dev,
137 struct exynos_drm_ipp *ipp);
138
139void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret);
140
141#ifdef CONFIG_DRM_EXYNOS_IPP
142int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data,
143 struct drm_file *file_priv);
144int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data,
145 struct drm_file *file_priv);
146int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data,
147 struct drm_file *file_priv);
148int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
149 void *data, struct drm_file *file_priv);
150#else
151static inline int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev,
152 void *data, struct drm_file *file_priv)
153{
154 struct drm_exynos_ioctl_ipp_get_res *resp = data;
155
156 resp->count_ipps = 0;
157 return 0;
158}
159static inline int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev,
160 void *data, struct drm_file *file_priv)
161{
162 return -ENODEV;
163}
164static inline int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev,
165 void *data, struct drm_file *file_priv)
166{
167 return -ENODEV;
168}
169static inline int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
170 void *data, struct drm_file *file_priv)
171{
172 return -ENODEV;
173}
174#endif
175#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index d2a90dae5c71..38a2a7f1204b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -289,13 +289,12 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
289}; 289};
290 290
291static void exynos_plane_attach_zpos_property(struct drm_plane *plane, 291static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
292 bool immutable) 292 int zpos, bool immutable)
293{ 293{
294 /* FIXME */
295 if (immutable) 294 if (immutable)
296 drm_plane_create_zpos_immutable_property(plane, 0); 295 drm_plane_create_zpos_immutable_property(plane, zpos);
297 else 296 else
298 drm_plane_create_zpos_property(plane, 0, 0, MAX_PLANE - 1); 297 drm_plane_create_zpos_property(plane, zpos, 0, MAX_PLANE - 1);
299} 298}
300 299
301int exynos_plane_init(struct drm_device *dev, 300int exynos_plane_init(struct drm_device *dev,
@@ -320,7 +319,7 @@ int exynos_plane_init(struct drm_device *dev,
320 exynos_plane->index = index; 319 exynos_plane->index = index;
321 exynos_plane->config = config; 320 exynos_plane->config = config;
322 321
323 exynos_plane_attach_zpos_property(&exynos_plane->base, 322 exynos_plane_attach_zpos_property(&exynos_plane->base, config->zpos,
324 !(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS)); 323 !(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS));
325 324
326 return 0; 325 return 0;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
index 79282a820ecc..1a76dd3d52e1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/component.h>
13#include <linux/err.h> 14#include <linux/err.h>
14#include <linux/interrupt.h> 15#include <linux/interrupt.h>
15#include <linux/io.h> 16#include <linux/io.h>
@@ -22,29 +23,18 @@
22#include <drm/exynos_drm.h> 23#include <drm/exynos_drm.h>
23#include "regs-rotator.h" 24#include "regs-rotator.h"
24#include "exynos_drm_drv.h" 25#include "exynos_drm_drv.h"
26#include "exynos_drm_iommu.h"
25#include "exynos_drm_ipp.h" 27#include "exynos_drm_ipp.h"
26 28
27/* 29/*
28 * Rotator supports image crop/rotator and input/output DMA operations. 30 * Rotator supports image crop/rotator and input/output DMA operations.
29 * input DMA reads image data from the memory. 31 * input DMA reads image data from the memory.
30 * output DMA writes image data to memory. 32 * output DMA writes image data to memory.
31 *
32 * M2M operation : supports crop/scale/rotation/csc so on.
33 * Memory ----> Rotator H/W ----> Memory.
34 */ 33 */
35 34
36/* 35#define ROTATOR_AUTOSUSPEND_DELAY 2000
37 * TODO
38 * 1. check suspend/resume api if needed.
39 * 2. need to check use case platform_device_id.
40 * 3. check src/dst size with, height.
41 * 4. need to add supported list in prop_list.
42 */
43 36
44#define get_rot_context(dev) platform_get_drvdata(to_platform_device(dev)) 37#define rot_read(offset) readl(rot->regs + (offset))
45#define get_ctx_from_ippdrv(ippdrv) container_of(ippdrv,\
46 struct rot_context, ippdrv);
47#define rot_read(offset) readl(rot->regs + (offset))
48#define rot_write(cfg, offset) writel(cfg, rot->regs + (offset)) 38#define rot_write(cfg, offset) writel(cfg, rot->regs + (offset))
49 39
50enum rot_irq_status { 40enum rot_irq_status {
@@ -52,54 +42,28 @@ enum rot_irq_status {
52 ROT_IRQ_STATUS_ILLEGAL = 9, 42 ROT_IRQ_STATUS_ILLEGAL = 9,
53}; 43};
54 44
55/* 45struct rot_variant {
56 * A structure of limitation. 46 const struct exynos_drm_ipp_formats *formats;
57 * 47 unsigned int num_formats;
58 * @min_w: minimum width.
59 * @min_h: minimum height.
60 * @max_w: maximum width.
61 * @max_h: maximum height.
62 * @align: align size.
63 */
64struct rot_limit {
65 u32 min_w;
66 u32 min_h;
67 u32 max_w;
68 u32 max_h;
69 u32 align;
70};
71
72/*
73 * A structure of limitation table.
74 *
75 * @ycbcr420_2p: case of YUV.
76 * @rgb888: case of RGB.
77 */
78struct rot_limit_table {
79 struct rot_limit ycbcr420_2p;
80 struct rot_limit rgb888;
81}; 48};
82 49
83/* 50/*
84 * A structure of rotator context. 51 * A structure of rotator context.
85 * @ippdrv: prepare initialization using ippdrv. 52 * @ippdrv: prepare initialization using ippdrv.
86 * @regs_res: register resources.
87 * @regs: memory mapped io registers. 53 * @regs: memory mapped io registers.
88 * @clock: rotator gate clock. 54 * @clock: rotator gate clock.
89 * @limit_tbl: limitation of rotator. 55 * @limit_tbl: limitation of rotator.
90 * @irq: irq number. 56 * @irq: irq number.
91 * @cur_buf_id: current operation buffer id.
92 * @suspended: suspended state.
93 */ 57 */
94struct rot_context { 58struct rot_context {
95 struct exynos_drm_ippdrv ippdrv; 59 struct exynos_drm_ipp ipp;
96 struct resource *regs_res; 60 struct drm_device *drm_dev;
61 struct device *dev;
97 void __iomem *regs; 62 void __iomem *regs;
98 struct clk *clock; 63 struct clk *clock;
99 struct rot_limit_table *limit_tbl; 64 const struct exynos_drm_ipp_formats *formats;
100 int irq; 65 unsigned int num_formats;
101 int cur_buf_id[EXYNOS_DRM_OPS_MAX]; 66 struct exynos_drm_ipp_task *task;
102 bool suspended;
103}; 67};
104 68
105static void rotator_reg_set_irq(struct rot_context *rot, bool enable) 69static void rotator_reg_set_irq(struct rot_context *rot, bool enable)
@@ -114,15 +78,6 @@ static void rotator_reg_set_irq(struct rot_context *rot, bool enable)
114 rot_write(val, ROT_CONFIG); 78 rot_write(val, ROT_CONFIG);
115} 79}
116 80
117static u32 rotator_reg_get_fmt(struct rot_context *rot)
118{
119 u32 val = rot_read(ROT_CONTROL);
120
121 val &= ROT_CONTROL_FMT_MASK;
122
123 return val;
124}
125
126static enum rot_irq_status rotator_reg_get_irq_status(struct rot_context *rot) 81static enum rot_irq_status rotator_reg_get_irq_status(struct rot_context *rot)
127{ 82{
128 u32 val = rot_read(ROT_STATUS); 83 u32 val = rot_read(ROT_STATUS);
@@ -138,9 +93,6 @@ static enum rot_irq_status rotator_reg_get_irq_status(struct rot_context *rot)
138static irqreturn_t rotator_irq_handler(int irq, void *arg) 93static irqreturn_t rotator_irq_handler(int irq, void *arg)
139{ 94{
140 struct rot_context *rot = arg; 95 struct rot_context *rot = arg;
141 struct exynos_drm_ippdrv *ippdrv = &rot->ippdrv;
142 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
143 struct drm_exynos_ipp_event_work *event_work = c_node->event_work;
144 enum rot_irq_status irq_status; 96 enum rot_irq_status irq_status;
145 u32 val; 97 u32 val;
146 98
@@ -152,56 +104,21 @@ static irqreturn_t rotator_irq_handler(int irq, void *arg)
152 val |= ROT_STATUS_IRQ_PENDING((u32)irq_status); 104 val |= ROT_STATUS_IRQ_PENDING((u32)irq_status);
153 rot_write(val, ROT_STATUS); 105 rot_write(val, ROT_STATUS);
154 106
155 if (irq_status == ROT_IRQ_STATUS_COMPLETE) { 107 if (rot->task) {
156 event_work->ippdrv = ippdrv; 108 struct exynos_drm_ipp_task *task = rot->task;
157 event_work->buf_id[EXYNOS_DRM_OPS_DST] = 109
158 rot->cur_buf_id[EXYNOS_DRM_OPS_DST]; 110 rot->task = NULL;
159 queue_work(ippdrv->event_workq, &event_work->work); 111 pm_runtime_mark_last_busy(rot->dev);
160 } else { 112 pm_runtime_put_autosuspend(rot->dev);
161 DRM_ERROR("the SFR is set illegally\n"); 113 exynos_drm_ipp_task_done(task,
114 irq_status == ROT_IRQ_STATUS_COMPLETE ? 0 : -EINVAL);
162 } 115 }
163 116
164 return IRQ_HANDLED; 117 return IRQ_HANDLED;
165} 118}
166 119
167static void rotator_align_size(struct rot_context *rot, u32 fmt, u32 *hsize, 120static void rotator_src_set_fmt(struct rot_context *rot, u32 fmt)
168 u32 *vsize)
169{ 121{
170 struct rot_limit_table *limit_tbl = rot->limit_tbl;
171 struct rot_limit *limit;
172 u32 mask, val;
173
174 /* Get size limit */
175 if (fmt == ROT_CONTROL_FMT_RGB888)
176 limit = &limit_tbl->rgb888;
177 else
178 limit = &limit_tbl->ycbcr420_2p;
179
180 /* Get mask for rounding to nearest aligned val */
181 mask = ~((1 << limit->align) - 1);
182
183 /* Set aligned width */
184 val = ROT_ALIGN(*hsize, limit->align, mask);
185 if (val < limit->min_w)
186 *hsize = ROT_MIN(limit->min_w, mask);
187 else if (val > limit->max_w)
188 *hsize = ROT_MAX(limit->max_w, mask);
189 else
190 *hsize = val;
191
192 /* Set aligned height */
193 val = ROT_ALIGN(*vsize, limit->align, mask);
194 if (val < limit->min_h)
195 *vsize = ROT_MIN(limit->min_h, mask);
196 else if (val > limit->max_h)
197 *vsize = ROT_MAX(limit->max_h, mask);
198 else
199 *vsize = val;
200}
201
202static int rotator_src_set_fmt(struct device *dev, u32 fmt)
203{
204 struct rot_context *rot = dev_get_drvdata(dev);
205 u32 val; 122 u32 val;
206 123
207 val = rot_read(ROT_CONTROL); 124 val = rot_read(ROT_CONTROL);
@@ -214,515 +131,176 @@ static int rotator_src_set_fmt(struct device *dev, u32 fmt)
214 case DRM_FORMAT_XRGB8888: 131 case DRM_FORMAT_XRGB8888:
215 val |= ROT_CONTROL_FMT_RGB888; 132 val |= ROT_CONTROL_FMT_RGB888;
216 break; 133 break;
217 default:
218 DRM_ERROR("invalid image format\n");
219 return -EINVAL;
220 } 134 }
221 135
222 rot_write(val, ROT_CONTROL); 136 rot_write(val, ROT_CONTROL);
223
224 return 0;
225} 137}
226 138
227static inline bool rotator_check_reg_fmt(u32 fmt) 139static void rotator_src_set_buf(struct rot_context *rot,
140 struct exynos_drm_ipp_buffer *buf)
228{ 141{
229 if ((fmt == ROT_CONTROL_FMT_YCBCR420_2P) ||
230 (fmt == ROT_CONTROL_FMT_RGB888))
231 return true;
232
233 return false;
234}
235
236static int rotator_src_set_size(struct device *dev, int swap,
237 struct drm_exynos_pos *pos,
238 struct drm_exynos_sz *sz)
239{
240 struct rot_context *rot = dev_get_drvdata(dev);
241 u32 fmt, hsize, vsize;
242 u32 val; 142 u32 val;
243 143
244 /* Get format */
245 fmt = rotator_reg_get_fmt(rot);
246 if (!rotator_check_reg_fmt(fmt)) {
247 DRM_ERROR("invalid format.\n");
248 return -EINVAL;
249 }
250
251 /* Align buffer size */
252 hsize = sz->hsize;
253 vsize = sz->vsize;
254 rotator_align_size(rot, fmt, &hsize, &vsize);
255
256 /* Set buffer size configuration */ 144 /* Set buffer size configuration */
257 val = ROT_SET_BUF_SIZE_H(vsize) | ROT_SET_BUF_SIZE_W(hsize); 145 val = ROT_SET_BUF_SIZE_H(buf->buf.height) |
146 ROT_SET_BUF_SIZE_W(buf->buf.pitch[0] / buf->format->cpp[0]);
258 rot_write(val, ROT_SRC_BUF_SIZE); 147 rot_write(val, ROT_SRC_BUF_SIZE);
259 148
260 /* Set crop image position configuration */ 149 /* Set crop image position configuration */
261 val = ROT_CROP_POS_Y(pos->y) | ROT_CROP_POS_X(pos->x); 150 val = ROT_CROP_POS_Y(buf->rect.y) | ROT_CROP_POS_X(buf->rect.x);
262 rot_write(val, ROT_SRC_CROP_POS); 151 rot_write(val, ROT_SRC_CROP_POS);
263 val = ROT_SRC_CROP_SIZE_H(pos->h) | ROT_SRC_CROP_SIZE_W(pos->w); 152 val = ROT_SRC_CROP_SIZE_H(buf->rect.h) |
153 ROT_SRC_CROP_SIZE_W(buf->rect.w);
264 rot_write(val, ROT_SRC_CROP_SIZE); 154 rot_write(val, ROT_SRC_CROP_SIZE);
265 155
266 return 0; 156 /* Set buffer DMA address */
157 rot_write(buf->dma_addr[0], ROT_SRC_BUF_ADDR(0));
158 rot_write(buf->dma_addr[1], ROT_SRC_BUF_ADDR(1));
267} 159}
268 160
269static int rotator_src_set_addr(struct device *dev, 161static void rotator_dst_set_transf(struct rot_context *rot,
270 struct drm_exynos_ipp_buf_info *buf_info, 162 unsigned int rotation)
271 u32 buf_id, enum drm_exynos_ipp_buf_type buf_type)
272{ 163{
273 struct rot_context *rot = dev_get_drvdata(dev);
274 dma_addr_t addr[EXYNOS_DRM_PLANAR_MAX];
275 u32 val, fmt, hsize, vsize;
276 int i;
277
278 /* Set current buf_id */
279 rot->cur_buf_id[EXYNOS_DRM_OPS_SRC] = buf_id;
280
281 switch (buf_type) {
282 case IPP_BUF_ENQUEUE:
283 /* Set address configuration */
284 for_each_ipp_planar(i)
285 addr[i] = buf_info->base[i];
286
287 /* Get format */
288 fmt = rotator_reg_get_fmt(rot);
289 if (!rotator_check_reg_fmt(fmt)) {
290 DRM_ERROR("invalid format.\n");
291 return -EINVAL;
292 }
293
294 /* Re-set cb planar for NV12 format */
295 if ((fmt == ROT_CONTROL_FMT_YCBCR420_2P) &&
296 !addr[EXYNOS_DRM_PLANAR_CB]) {
297
298 val = rot_read(ROT_SRC_BUF_SIZE);
299 hsize = ROT_GET_BUF_SIZE_W(val);
300 vsize = ROT_GET_BUF_SIZE_H(val);
301
302 /* Set cb planar */
303 addr[EXYNOS_DRM_PLANAR_CB] =
304 addr[EXYNOS_DRM_PLANAR_Y] + hsize * vsize;
305 }
306
307 for_each_ipp_planar(i)
308 rot_write(addr[i], ROT_SRC_BUF_ADDR(i));
309 break;
310 case IPP_BUF_DEQUEUE:
311 for_each_ipp_planar(i)
312 rot_write(0x0, ROT_SRC_BUF_ADDR(i));
313 break;
314 default:
315 /* Nothing to do */
316 break;
317 }
318
319 return 0;
320}
321
322static int rotator_dst_set_transf(struct device *dev,
323 enum drm_exynos_degree degree,
324 enum drm_exynos_flip flip, bool *swap)
325{
326 struct rot_context *rot = dev_get_drvdata(dev);
327 u32 val; 164 u32 val;
328 165
329 /* Set transform configuration */ 166 /* Set transform configuration */
330 val = rot_read(ROT_CONTROL); 167 val = rot_read(ROT_CONTROL);
331 val &= ~ROT_CONTROL_FLIP_MASK; 168 val &= ~ROT_CONTROL_FLIP_MASK;
332 169
333 switch (flip) { 170 if (rotation & DRM_MODE_REFLECT_X)
334 case EXYNOS_DRM_FLIP_VERTICAL:
335 val |= ROT_CONTROL_FLIP_VERTICAL;
336 break;
337 case EXYNOS_DRM_FLIP_HORIZONTAL:
338 val |= ROT_CONTROL_FLIP_HORIZONTAL; 171 val |= ROT_CONTROL_FLIP_HORIZONTAL;
339 break; 172 if (rotation & DRM_MODE_REFLECT_Y)
340 default: 173 val |= ROT_CONTROL_FLIP_VERTICAL;
341 /* Flip None */
342 break;
343 }
344 174
345 val &= ~ROT_CONTROL_ROT_MASK; 175 val &= ~ROT_CONTROL_ROT_MASK;
346 176
347 switch (degree) { 177 if (rotation & DRM_MODE_ROTATE_90)
348 case EXYNOS_DRM_DEGREE_90:
349 val |= ROT_CONTROL_ROT_90; 178 val |= ROT_CONTROL_ROT_90;
350 break; 179 else if (rotation & DRM_MODE_ROTATE_180)
351 case EXYNOS_DRM_DEGREE_180:
352 val |= ROT_CONTROL_ROT_180; 180 val |= ROT_CONTROL_ROT_180;
353 break; 181 else if (rotation & DRM_MODE_ROTATE_270)
354 case EXYNOS_DRM_DEGREE_270:
355 val |= ROT_CONTROL_ROT_270; 182 val |= ROT_CONTROL_ROT_270;
356 break;
357 default:
358 /* Rotation 0 Degree */
359 break;
360 }
361 183
362 rot_write(val, ROT_CONTROL); 184 rot_write(val, ROT_CONTROL);
363
364 /* Check degree for setting buffer size swap */
365 if ((degree == EXYNOS_DRM_DEGREE_90) ||
366 (degree == EXYNOS_DRM_DEGREE_270))
367 *swap = true;
368 else
369 *swap = false;
370
371 return 0;
372} 185}
373 186
374static int rotator_dst_set_size(struct device *dev, int swap, 187static void rotator_dst_set_buf(struct rot_context *rot,
375 struct drm_exynos_pos *pos, 188 struct exynos_drm_ipp_buffer *buf)
376 struct drm_exynos_sz *sz)
377{ 189{
378 struct rot_context *rot = dev_get_drvdata(dev); 190 u32 val;
379 u32 val, fmt, hsize, vsize;
380
381 /* Get format */
382 fmt = rotator_reg_get_fmt(rot);
383 if (!rotator_check_reg_fmt(fmt)) {
384 DRM_ERROR("invalid format.\n");
385 return -EINVAL;
386 }
387
388 /* Align buffer size */
389 hsize = sz->hsize;
390 vsize = sz->vsize;
391 rotator_align_size(rot, fmt, &hsize, &vsize);
392 191
393 /* Set buffer size configuration */ 192 /* Set buffer size configuration */
394 val = ROT_SET_BUF_SIZE_H(vsize) | ROT_SET_BUF_SIZE_W(hsize); 193 val = ROT_SET_BUF_SIZE_H(buf->buf.height) |
194 ROT_SET_BUF_SIZE_W(buf->buf.pitch[0] / buf->format->cpp[0]);
395 rot_write(val, ROT_DST_BUF_SIZE); 195 rot_write(val, ROT_DST_BUF_SIZE);
396 196
397 /* Set crop image position configuration */ 197 /* Set crop image position configuration */
398 val = ROT_CROP_POS_Y(pos->y) | ROT_CROP_POS_X(pos->x); 198 val = ROT_CROP_POS_Y(buf->rect.y) | ROT_CROP_POS_X(buf->rect.x);
399 rot_write(val, ROT_DST_CROP_POS); 199 rot_write(val, ROT_DST_CROP_POS);
400 200
401 return 0; 201 /* Set buffer DMA address */
202 rot_write(buf->dma_addr[0], ROT_DST_BUF_ADDR(0));
203 rot_write(buf->dma_addr[1], ROT_DST_BUF_ADDR(1));
402} 204}
403 205
404static int rotator_dst_set_addr(struct device *dev, 206static void rotator_start(struct rot_context *rot)
405 struct drm_exynos_ipp_buf_info *buf_info,
406 u32 buf_id, enum drm_exynos_ipp_buf_type buf_type)
407{ 207{
408 struct rot_context *rot = dev_get_drvdata(dev); 208 u32 val;
409 dma_addr_t addr[EXYNOS_DRM_PLANAR_MAX];
410 u32 val, fmt, hsize, vsize;
411 int i;
412
413 /* Set current buf_id */
414 rot->cur_buf_id[EXYNOS_DRM_OPS_DST] = buf_id;
415
416 switch (buf_type) {
417 case IPP_BUF_ENQUEUE:
418 /* Set address configuration */
419 for_each_ipp_planar(i)
420 addr[i] = buf_info->base[i];
421
422 /* Get format */
423 fmt = rotator_reg_get_fmt(rot);
424 if (!rotator_check_reg_fmt(fmt)) {
425 DRM_ERROR("invalid format.\n");
426 return -EINVAL;
427 }
428
429 /* Re-set cb planar for NV12 format */
430 if ((fmt == ROT_CONTROL_FMT_YCBCR420_2P) &&
431 !addr[EXYNOS_DRM_PLANAR_CB]) {
432 /* Get buf size */
433 val = rot_read(ROT_DST_BUF_SIZE);
434
435 hsize = ROT_GET_BUF_SIZE_W(val);
436 vsize = ROT_GET_BUF_SIZE_H(val);
437
438 /* Set cb planar */
439 addr[EXYNOS_DRM_PLANAR_CB] =
440 addr[EXYNOS_DRM_PLANAR_Y] + hsize * vsize;
441 }
442
443 for_each_ipp_planar(i)
444 rot_write(addr[i], ROT_DST_BUF_ADDR(i));
445 break;
446 case IPP_BUF_DEQUEUE:
447 for_each_ipp_planar(i)
448 rot_write(0x0, ROT_DST_BUF_ADDR(i));
449 break;
450 default:
451 /* Nothing to do */
452 break;
453 }
454 209
455 return 0; 210 /* Set interrupt enable */
211 rotator_reg_set_irq(rot, true);
212
213 val = rot_read(ROT_CONTROL);
214 val |= ROT_CONTROL_START;
215 rot_write(val, ROT_CONTROL);
456} 216}
457 217
458static struct exynos_drm_ipp_ops rot_src_ops = { 218static int rotator_commit(struct exynos_drm_ipp *ipp,
459 .set_fmt = rotator_src_set_fmt, 219 struct exynos_drm_ipp_task *task)
460 .set_size = rotator_src_set_size, 220{
461 .set_addr = rotator_src_set_addr, 221 struct rot_context *rot =
462}; 222 container_of(ipp, struct rot_context, ipp);
463 223
464static struct exynos_drm_ipp_ops rot_dst_ops = { 224 pm_runtime_get_sync(rot->dev);
465 .set_transf = rotator_dst_set_transf, 225 rot->task = task;
466 .set_size = rotator_dst_set_size,
467 .set_addr = rotator_dst_set_addr,
468};
469 226
470static int rotator_init_prop_list(struct exynos_drm_ippdrv *ippdrv) 227 rotator_src_set_fmt(rot, task->src.buf.fourcc);
471{ 228 rotator_src_set_buf(rot, &task->src);
472 struct drm_exynos_ipp_prop_list *prop_list = &ippdrv->prop_list; 229 rotator_dst_set_transf(rot, task->transform.rotation);
473 230 rotator_dst_set_buf(rot, &task->dst);
474 prop_list->version = 1; 231 rotator_start(rot);
475 prop_list->flip = (1 << EXYNOS_DRM_FLIP_VERTICAL) |
476 (1 << EXYNOS_DRM_FLIP_HORIZONTAL);
477 prop_list->degree = (1 << EXYNOS_DRM_DEGREE_0) |
478 (1 << EXYNOS_DRM_DEGREE_90) |
479 (1 << EXYNOS_DRM_DEGREE_180) |
480 (1 << EXYNOS_DRM_DEGREE_270);
481 prop_list->csc = 0;
482 prop_list->crop = 0;
483 prop_list->scale = 0;
484 232
485 return 0; 233 return 0;
486} 234}
487 235
488static inline bool rotator_check_drm_fmt(u32 fmt) 236static const struct exynos_drm_ipp_funcs ipp_funcs = {
489{ 237 .commit = rotator_commit,
490 switch (fmt) { 238};
491 case DRM_FORMAT_XRGB8888:
492 case DRM_FORMAT_NV12:
493 return true;
494 default:
495 DRM_DEBUG_KMS("not support format\n");
496 return false;
497 }
498}
499
500static inline bool rotator_check_drm_flip(enum drm_exynos_flip flip)
501{
502 switch (flip) {
503 case EXYNOS_DRM_FLIP_NONE:
504 case EXYNOS_DRM_FLIP_VERTICAL:
505 case EXYNOS_DRM_FLIP_HORIZONTAL:
506 case EXYNOS_DRM_FLIP_BOTH:
507 return true;
508 default:
509 DRM_DEBUG_KMS("invalid flip\n");
510 return false;
511 }
512}
513 239
514static int rotator_ippdrv_check_property(struct device *dev, 240static int rotator_bind(struct device *dev, struct device *master, void *data)
515 struct drm_exynos_ipp_property *property)
516{ 241{
517 struct drm_exynos_ipp_config *src_config = 242 struct rot_context *rot = dev_get_drvdata(dev);
518 &property->config[EXYNOS_DRM_OPS_SRC]; 243 struct drm_device *drm_dev = data;
519 struct drm_exynos_ipp_config *dst_config = 244 struct exynos_drm_ipp *ipp = &rot->ipp;
520 &property->config[EXYNOS_DRM_OPS_DST];
521 struct drm_exynos_pos *src_pos = &src_config->pos;
522 struct drm_exynos_pos *dst_pos = &dst_config->pos;
523 struct drm_exynos_sz *src_sz = &src_config->sz;
524 struct drm_exynos_sz *dst_sz = &dst_config->sz;
525 bool swap = false;
526
527 /* Check format configuration */
528 if (src_config->fmt != dst_config->fmt) {
529 DRM_DEBUG_KMS("not support csc feature\n");
530 return -EINVAL;
531 }
532
533 if (!rotator_check_drm_fmt(dst_config->fmt)) {
534 DRM_DEBUG_KMS("invalid format\n");
535 return -EINVAL;
536 }
537
538 /* Check transform configuration */
539 if (src_config->degree != EXYNOS_DRM_DEGREE_0) {
540 DRM_DEBUG_KMS("not support source-side rotation\n");
541 return -EINVAL;
542 }
543
544 switch (dst_config->degree) {
545 case EXYNOS_DRM_DEGREE_90:
546 case EXYNOS_DRM_DEGREE_270:
547 swap = true;
548 case EXYNOS_DRM_DEGREE_0:
549 case EXYNOS_DRM_DEGREE_180:
550 /* No problem */
551 break;
552 default:
553 DRM_DEBUG_KMS("invalid degree\n");
554 return -EINVAL;
555 }
556
557 if (src_config->flip != EXYNOS_DRM_FLIP_NONE) {
558 DRM_DEBUG_KMS("not support source-side flip\n");
559 return -EINVAL;
560 }
561 245
562 if (!rotator_check_drm_flip(dst_config->flip)) { 246 rot->drm_dev = drm_dev;
563 DRM_DEBUG_KMS("invalid flip\n"); 247 drm_iommu_attach_device(drm_dev, dev);
564 return -EINVAL;
565 }
566 248
567 /* Check size configuration */ 249 exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs,
568 if ((src_pos->x + src_pos->w > src_sz->hsize) || 250 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE,
569 (src_pos->y + src_pos->h > src_sz->vsize)) { 251 rot->formats, rot->num_formats, "rotator");
570 DRM_DEBUG_KMS("out of source buffer bound\n");
571 return -EINVAL;
572 }
573 252
574 if (swap) { 253 dev_info(dev, "The exynos rotator has been probed successfully\n");
575 if ((dst_pos->x + dst_pos->h > dst_sz->vsize) ||
576 (dst_pos->y + dst_pos->w > dst_sz->hsize)) {
577 DRM_DEBUG_KMS("out of destination buffer bound\n");
578 return -EINVAL;
579 }
580
581 if ((src_pos->w != dst_pos->h) || (src_pos->h != dst_pos->w)) {
582 DRM_DEBUG_KMS("not support scale feature\n");
583 return -EINVAL;
584 }
585 } else {
586 if ((dst_pos->x + dst_pos->w > dst_sz->hsize) ||
587 (dst_pos->y + dst_pos->h > dst_sz->vsize)) {
588 DRM_DEBUG_KMS("out of destination buffer bound\n");
589 return -EINVAL;
590 }
591
592 if ((src_pos->w != dst_pos->w) || (src_pos->h != dst_pos->h)) {
593 DRM_DEBUG_KMS("not support scale feature\n");
594 return -EINVAL;
595 }
596 }
597 254
598 return 0; 255 return 0;
599} 256}
600 257
601static int rotator_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) 258static void rotator_unbind(struct device *dev, struct device *master,
259 void *data)
602{ 260{
603 struct rot_context *rot = dev_get_drvdata(dev); 261 struct rot_context *rot = dev_get_drvdata(dev);
604 u32 val; 262 struct drm_device *drm_dev = data;
605 263 struct exynos_drm_ipp *ipp = &rot->ipp;
606 if (rot->suspended) {
607 DRM_ERROR("suspended state\n");
608 return -EPERM;
609 }
610
611 if (cmd != IPP_CMD_M2M) {
612 DRM_ERROR("not support cmd: %d\n", cmd);
613 return -EINVAL;
614 }
615
616 /* Set interrupt enable */
617 rotator_reg_set_irq(rot, true);
618
619 val = rot_read(ROT_CONTROL);
620 val |= ROT_CONTROL_START;
621
622 rot_write(val, ROT_CONTROL);
623 264
624 return 0; 265 exynos_drm_ipp_unregister(drm_dev, ipp);
266 drm_iommu_detach_device(rot->drm_dev, rot->dev);
625} 267}
626 268
627static struct rot_limit_table rot_limit_tbl_4210 = { 269static const struct component_ops rotator_component_ops = {
628 .ycbcr420_2p = { 270 .bind = rotator_bind,
629 .min_w = 32, 271 .unbind = rotator_unbind,
630 .min_h = 32,
631 .max_w = SZ_64K,
632 .max_h = SZ_64K,
633 .align = 3,
634 },
635 .rgb888 = {
636 .min_w = 8,
637 .min_h = 8,
638 .max_w = SZ_16K,
639 .max_h = SZ_16K,
640 .align = 2,
641 },
642};
643
644static struct rot_limit_table rot_limit_tbl_4x12 = {
645 .ycbcr420_2p = {
646 .min_w = 32,
647 .min_h = 32,
648 .max_w = SZ_32K,
649 .max_h = SZ_32K,
650 .align = 3,
651 },
652 .rgb888 = {
653 .min_w = 8,
654 .min_h = 8,
655 .max_w = SZ_8K,
656 .max_h = SZ_8K,
657 .align = 2,
658 },
659}; 272};
660 273
661static struct rot_limit_table rot_limit_tbl_5250 = {
662 .ycbcr420_2p = {
663 .min_w = 32,
664 .min_h = 32,
665 .max_w = SZ_32K,
666 .max_h = SZ_32K,
667 .align = 3,
668 },
669 .rgb888 = {
670 .min_w = 8,
671 .min_h = 8,
672 .max_w = SZ_8K,
673 .max_h = SZ_8K,
674 .align = 1,
675 },
676};
677
678static const struct of_device_id exynos_rotator_match[] = {
679 {
680 .compatible = "samsung,exynos4210-rotator",
681 .data = &rot_limit_tbl_4210,
682 },
683 {
684 .compatible = "samsung,exynos4212-rotator",
685 .data = &rot_limit_tbl_4x12,
686 },
687 {
688 .compatible = "samsung,exynos5250-rotator",
689 .data = &rot_limit_tbl_5250,
690 },
691 {},
692};
693MODULE_DEVICE_TABLE(of, exynos_rotator_match);
694
695static int rotator_probe(struct platform_device *pdev) 274static int rotator_probe(struct platform_device *pdev)
696{ 275{
697 struct device *dev = &pdev->dev; 276 struct device *dev = &pdev->dev;
277 struct resource *regs_res;
698 struct rot_context *rot; 278 struct rot_context *rot;
699 struct exynos_drm_ippdrv *ippdrv; 279 const struct rot_variant *variant;
280 int irq;
700 int ret; 281 int ret;
701 282
702 if (!dev->of_node) {
703 dev_err(dev, "cannot find of_node.\n");
704 return -ENODEV;
705 }
706
707 rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL); 283 rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL);
708 if (!rot) 284 if (!rot)
709 return -ENOMEM; 285 return -ENOMEM;
710 286
711 rot->limit_tbl = (struct rot_limit_table *) 287 variant = of_device_get_match_data(dev);
712 of_device_get_match_data(dev); 288 rot->formats = variant->formats;
713 rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 289 rot->num_formats = variant->num_formats;
714 rot->regs = devm_ioremap_resource(dev, rot->regs_res); 290 rot->dev = dev;
291 regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
292 rot->regs = devm_ioremap_resource(dev, regs_res);
715 if (IS_ERR(rot->regs)) 293 if (IS_ERR(rot->regs))
716 return PTR_ERR(rot->regs); 294 return PTR_ERR(rot->regs);
717 295
718 rot->irq = platform_get_irq(pdev, 0); 296 irq = platform_get_irq(pdev, 0);
719 if (rot->irq < 0) { 297 if (irq < 0) {
720 dev_err(dev, "failed to get irq\n"); 298 dev_err(dev, "failed to get irq\n");
721 return rot->irq; 299 return irq;
722 } 300 }
723 301
724 ret = devm_request_threaded_irq(dev, rot->irq, NULL, 302 ret = devm_request_irq(dev, irq, rotator_irq_handler, 0, dev_name(dev),
725 rotator_irq_handler, IRQF_ONESHOT, "drm_rotator", rot); 303 rot);
726 if (ret < 0) { 304 if (ret < 0) {
727 dev_err(dev, "failed to request irq\n"); 305 dev_err(dev, "failed to request irq\n");
728 return ret; 306 return ret;
@@ -734,35 +312,19 @@ static int rotator_probe(struct platform_device *pdev)
734 return PTR_ERR(rot->clock); 312 return PTR_ERR(rot->clock);
735 } 313 }
736 314
315 pm_runtime_use_autosuspend(dev);
316 pm_runtime_set_autosuspend_delay(dev, ROTATOR_AUTOSUSPEND_DELAY);
737 pm_runtime_enable(dev); 317 pm_runtime_enable(dev);
738
739 ippdrv = &rot->ippdrv;
740 ippdrv->dev = dev;
741 ippdrv->ops[EXYNOS_DRM_OPS_SRC] = &rot_src_ops;
742 ippdrv->ops[EXYNOS_DRM_OPS_DST] = &rot_dst_ops;
743 ippdrv->check_property = rotator_ippdrv_check_property;
744 ippdrv->start = rotator_ippdrv_start;
745 ret = rotator_init_prop_list(ippdrv);
746 if (ret < 0) {
747 dev_err(dev, "failed to init property list.\n");
748 goto err_ippdrv_register;
749 }
750
751 DRM_DEBUG_KMS("ippdrv[%pK]\n", ippdrv);
752
753 platform_set_drvdata(pdev, rot); 318 platform_set_drvdata(pdev, rot);
754 319
755 ret = exynos_drm_ippdrv_register(ippdrv); 320 ret = component_add(dev, &rotator_component_ops);
756 if (ret < 0) { 321 if (ret)
757 dev_err(dev, "failed to register drm rotator device\n"); 322 goto err_component;
758 goto err_ippdrv_register;
759 }
760
761 dev_info(dev, "The exynos rotator is probed successfully\n");
762 323
763 return 0; 324 return 0;
764 325
765err_ippdrv_register: 326err_component:
327 pm_runtime_dont_use_autosuspend(dev);
766 pm_runtime_disable(dev); 328 pm_runtime_disable(dev);
767 return ret; 329 return ret;
768} 330}
@@ -770,45 +332,101 @@ err_ippdrv_register:
770static int rotator_remove(struct platform_device *pdev) 332static int rotator_remove(struct platform_device *pdev)
771{ 333{
772 struct device *dev = &pdev->dev; 334 struct device *dev = &pdev->dev;
773 struct rot_context *rot = dev_get_drvdata(dev);
774 struct exynos_drm_ippdrv *ippdrv = &rot->ippdrv;
775
776 exynos_drm_ippdrv_unregister(ippdrv);
777 335
336 component_del(dev, &rotator_component_ops);
337 pm_runtime_dont_use_autosuspend(dev);
778 pm_runtime_disable(dev); 338 pm_runtime_disable(dev);
779 339
780 return 0; 340 return 0;
781} 341}
782 342
783#ifdef CONFIG_PM 343#ifdef CONFIG_PM
784static int rotator_clk_crtl(struct rot_context *rot, bool enable)
785{
786 if (enable) {
787 clk_prepare_enable(rot->clock);
788 rot->suspended = false;
789 } else {
790 clk_disable_unprepare(rot->clock);
791 rot->suspended = true;
792 }
793
794 return 0;
795}
796
797static int rotator_runtime_suspend(struct device *dev) 344static int rotator_runtime_suspend(struct device *dev)
798{ 345{
799 struct rot_context *rot = dev_get_drvdata(dev); 346 struct rot_context *rot = dev_get_drvdata(dev);
800 347
801 return rotator_clk_crtl(rot, false); 348 clk_disable_unprepare(rot->clock);
349 return 0;
802} 350}
803 351
804static int rotator_runtime_resume(struct device *dev) 352static int rotator_runtime_resume(struct device *dev)
805{ 353{
806 struct rot_context *rot = dev_get_drvdata(dev); 354 struct rot_context *rot = dev_get_drvdata(dev);
807 355
808 return rotator_clk_crtl(rot, true); 356 return clk_prepare_enable(rot->clock);
809} 357}
810#endif 358#endif
811 359
360static const struct drm_exynos_ipp_limit rotator_4210_rbg888_limits[] = {
361 { IPP_SIZE_LIMIT(BUFFER, .h = { 8, SZ_16K }, .v = { 8, SZ_16K }) },
362 { IPP_SIZE_LIMIT(AREA, .h.align = 4, .v.align = 4) },
363};
364
365static const struct drm_exynos_ipp_limit rotator_4412_rbg888_limits[] = {
366 { IPP_SIZE_LIMIT(BUFFER, .h = { 8, SZ_8K }, .v = { 8, SZ_8K }) },
367 { IPP_SIZE_LIMIT(AREA, .h.align = 4, .v.align = 4) },
368};
369
370static const struct drm_exynos_ipp_limit rotator_5250_rbg888_limits[] = {
371 { IPP_SIZE_LIMIT(BUFFER, .h = { 8, SZ_8K }, .v = { 8, SZ_8K }) },
372 { IPP_SIZE_LIMIT(AREA, .h.align = 2, .v.align = 2) },
373};
374
375static const struct drm_exynos_ipp_limit rotator_4210_yuv_limits[] = {
376 { IPP_SIZE_LIMIT(BUFFER, .h = { 32, SZ_64K }, .v = { 32, SZ_64K }) },
377 { IPP_SIZE_LIMIT(AREA, .h.align = 8, .v.align = 8) },
378};
379
380static const struct drm_exynos_ipp_limit rotator_4412_yuv_limits[] = {
381 { IPP_SIZE_LIMIT(BUFFER, .h = { 32, SZ_32K }, .v = { 32, SZ_32K }) },
382 { IPP_SIZE_LIMIT(AREA, .h.align = 8, .v.align = 8) },
383};
384
385static const struct exynos_drm_ipp_formats rotator_4210_formats[] = {
386 { IPP_SRCDST_FORMAT(XRGB8888, rotator_4210_rbg888_limits) },
387 { IPP_SRCDST_FORMAT(NV12, rotator_4210_yuv_limits) },
388};
389
390static const struct exynos_drm_ipp_formats rotator_4412_formats[] = {
391 { IPP_SRCDST_FORMAT(XRGB8888, rotator_4412_rbg888_limits) },
392 { IPP_SRCDST_FORMAT(NV12, rotator_4412_yuv_limits) },
393};
394
395static const struct exynos_drm_ipp_formats rotator_5250_formats[] = {
396 { IPP_SRCDST_FORMAT(XRGB8888, rotator_5250_rbg888_limits) },
397 { IPP_SRCDST_FORMAT(NV12, rotator_4412_yuv_limits) },
398};
399
400static const struct rot_variant rotator_4210_data = {
401 .formats = rotator_4210_formats,
402 .num_formats = ARRAY_SIZE(rotator_4210_formats),
403};
404
405static const struct rot_variant rotator_4412_data = {
406 .formats = rotator_4412_formats,
407 .num_formats = ARRAY_SIZE(rotator_4412_formats),
408};
409
410static const struct rot_variant rotator_5250_data = {
411 .formats = rotator_5250_formats,
412 .num_formats = ARRAY_SIZE(rotator_5250_formats),
413};
414
415static const struct of_device_id exynos_rotator_match[] = {
416 {
417 .compatible = "samsung,exynos4210-rotator",
418 .data = &rotator_4210_data,
419 }, {
420 .compatible = "samsung,exynos4212-rotator",
421 .data = &rotator_4412_data,
422 }, {
423 .compatible = "samsung,exynos5250-rotator",
424 .data = &rotator_5250_data,
425 }, {
426 },
427};
428MODULE_DEVICE_TABLE(of, exynos_rotator_match);
429
812static const struct dev_pm_ops rotator_pm_ops = { 430static const struct dev_pm_ops rotator_pm_ops = {
813 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 431 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
814 pm_runtime_force_resume) 432 pm_runtime_force_resume)
@@ -820,7 +438,7 @@ struct platform_driver rotator_driver = {
820 .probe = rotator_probe, 438 .probe = rotator_probe,
821 .remove = rotator_remove, 439 .remove = rotator_remove,
822 .driver = { 440 .driver = {
823 .name = "exynos-rot", 441 .name = "exynos-rotator",
824 .owner = THIS_MODULE, 442 .owner = THIS_MODULE,
825 .pm = &rotator_pm_ops, 443 .pm = &rotator_pm_ops,
826 .of_match_table = exynos_rotator_match, 444 .of_match_table = exynos_rotator_match,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_scaler.c b/drivers/gpu/drm/exynos/exynos_drm_scaler.c
new file mode 100644
index 000000000000..91d4382343d0
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_scaler.c
@@ -0,0 +1,694 @@
1/*
2 * Copyright (C) 2017 Samsung Electronics Co.Ltd
3 * Author:
4 * Andrzej Pietrasiewicz <andrzej.p@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundationr
9 */
10
11#include <linux/kernel.h>
12#include <linux/component.h>
13#include <linux/err.h>
14#include <linux/interrupt.h>
15#include <linux/io.h>
16#include <linux/platform_device.h>
17#include <linux/clk.h>
18#include <linux/of_device.h>
19#include <linux/pm_runtime.h>
20
21#include <drm/drmP.h>
22#include <drm/exynos_drm.h>
23#include "regs-scaler.h"
24#include "exynos_drm_fb.h"
25#include "exynos_drm_drv.h"
26#include "exynos_drm_iommu.h"
27#include "exynos_drm_ipp.h"
28
29#define scaler_read(offset) readl(scaler->regs + (offset))
30#define scaler_write(cfg, offset) writel(cfg, scaler->regs + (offset))
31#define SCALER_MAX_CLK 4
32#define SCALER_AUTOSUSPEND_DELAY 2000
33
34struct scaler_data {
35 const char *clk_name[SCALER_MAX_CLK];
36 unsigned int num_clk;
37 const struct exynos_drm_ipp_formats *formats;
38 unsigned int num_formats;
39};
40
41struct scaler_context {
42 struct exynos_drm_ipp ipp;
43 struct drm_device *drm_dev;
44 struct device *dev;
45 void __iomem *regs;
46 struct clk *clock[SCALER_MAX_CLK];
47 struct exynos_drm_ipp_task *task;
48 const struct scaler_data *scaler_data;
49};
50
51static u32 scaler_get_format(u32 drm_fmt)
52{
53 switch (drm_fmt) {
54 case DRM_FORMAT_NV21:
55 return SCALER_YUV420_2P_UV;
56 case DRM_FORMAT_NV12:
57 return SCALER_YUV420_2P_VU;
58 case DRM_FORMAT_YUV420:
59 return SCALER_YUV420_3P;
60 case DRM_FORMAT_YUYV:
61 return SCALER_YUV422_1P_YUYV;
62 case DRM_FORMAT_UYVY:
63 return SCALER_YUV422_1P_UYVY;
64 case DRM_FORMAT_YVYU:
65 return SCALER_YUV422_1P_YVYU;
66 case DRM_FORMAT_NV61:
67 return SCALER_YUV422_2P_UV;
68 case DRM_FORMAT_NV16:
69 return SCALER_YUV422_2P_VU;
70 case DRM_FORMAT_YUV422:
71 return SCALER_YUV422_3P;
72 case DRM_FORMAT_NV42:
73 return SCALER_YUV444_2P_UV;
74 case DRM_FORMAT_NV24:
75 return SCALER_YUV444_2P_VU;
76 case DRM_FORMAT_YUV444:
77 return SCALER_YUV444_3P;
78 case DRM_FORMAT_RGB565:
79 return SCALER_RGB_565;
80 case DRM_FORMAT_XRGB1555:
81 return SCALER_ARGB1555;
82 case DRM_FORMAT_ARGB1555:
83 return SCALER_ARGB1555;
84 case DRM_FORMAT_XRGB4444:
85 return SCALER_ARGB4444;
86 case DRM_FORMAT_ARGB4444:
87 return SCALER_ARGB4444;
88 case DRM_FORMAT_XRGB8888:
89 return SCALER_ARGB8888;
90 case DRM_FORMAT_ARGB8888:
91 return SCALER_ARGB8888;
92 case DRM_FORMAT_RGBX8888:
93 return SCALER_RGBA8888;
94 case DRM_FORMAT_RGBA8888:
95 return SCALER_RGBA8888;
96 default:
97 break;
98 }
99
100 return 0;
101}
102
103static inline void scaler_enable_int(struct scaler_context *scaler)
104{
105 u32 val;
106
107 val = SCALER_INT_EN_TIMEOUT |
108 SCALER_INT_EN_ILLEGAL_BLEND |
109 SCALER_INT_EN_ILLEGAL_RATIO |
110 SCALER_INT_EN_ILLEGAL_DST_HEIGHT |
111 SCALER_INT_EN_ILLEGAL_DST_WIDTH |
112 SCALER_INT_EN_ILLEGAL_DST_V_POS |
113 SCALER_INT_EN_ILLEGAL_DST_H_POS |
114 SCALER_INT_EN_ILLEGAL_DST_C_SPAN |
115 SCALER_INT_EN_ILLEGAL_DST_Y_SPAN |
116 SCALER_INT_EN_ILLEGAL_DST_CR_BASE |
117 SCALER_INT_EN_ILLEGAL_DST_CB_BASE |
118 SCALER_INT_EN_ILLEGAL_DST_Y_BASE |
119 SCALER_INT_EN_ILLEGAL_DST_COLOR |
120 SCALER_INT_EN_ILLEGAL_SRC_HEIGHT |
121 SCALER_INT_EN_ILLEGAL_SRC_WIDTH |
122 SCALER_INT_EN_ILLEGAL_SRC_CV_POS |
123 SCALER_INT_EN_ILLEGAL_SRC_CH_POS |
124 SCALER_INT_EN_ILLEGAL_SRC_YV_POS |
125 SCALER_INT_EN_ILLEGAL_SRC_YH_POS |
126 SCALER_INT_EN_ILLEGAL_DST_SPAN |
127 SCALER_INT_EN_ILLEGAL_SRC_Y_SPAN |
128 SCALER_INT_EN_ILLEGAL_SRC_CR_BASE |
129 SCALER_INT_EN_ILLEGAL_SRC_CB_BASE |
130 SCALER_INT_EN_ILLEGAL_SRC_Y_BASE |
131 SCALER_INT_EN_ILLEGAL_SRC_COLOR |
132 SCALER_INT_EN_FRAME_END;
133 scaler_write(val, SCALER_INT_EN);
134}
135
136static inline void scaler_set_src_fmt(struct scaler_context *scaler,
137 u32 src_fmt)
138{
139 u32 val;
140
141 val = SCALER_SRC_CFG_SET_COLOR_FORMAT(src_fmt);
142 scaler_write(val, SCALER_SRC_CFG);
143}
144
145static inline void scaler_set_src_base(struct scaler_context *scaler,
146 struct exynos_drm_ipp_buffer *src_buf)
147{
148 static unsigned int bases[] = {
149 SCALER_SRC_Y_BASE,
150 SCALER_SRC_CB_BASE,
151 SCALER_SRC_CR_BASE,
152 };
153 int i;
154
155 for (i = 0; i < src_buf->format->num_planes; ++i)
156 scaler_write(src_buf->dma_addr[i], bases[i]);
157}
158
159static inline void scaler_set_src_span(struct scaler_context *scaler,
160 struct exynos_drm_ipp_buffer *src_buf)
161{
162 u32 val;
163
164 val = SCALER_SRC_SPAN_SET_Y_SPAN(src_buf->buf.pitch[0] /
165 src_buf->format->cpp[0]);
166
167 if (src_buf->format->num_planes > 1)
168 val |= SCALER_SRC_SPAN_SET_C_SPAN(src_buf->buf.pitch[1]);
169
170 scaler_write(val, SCALER_SRC_SPAN);
171}
172
173static inline void scaler_set_src_luma_pos(struct scaler_context *scaler,
174 struct drm_exynos_ipp_task_rect *src_pos)
175{
176 u32 val;
177
178 val = SCALER_SRC_Y_POS_SET_YH_POS(src_pos->x << 2);
179 val |= SCALER_SRC_Y_POS_SET_YV_POS(src_pos->y << 2);
180 scaler_write(val, SCALER_SRC_Y_POS);
181 scaler_write(val, SCALER_SRC_C_POS); /* ATTENTION! */
182}
183
184static inline void scaler_set_src_wh(struct scaler_context *scaler,
185 struct drm_exynos_ipp_task_rect *src_pos)
186{
187 u32 val;
188
189 val = SCALER_SRC_WH_SET_WIDTH(src_pos->w);
190 val |= SCALER_SRC_WH_SET_HEIGHT(src_pos->h);
191 scaler_write(val, SCALER_SRC_WH);
192}
193
194static inline void scaler_set_dst_fmt(struct scaler_context *scaler,
195 u32 dst_fmt)
196{
197 u32 val;
198
199 val = SCALER_DST_CFG_SET_COLOR_FORMAT(dst_fmt);
200 scaler_write(val, SCALER_DST_CFG);
201}
202
203static inline void scaler_set_dst_base(struct scaler_context *scaler,
204 struct exynos_drm_ipp_buffer *dst_buf)
205{
206 static unsigned int bases[] = {
207 SCALER_DST_Y_BASE,
208 SCALER_DST_CB_BASE,
209 SCALER_DST_CR_BASE,
210 };
211 int i;
212
213 for (i = 0; i < dst_buf->format->num_planes; ++i)
214 scaler_write(dst_buf->dma_addr[i], bases[i]);
215}
216
217static inline void scaler_set_dst_span(struct scaler_context *scaler,
218 struct exynos_drm_ipp_buffer *dst_buf)
219{
220 u32 val;
221
222 val = SCALER_DST_SPAN_SET_Y_SPAN(dst_buf->buf.pitch[0] /
223 dst_buf->format->cpp[0]);
224
225 if (dst_buf->format->num_planes > 1)
226 val |= SCALER_DST_SPAN_SET_C_SPAN(dst_buf->buf.pitch[1]);
227
228 scaler_write(val, SCALER_DST_SPAN);
229}
230
231static inline void scaler_set_dst_luma_pos(struct scaler_context *scaler,
232 struct drm_exynos_ipp_task_rect *dst_pos)
233{
234 u32 val;
235
236 val = SCALER_DST_WH_SET_WIDTH(dst_pos->w);
237 val |= SCALER_DST_WH_SET_HEIGHT(dst_pos->h);
238 scaler_write(val, SCALER_DST_WH);
239}
240
241static inline void scaler_set_dst_wh(struct scaler_context *scaler,
242 struct drm_exynos_ipp_task_rect *dst_pos)
243{
244 u32 val;
245
246 val = SCALER_DST_POS_SET_H_POS(dst_pos->x);
247 val |= SCALER_DST_POS_SET_V_POS(dst_pos->y);
248 scaler_write(val, SCALER_DST_POS);
249}
250
251static inline void scaler_set_hv_ratio(struct scaler_context *scaler,
252 unsigned int rotation,
253 struct drm_exynos_ipp_task_rect *src_pos,
254 struct drm_exynos_ipp_task_rect *dst_pos)
255{
256 u32 val, h_ratio, v_ratio;
257
258 if (drm_rotation_90_or_270(rotation)) {
259 h_ratio = (src_pos->h << 16) / dst_pos->w;
260 v_ratio = (src_pos->w << 16) / dst_pos->h;
261 } else {
262 h_ratio = (src_pos->w << 16) / dst_pos->w;
263 v_ratio = (src_pos->h << 16) / dst_pos->h;
264 }
265
266 val = SCALER_H_RATIO_SET(h_ratio);
267 scaler_write(val, SCALER_H_RATIO);
268
269 val = SCALER_V_RATIO_SET(v_ratio);
270 scaler_write(val, SCALER_V_RATIO);
271}
272
273static inline void scaler_set_rotation(struct scaler_context *scaler,
274 unsigned int rotation)
275{
276 u32 val = 0;
277
278 if (rotation & DRM_MODE_ROTATE_90)
279 val |= SCALER_ROT_CFG_SET_ROTMODE(SCALER_ROT_MODE_90);
280 else if (rotation & DRM_MODE_ROTATE_180)
281 val |= SCALER_ROT_CFG_SET_ROTMODE(SCALER_ROT_MODE_180);
282 else if (rotation & DRM_MODE_ROTATE_270)
283 val |= SCALER_ROT_CFG_SET_ROTMODE(SCALER_ROT_MODE_270);
284 if (rotation & DRM_MODE_REFLECT_X)
285 val |= SCALER_ROT_CFG_FLIP_X_EN;
286 if (rotation & DRM_MODE_REFLECT_Y)
287 val |= SCALER_ROT_CFG_FLIP_Y_EN;
288 scaler_write(val, SCALER_ROT_CFG);
289}
290
291static inline void scaler_set_csc(struct scaler_context *scaler,
292 const struct drm_format_info *fmt)
293{
294 static const u32 csc_mtx[2][3][3] = {
295 { /* YCbCr to RGB */
296 {0x254, 0x000, 0x331},
297 {0x254, 0xf38, 0xe60},
298 {0x254, 0x409, 0x000},
299 },
300 { /* RGB to YCbCr */
301 {0x084, 0x102, 0x032},
302 {0xfb4, 0xf6b, 0x0e1},
303 {0x0e1, 0xf44, 0xfdc},
304 },
305 };
306 int i, j, dir;
307
308 switch (fmt->format) {
309 case DRM_FORMAT_RGB565:
310 case DRM_FORMAT_XRGB1555:
311 case DRM_FORMAT_ARGB1555:
312 case DRM_FORMAT_XRGB4444:
313 case DRM_FORMAT_ARGB4444:
314 case DRM_FORMAT_XRGB8888:
315 case DRM_FORMAT_ARGB8888:
316 case DRM_FORMAT_RGBX8888:
317 case DRM_FORMAT_RGBA8888:
318 dir = 1;
319 break;
320 default:
321 dir = 0;
322 }
323
324 for (i = 0; i < 3; i++)
325 for (j = 0; j < 3; j++)
326 scaler_write(csc_mtx[dir][i][j], SCALER_CSC_COEF(j, i));
327}
328
329static inline void scaler_set_timer(struct scaler_context *scaler,
330 unsigned int timer, unsigned int divider)
331{
332 u32 val;
333
334 val = SCALER_TIMEOUT_CTRL_TIMER_ENABLE;
335 val |= SCALER_TIMEOUT_CTRL_SET_TIMER_VALUE(timer);
336 val |= SCALER_TIMEOUT_CTRL_SET_TIMER_DIV(divider);
337 scaler_write(val, SCALER_TIMEOUT_CTRL);
338}
339
340static inline void scaler_start_hw(struct scaler_context *scaler)
341{
342 scaler_write(SCALER_CFG_START_CMD, SCALER_CFG);
343}
344
345static int scaler_commit(struct exynos_drm_ipp *ipp,
346 struct exynos_drm_ipp_task *task)
347{
348 struct scaler_context *scaler =
349 container_of(ipp, struct scaler_context, ipp);
350
351 u32 src_fmt = scaler_get_format(task->src.buf.fourcc);
352 struct drm_exynos_ipp_task_rect *src_pos = &task->src.rect;
353
354 u32 dst_fmt = scaler_get_format(task->dst.buf.fourcc);
355 struct drm_exynos_ipp_task_rect *dst_pos = &task->dst.rect;
356
357 scaler->task = task;
358
359 pm_runtime_get_sync(scaler->dev);
360
361 scaler_set_src_fmt(scaler, src_fmt);
362 scaler_set_src_base(scaler, &task->src);
363 scaler_set_src_span(scaler, &task->src);
364 scaler_set_src_luma_pos(scaler, src_pos);
365 scaler_set_src_wh(scaler, src_pos);
366
367 scaler_set_dst_fmt(scaler, dst_fmt);
368 scaler_set_dst_base(scaler, &task->dst);
369 scaler_set_dst_span(scaler, &task->dst);
370 scaler_set_dst_luma_pos(scaler, dst_pos);
371 scaler_set_dst_wh(scaler, dst_pos);
372
373 scaler_set_hv_ratio(scaler, task->transform.rotation, src_pos, dst_pos);
374 scaler_set_rotation(scaler, task->transform.rotation);
375
376 scaler_set_csc(scaler, task->src.format);
377
378 scaler_set_timer(scaler, 0xffff, 0xf);
379
380 scaler_enable_int(scaler);
381 scaler_start_hw(scaler);
382
383 return 0;
384}
385
386static struct exynos_drm_ipp_funcs ipp_funcs = {
387 .commit = scaler_commit,
388};
389
390static inline void scaler_disable_int(struct scaler_context *scaler)
391{
392 scaler_write(0, SCALER_INT_EN);
393}
394
395static inline u32 scaler_get_int_status(struct scaler_context *scaler)
396{
397 return scaler_read(SCALER_INT_STATUS);
398}
399
400static inline int scaler_task_done(u32 val)
401{
402 return val & SCALER_INT_STATUS_FRAME_END ? 0 : -EINVAL;
403}
404
405static irqreturn_t scaler_irq_handler(int irq, void *arg)
406{
407 struct scaler_context *scaler = arg;
408
409 u32 val = scaler_get_int_status(scaler);
410
411 scaler_disable_int(scaler);
412
413 if (scaler->task) {
414 struct exynos_drm_ipp_task *task = scaler->task;
415
416 scaler->task = NULL;
417 pm_runtime_mark_last_busy(scaler->dev);
418 pm_runtime_put_autosuspend(scaler->dev);
419 exynos_drm_ipp_task_done(task, scaler_task_done(val));
420 }
421
422 return IRQ_HANDLED;
423}
424
425static int scaler_bind(struct device *dev, struct device *master, void *data)
426{
427 struct scaler_context *scaler = dev_get_drvdata(dev);
428 struct drm_device *drm_dev = data;
429 struct exynos_drm_ipp *ipp = &scaler->ipp;
430
431 scaler->drm_dev = drm_dev;
432 drm_iommu_attach_device(drm_dev, dev);
433
434 exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs,
435 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
436 DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT,
437 scaler->scaler_data->formats,
438 scaler->scaler_data->num_formats, "scaler");
439
440 dev_info(dev, "The exynos scaler has been probed successfully\n");
441
442 return 0;
443}
444
445static void scaler_unbind(struct device *dev, struct device *master,
446 void *data)
447{
448 struct scaler_context *scaler = dev_get_drvdata(dev);
449 struct drm_device *drm_dev = data;
450 struct exynos_drm_ipp *ipp = &scaler->ipp;
451
452 exynos_drm_ipp_unregister(drm_dev, ipp);
453 drm_iommu_detach_device(scaler->drm_dev, scaler->dev);
454}
455
456static const struct component_ops scaler_component_ops = {
457 .bind = scaler_bind,
458 .unbind = scaler_unbind,
459};
460
461static int scaler_probe(struct platform_device *pdev)
462{
463 struct device *dev = &pdev->dev;
464 struct resource *regs_res;
465 struct scaler_context *scaler;
466 int irq;
467 int ret, i;
468
469 scaler = devm_kzalloc(dev, sizeof(*scaler), GFP_KERNEL);
470 if (!scaler)
471 return -ENOMEM;
472
473 scaler->scaler_data =
474 (struct scaler_data *)of_device_get_match_data(dev);
475
476 scaler->dev = dev;
477 regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
478 scaler->regs = devm_ioremap_resource(dev, regs_res);
479 if (IS_ERR(scaler->regs))
480 return PTR_ERR(scaler->regs);
481
482 irq = platform_get_irq(pdev, 0);
483 if (irq < 0) {
484 dev_err(dev, "failed to get irq\n");
485 return irq;
486 }
487
488 ret = devm_request_threaded_irq(dev, irq, NULL, scaler_irq_handler,
489 IRQF_ONESHOT, "drm_scaler", scaler);
490 if (ret < 0) {
491 dev_err(dev, "failed to request irq\n");
492 return ret;
493 }
494
495 for (i = 0; i < scaler->scaler_data->num_clk; ++i) {
496 scaler->clock[i] = devm_clk_get(dev,
497 scaler->scaler_data->clk_name[i]);
498 if (IS_ERR(scaler->clock[i])) {
499 dev_err(dev, "failed to get clock\n");
500 return PTR_ERR(scaler->clock[i]);
501 }
502 }
503
504 pm_runtime_use_autosuspend(dev);
505 pm_runtime_set_autosuspend_delay(dev, SCALER_AUTOSUSPEND_DELAY);
506 pm_runtime_enable(dev);
507 platform_set_drvdata(pdev, scaler);
508
509 ret = component_add(dev, &scaler_component_ops);
510 if (ret)
511 goto err_ippdrv_register;
512
513 return 0;
514
515err_ippdrv_register:
516 pm_runtime_dont_use_autosuspend(dev);
517 pm_runtime_disable(dev);
518 return ret;
519}
520
521static int scaler_remove(struct platform_device *pdev)
522{
523 struct device *dev = &pdev->dev;
524
525 component_del(dev, &scaler_component_ops);
526 pm_runtime_dont_use_autosuspend(dev);
527 pm_runtime_disable(dev);
528
529 return 0;
530}
531
532#ifdef CONFIG_PM
533
534static int clk_disable_unprepare_wrapper(struct clk *clk)
535{
536 clk_disable_unprepare(clk);
537
538 return 0;
539}
540
541static int scaler_clk_ctrl(struct scaler_context *scaler, bool enable)
542{
543 int (*clk_fun)(struct clk *clk), i;
544
545 clk_fun = enable ? clk_prepare_enable : clk_disable_unprepare_wrapper;
546
547 for (i = 0; i < scaler->scaler_data->num_clk; ++i)
548 clk_fun(scaler->clock[i]);
549
550 return 0;
551}
552
553static int scaler_runtime_suspend(struct device *dev)
554{
555 struct scaler_context *scaler = dev_get_drvdata(dev);
556
557 return scaler_clk_ctrl(scaler, false);
558}
559
560static int scaler_runtime_resume(struct device *dev)
561{
562 struct scaler_context *scaler = dev_get_drvdata(dev);
563
564 return scaler_clk_ctrl(scaler, true);
565}
566#endif
567
568static const struct dev_pm_ops scaler_pm_ops = {
569 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
570 pm_runtime_force_resume)
571 SET_RUNTIME_PM_OPS(scaler_runtime_suspend, scaler_runtime_resume, NULL)
572};
573
574static const struct drm_exynos_ipp_limit scaler_5420_two_pixel_hv_limits[] = {
575 { IPP_SIZE_LIMIT(BUFFER, .h = { 16, SZ_8K }, .v = { 16, SZ_8K }) },
576 { IPP_SIZE_LIMIT(AREA, .h.align = 2, .v.align = 2) },
577 { IPP_SCALE_LIMIT(.h = { 65536 * 1 / 4, 65536 * 16 },
578 .v = { 65536 * 1 / 4, 65536 * 16 }) },
579};
580
581static const struct drm_exynos_ipp_limit scaler_5420_two_pixel_h_limits[] = {
582 { IPP_SIZE_LIMIT(BUFFER, .h = { 16, SZ_8K }, .v = { 16, SZ_8K }) },
583 { IPP_SIZE_LIMIT(AREA, .h.align = 2, .v.align = 1) },
584 { IPP_SCALE_LIMIT(.h = { 65536 * 1 / 4, 65536 * 16 },
585 .v = { 65536 * 1 / 4, 65536 * 16 }) },
586};
587
588static const struct drm_exynos_ipp_limit scaler_5420_one_pixel_limits[] = {
589 { IPP_SIZE_LIMIT(BUFFER, .h = { 16, SZ_8K }, .v = { 16, SZ_8K }) },
590 { IPP_SCALE_LIMIT(.h = { 65536 * 1 / 4, 65536 * 16 },
591 .v = { 65536 * 1 / 4, 65536 * 16 }) },
592};
593
594static const struct exynos_drm_ipp_formats exynos5420_formats[] = {
595 /* SCALER_YUV420_2P_UV */
596 { IPP_SRCDST_FORMAT(NV21, scaler_5420_two_pixel_hv_limits) },
597
598 /* SCALER_YUV420_2P_VU */
599 { IPP_SRCDST_FORMAT(NV12, scaler_5420_two_pixel_hv_limits) },
600
601 /* SCALER_YUV420_3P */
602 { IPP_SRCDST_FORMAT(YUV420, scaler_5420_two_pixel_hv_limits) },
603
604 /* SCALER_YUV422_1P_YUYV */
605 { IPP_SRCDST_FORMAT(YUYV, scaler_5420_two_pixel_h_limits) },
606
607 /* SCALER_YUV422_1P_UYVY */
608 { IPP_SRCDST_FORMAT(UYVY, scaler_5420_two_pixel_h_limits) },
609
610 /* SCALER_YUV422_1P_YVYU */
611 { IPP_SRCDST_FORMAT(YVYU, scaler_5420_two_pixel_h_limits) },
612
613 /* SCALER_YUV422_2P_UV */
614 { IPP_SRCDST_FORMAT(NV61, scaler_5420_two_pixel_h_limits) },
615
616 /* SCALER_YUV422_2P_VU */
617 { IPP_SRCDST_FORMAT(NV16, scaler_5420_two_pixel_h_limits) },
618
619 /* SCALER_YUV422_3P */
620 { IPP_SRCDST_FORMAT(YUV422, scaler_5420_two_pixel_h_limits) },
621
622 /* SCALER_YUV444_2P_UV */
623 { IPP_SRCDST_FORMAT(NV42, scaler_5420_one_pixel_limits) },
624
625 /* SCALER_YUV444_2P_VU */
626 { IPP_SRCDST_FORMAT(NV24, scaler_5420_one_pixel_limits) },
627
628 /* SCALER_YUV444_3P */
629 { IPP_SRCDST_FORMAT(YUV444, scaler_5420_one_pixel_limits) },
630
631 /* SCALER_RGB_565 */
632 { IPP_SRCDST_FORMAT(RGB565, scaler_5420_one_pixel_limits) },
633
634 /* SCALER_ARGB1555 */
635 { IPP_SRCDST_FORMAT(XRGB1555, scaler_5420_one_pixel_limits) },
636
637 /* SCALER_ARGB1555 */
638 { IPP_SRCDST_FORMAT(ARGB1555, scaler_5420_one_pixel_limits) },
639
640 /* SCALER_ARGB4444 */
641 { IPP_SRCDST_FORMAT(XRGB4444, scaler_5420_one_pixel_limits) },
642
643 /* SCALER_ARGB4444 */
644 { IPP_SRCDST_FORMAT(ARGB4444, scaler_5420_one_pixel_limits) },
645
646 /* SCALER_ARGB8888 */
647 { IPP_SRCDST_FORMAT(XRGB8888, scaler_5420_one_pixel_limits) },
648
649 /* SCALER_ARGB8888 */
650 { IPP_SRCDST_FORMAT(ARGB8888, scaler_5420_one_pixel_limits) },
651
652 /* SCALER_RGBA8888 */
653 { IPP_SRCDST_FORMAT(RGBX8888, scaler_5420_one_pixel_limits) },
654
655 /* SCALER_RGBA8888 */
656 { IPP_SRCDST_FORMAT(RGBA8888, scaler_5420_one_pixel_limits) },
657};
658
659static const struct scaler_data exynos5420_data = {
660 .clk_name = {"mscl"},
661 .num_clk = 1,
662 .formats = exynos5420_formats,
663 .num_formats = ARRAY_SIZE(exynos5420_formats),
664};
665
666static const struct scaler_data exynos5433_data = {
667 .clk_name = {"pclk", "aclk", "aclk_xiu"},
668 .num_clk = 3,
669 .formats = exynos5420_formats, /* intentional */
670 .num_formats = ARRAY_SIZE(exynos5420_formats),
671};
672
673static const struct of_device_id exynos_scaler_match[] = {
674 {
675 .compatible = "samsung,exynos5420-scaler",
676 .data = &exynos5420_data,
677 }, {
678 .compatible = "samsung,exynos5433-scaler",
679 .data = &exynos5433_data,
680 }, {
681 },
682};
683MODULE_DEVICE_TABLE(of, exynos_scaler_match);
684
685struct platform_driver scaler_driver = {
686 .probe = scaler_probe,
687 .remove = scaler_remove,
688 .driver = {
689 .name = "exynos-scaler",
690 .owner = THIS_MODULE,
691 .pm = &scaler_pm_ops,
692 .of_match_table = exynos_scaler_match,
693 },
694};
diff --git a/drivers/gpu/drm/exynos/regs-scaler.h b/drivers/gpu/drm/exynos/regs-scaler.h
new file mode 100644
index 000000000000..fc7ccad75e74
--- /dev/null
+++ b/drivers/gpu/drm/exynos/regs-scaler.h
@@ -0,0 +1,426 @@
1/* drivers/gpu/drm/exynos/regs-scaler.h
2 *
3 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
6 *
7 * Register definition file for Samsung scaler driver
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#ifndef EXYNOS_REGS_SCALER_H
15#define EXYNOS_REGS_SCALER_H
16
17/* Register part */
18
19/* Global setting */
20#define SCALER_STATUS 0x0 /* no shadow */
21#define SCALER_CFG 0x4
22
23/* Interrupt */
24#define SCALER_INT_EN 0x8 /* no shadow */
25#define SCALER_INT_STATUS 0xc /* no shadow */
26
27/* SRC */
28#define SCALER_SRC_CFG 0x10
29#define SCALER_SRC_Y_BASE 0x14
30#define SCALER_SRC_CB_BASE 0x18
31#define SCALER_SRC_CR_BASE 0x294
32#define SCALER_SRC_SPAN 0x1c
33#define SCALER_SRC_Y_POS 0x20
34#define SCALER_SRC_WH 0x24
35#define SCALER_SRC_C_POS 0x28
36
37/* DST */
38#define SCALER_DST_CFG 0x30
39#define SCALER_DST_Y_BASE 0x34
40#define SCALER_DST_CB_BASE 0x38
41#define SCALER_DST_CR_BASE 0x298
42#define SCALER_DST_SPAN 0x3c
43#define SCALER_DST_WH 0x40
44#define SCALER_DST_POS 0x44
45
46/* Ratio */
47#define SCALER_H_RATIO 0x50
48#define SCALER_V_RATIO 0x54
49
50/* Rotation */
51#define SCALER_ROT_CFG 0x58
52
53/* Coefficient */
54/*
55 * YHCOEF_{x}{A|B|C|D} CHCOEF_{x}{A|B|C|D}
56 *
57 * A B C D A B C D
58 * 0 60 64 68 6c 140 144 148 14c
59 * 1 70 74 78 7c 150 154 158 15c
60 * 2 80 84 88 8c 160 164 168 16c
61 * 3 90 94 98 9c 170 174 178 17c
62 * 4 a0 a4 a8 ac 180 184 188 18c
63 * 5 b0 b4 b8 bc 190 194 198 19c
64 * 6 c0 c4 c8 cc 1a0 1a4 1a8 1ac
65 * 7 d0 d4 d8 dc 1b0 1b4 1b8 1bc
66 * 8 e0 e4 e8 ec 1c0 1c4 1c8 1cc
67 *
68 *
69 * YVCOEF_{x}{A|B} CVCOEF_{x}{A|B}
70 *
71 * A B A B
72 * 0 f0 f4 1d0 1d4
73 * 1 f8 fc 1d8 1dc
74 * 2 100 104 1e0 1e4
75 * 3 108 10c 1e8 1ec
76 * 4 110 114 1f0 1f4
77 * 5 118 11c 1f8 1fc
78 * 6 120 124 200 204
79 * 7 128 12c 208 20c
80 * 8 130 134 210 214
81 */
82#define _SCALER_HCOEF_DELTA(r, c) ((r) * 0x10 + (c) * 0x4)
83#define _SCALER_VCOEF_DELTA(r, c) ((r) * 0x8 + (c) * 0x4)
84
85#define SCALER_YHCOEF(r, c) (0x60 + _SCALER_HCOEF_DELTA((r), (c)))
86#define SCALER_YVCOEF(r, c) (0xf0 + _SCALER_VCOEF_DELTA((r), (c)))
87#define SCALER_CHCOEF(r, c) (0x140 + _SCALER_HCOEF_DELTA((r), (c)))
88#define SCALER_CVCOEF(r, c) (0x1d0 + _SCALER_VCOEF_DELTA((r), (c)))
89
90
91/* Color Space Conversion */
92#define SCALER_CSC_COEF(x, y) (0x220 + (y) * 0xc + (x) * 0x4)
93
94/* Dithering */
95#define SCALER_DITH_CFG 0x250
96
97/* Version Number */
98#define SCALER_VER 0x260 /* no shadow */
99
100/* Cycle count and Timeout */
101#define SCALER_CYCLE_COUNT 0x278 /* no shadow */
102#define SCALER_TIMEOUT_CTRL 0x2c0 /* no shadow */
103#define SCALER_TIMEOUT_CNT 0x2c4 /* no shadow */
104
105/* Blending */
106#define SCALER_SRC_BLEND_COLOR 0x280
107#define SCALER_SRC_BLEND_ALPHA 0x284
108#define SCALER_DST_BLEND_COLOR 0x288
109#define SCALER_DST_BLEND_ALPHA 0x28c
110
111/* Color Fill */
112#define SCALER_FILL_COLOR 0x290
113
114/* Multiple Command Queue */
115#define SCALER_ADDR_Q_CONFIG 0x2a0 /* no shadow */
116#define SCALER_SRC_ADDR_Q_STATUS 0x2a4 /* no shadow */
117#define SCALER_SRC_ADDR_Q 0x2a8 /* no shadow */
118
119/* CRC */
120#define SCALER_CRC_COLOR00_10 0x2b0 /* no shadow */
121#define SCALER_CRC_COLOR20_30 0x2b4 /* no shadow */
122#define SCALER_CRC_COLOR01_11 0x2b8 /* no shadow */
123#define SCALER_CRC_COLOR21_31 0x2bc /* no shadow */
124
125/* Shadow Registers */
126#define SCALER_SHADOW_OFFSET 0x1000
127
128
129/* Bit definition part */
130#define SCALER_MASK(hi_b, lo_b) ((1 << ((hi_b) - (lo_b) + 1)) - 1)
131#define SCALER_GET(reg, hi_b, lo_b) \
132 (((reg) >> (lo_b)) & SCALER_MASK(hi_b, lo_b))
133#define SCALER_SET(val, hi_b, lo_b) \
134 (((val) & SCALER_MASK(hi_b, lo_b)) << lo_b)
135
136/* SCALER_STATUS */
137#define SCALER_STATUS_SCALER_RUNNING (1 << 1)
138#define SCALER_STATUS_SCALER_READY_CLK_DOWN (1 << 0)
139
140/* SCALER_CFG */
141#define SCALER_CFG_FILL_EN (1 << 24)
142#define SCALER_CFG_BLEND_COLOR_DIVIDE_ALPHA_EN (1 << 17)
143#define SCALER_CFG_BLEND_EN (1 << 16)
144#define SCALER_CFG_CSC_Y_OFFSET_SRC_EN (1 << 10)
145#define SCALER_CFG_CSC_Y_OFFSET_DST_EN (1 << 9)
146#define SCALER_CFG_16_BURST_MODE (1 << 8)
147#define SCALER_CFG_SOFT_RESET (1 << 1)
148#define SCALER_CFG_START_CMD (1 << 0)
149
150/* SCALER_INT_EN */
151#define SCALER_INT_EN_TIMEOUT (1 << 31)
152#define SCALER_INT_EN_ILLEGAL_BLEND (1 << 24)
153#define SCALER_INT_EN_ILLEGAL_RATIO (1 << 23)
154#define SCALER_INT_EN_ILLEGAL_DST_HEIGHT (1 << 22)
155#define SCALER_INT_EN_ILLEGAL_DST_WIDTH (1 << 21)
156#define SCALER_INT_EN_ILLEGAL_DST_V_POS (1 << 20)
157#define SCALER_INT_EN_ILLEGAL_DST_H_POS (1 << 19)
158#define SCALER_INT_EN_ILLEGAL_DST_C_SPAN (1 << 18)
159#define SCALER_INT_EN_ILLEGAL_DST_Y_SPAN (1 << 17)
160#define SCALER_INT_EN_ILLEGAL_DST_CR_BASE (1 << 16)
161#define SCALER_INT_EN_ILLEGAL_DST_CB_BASE (1 << 15)
162#define SCALER_INT_EN_ILLEGAL_DST_Y_BASE (1 << 14)
163#define SCALER_INT_EN_ILLEGAL_DST_COLOR (1 << 13)
164#define SCALER_INT_EN_ILLEGAL_SRC_HEIGHT (1 << 12)
165#define SCALER_INT_EN_ILLEGAL_SRC_WIDTH (1 << 11)
166#define SCALER_INT_EN_ILLEGAL_SRC_CV_POS (1 << 10)
167#define SCALER_INT_EN_ILLEGAL_SRC_CH_POS (1 << 9)
168#define SCALER_INT_EN_ILLEGAL_SRC_YV_POS (1 << 8)
169#define SCALER_INT_EN_ILLEGAL_SRC_YH_POS (1 << 7)
170#define SCALER_INT_EN_ILLEGAL_DST_SPAN (1 << 6)
171#define SCALER_INT_EN_ILLEGAL_SRC_Y_SPAN (1 << 5)
172#define SCALER_INT_EN_ILLEGAL_SRC_CR_BASE (1 << 4)
173#define SCALER_INT_EN_ILLEGAL_SRC_CB_BASE (1 << 3)
174#define SCALER_INT_EN_ILLEGAL_SRC_Y_BASE (1 << 2)
175#define SCALER_INT_EN_ILLEGAL_SRC_COLOR (1 << 1)
176#define SCALER_INT_EN_FRAME_END (1 << 0)
177
178/* SCALER_INT_STATUS */
179#define SCALER_INT_STATUS_TIMEOUT (1 << 31)
180#define SCALER_INT_STATUS_ILLEGAL_BLEND (1 << 24)
181#define SCALER_INT_STATUS_ILLEGAL_RATIO (1 << 23)
182#define SCALER_INT_STATUS_ILLEGAL_DST_HEIGHT (1 << 22)
183#define SCALER_INT_STATUS_ILLEGAL_DST_WIDTH (1 << 21)
184#define SCALER_INT_STATUS_ILLEGAL_DST_V_POS (1 << 20)
185#define SCALER_INT_STATUS_ILLEGAL_DST_H_POS (1 << 19)
186#define SCALER_INT_STATUS_ILLEGAL_DST_C_SPAN (1 << 18)
187#define SCALER_INT_STATUS_ILLEGAL_DST_Y_SPAN (1 << 17)
188#define SCALER_INT_STATUS_ILLEGAL_DST_CR_BASE (1 << 16)
189#define SCALER_INT_STATUS_ILLEGAL_DST_CB_BASE (1 << 15)
190#define SCALER_INT_STATUS_ILLEGAL_DST_Y_BASE (1 << 14)
191#define SCALER_INT_STATUS_ILLEGAL_DST_COLOR (1 << 13)
192#define SCALER_INT_STATUS_ILLEGAL_SRC_HEIGHT (1 << 12)
193#define SCALER_INT_STATUS_ILLEGAL_SRC_WIDTH (1 << 11)
194#define SCALER_INT_STATUS_ILLEGAL_SRC_CV_POS (1 << 10)
195#define SCALER_INT_STATUS_ILLEGAL_SRC_CH_POS (1 << 9)
196#define SCALER_INT_STATUS_ILLEGAL_SRC_YV_POS (1 << 8)
197#define SCALER_INT_STATUS_ILLEGAL_SRC_YH_POS (1 << 7)
198#define SCALER_INT_STATUS_ILLEGAL_DST_SPAN (1 << 6)
199#define SCALER_INT_STATUS_ILLEGAL_SRC_Y_SPAN (1 << 5)
200#define SCALER_INT_STATUS_ILLEGAL_SRC_CR_BASE (1 << 4)
201#define SCALER_INT_STATUS_ILLEGAL_SRC_CB_BASE (1 << 3)
202#define SCALER_INT_STATUS_ILLEGAL_SRC_Y_BASE (1 << 2)
203#define SCALER_INT_STATUS_ILLEGAL_SRC_COLOR (1 << 1)
204#define SCALER_INT_STATUS_FRAME_END (1 << 0)
205
206/* SCALER_SRC_CFG */
207#define SCALER_SRC_CFG_TILE_EN (1 << 10)
208#define SCALER_SRC_CFG_GET_BYTE_SWAP(r) SCALER_GET(r, 6, 5)
209#define SCALER_SRC_CFG_SET_BYTE_SWAP(v) SCALER_SET(v, 6, 5)
210#define SCALER_SRC_CFG_GET_COLOR_FORMAT(r) SCALER_GET(r, 4, 0)
211#define SCALER_SRC_CFG_SET_COLOR_FORMAT(v) SCALER_SET(v, 4, 0)
212#define SCALER_YUV420_2P_UV 0
213#define SCALER_YUV422_2P_UV 2
214#define SCALER_YUV444_2P_UV 3
215#define SCALER_RGB_565 4
216#define SCALER_ARGB1555 5
217#define SCALER_ARGB8888 6
218#define SCALER_ARGB8888_PRE 7
219#define SCALER_YUV422_1P_YVYU 9
220#define SCALER_YUV422_1P_YUYV 10
221#define SCALER_YUV422_1P_UYVY 11
222#define SCALER_ARGB4444 12
223#define SCALER_L8A8 13
224#define SCALER_RGBA8888 14
225#define SCALER_L8 15
226#define SCALER_YUV420_2P_VU 16
227#define SCALER_YUV422_2P_VU 18
228#define SCALER_YUV444_2P_VU 19
229#define SCALER_YUV420_3P 20
230#define SCALER_YUV422_3P 22
231#define SCALER_YUV444_3P 23
232
233/* SCALER_SRC_SPAN */
234#define SCALER_SRC_SPAN_GET_C_SPAN(r) SCALER_GET(r, 29, 16)
235#define SCALER_SRC_SPAN_SET_C_SPAN(v) SCALER_SET(v, 29, 16)
236#define SCALER_SRC_SPAN_GET_Y_SPAN(r) SCALER_GET(r, 13, 0)
237#define SCALER_SRC_SPAN_SET_Y_SPAN(v) SCALER_SET(v, 13, 0)
238
239/* SCALER_SRC_Y_POS */
240#define SCALER_SRC_Y_POS_GET_YH_POS(r) SCALER_GET(r, 31, 16)
241#define SCALER_SRC_Y_POS_SET_YH_POS(v) SCALER_SET(v, 31, 16)
242#define SCALER_SRC_Y_POS_GET_YV_POS(r) SCALER_GET(r, 15, 0)
243#define SCALER_SRC_Y_POS_SET_YV_POS(v) SCALER_SET(v, 15, 0)
244
245/* SCALER_SRC_WH */
246#define SCALER_SRC_WH_GET_WIDTH(r) SCALER_GET(r, 29, 16)
247#define SCALER_SRC_WH_SET_WIDTH(v) SCALER_SET(v, 29, 16)
248#define SCALER_SRC_WH_GET_HEIGHT(r) SCALER_GET(r, 13, 0)
249#define SCALER_SRC_WH_SET_HEIGHT(v) SCALER_SET(v, 13, 0)
250
251/* SCALER_SRC_C_POS */
252#define SCALER_SRC_C_POS_GET_CH_POS(r) SCALER_GET(r, 31, 16)
253#define SCALER_SRC_C_POS_SET_CH_POS(v) SCALER_SET(v, 31, 16)
254#define SCALER_SRC_C_POS_GET_CV_POS(r) SCALER_GET(r, 15, 0)
255#define SCALER_SRC_C_POS_SET_CV_POS(v) SCALER_SET(v, 15, 0)
256
257/* SCALER_DST_CFG */
258#define SCALER_DST_CFG_GET_BYTE_SWAP(r) SCALER_GET(r, 6, 5)
259#define SCALER_DST_CFG_SET_BYTE_SWAP(v) SCALER_SET(v, 6, 5)
260#define SCALER_DST_CFG_GET_COLOR_FORMAT(r) SCALER_GET(r, 4, 0)
261#define SCALER_DST_CFG_SET_COLOR_FORMAT(v) SCALER_SET(v, 4, 0)
262
263/* SCALER_DST_SPAN */
264#define SCALER_DST_SPAN_GET_C_SPAN(r) SCALER_GET(r, 29, 16)
265#define SCALER_DST_SPAN_SET_C_SPAN(v) SCALER_SET(v, 29, 16)
266#define SCALER_DST_SPAN_GET_Y_SPAN(r) SCALER_GET(r, 13, 0)
267#define SCALER_DST_SPAN_SET_Y_SPAN(v) SCALER_SET(v, 13, 0)
268
269/* SCALER_DST_WH */
270#define SCALER_DST_WH_GET_WIDTH(r) SCALER_GET(r, 29, 16)
271#define SCALER_DST_WH_SET_WIDTH(v) SCALER_SET(v, 29, 16)
272#define SCALER_DST_WH_GET_HEIGHT(r) SCALER_GET(r, 13, 0)
273#define SCALER_DST_WH_SET_HEIGHT(v) SCALER_SET(v, 13, 0)
274
275/* SCALER_DST_POS */
276#define SCALER_DST_POS_GET_H_POS(r) SCALER_GET(r, 29, 16)
277#define SCALER_DST_POS_SET_H_POS(v) SCALER_SET(v, 29, 16)
278#define SCALER_DST_POS_GET_V_POS(r) SCALER_GET(r, 13, 0)
279#define SCALER_DST_POS_SET_V_POS(v) SCALER_SET(v, 13, 0)
280
281/* SCALER_H_RATIO */
282#define SCALER_H_RATIO_GET(r) SCALER_GET(r, 18, 0)
283#define SCALER_H_RATIO_SET(v) SCALER_SET(v, 18, 0)
284
285/* SCALER_V_RATIO */
286#define SCALER_V_RATIO_GET(r) SCALER_GET(r, 18, 0)
287#define SCALER_V_RATIO_SET(v) SCALER_SET(v, 18, 0)
288
289/* SCALER_ROT_CFG */
290#define SCALER_ROT_CFG_FLIP_X_EN (1 << 3)
291#define SCALER_ROT_CFG_FLIP_Y_EN (1 << 2)
292#define SCALER_ROT_CFG_GET_ROTMODE(r) SCALER_GET(r, 1, 0)
293#define SCALER_ROT_CFG_SET_ROTMODE(v) SCALER_SET(v, 1, 0)
294#define SCALER_ROT_MODE_90 1
295#define SCALER_ROT_MODE_180 2
296#define SCALER_ROT_MODE_270 3
297
298/* SCALER_HCOEF, SCALER_VCOEF */
299#define SCALER_COEF_SHIFT(i) (16 * (1 - (i) % 2))
300#define SCALER_COEF_GET(r, i) \
301 (((r) >> SCALER_COEF_SHIFT(i)) & 0x1ff)
302#define SCALER_COEF_SET(v, i) \
303 (((v) & 0x1ff) << SCALER_COEF_SHIFT(i))
304
305/* SCALER_CSC_COEFxy */
306#define SCALER_CSC_COEF_GET(r) SCALER_GET(r, 11, 0)
307#define SCALER_CSC_COEF_SET(v) SCALER_SET(v, 11, 0)
308
309/* SCALER_DITH_CFG */
310#define SCALER_DITH_CFG_GET_R_TYPE(r) SCALER_GET(r, 8, 6)
311#define SCALER_DITH_CFG_SET_R_TYPE(v) SCALER_SET(v, 8, 6)
312#define SCALER_DITH_CFG_GET_G_TYPE(r) SCALER_GET(r, 5, 3)
313#define SCALER_DITH_CFG_SET_G_TYPE(v) SCALER_SET(v, 5, 3)
314#define SCALER_DITH_CFG_GET_B_TYPE(r) SCALER_GET(r, 2, 0)
315#define SCALER_DITH_CFG_SET_B_TYPE(v) SCALER_SET(v, 2, 0)
316
317/* SCALER_TIMEOUT_CTRL */
318#define SCALER_TIMEOUT_CTRL_GET_TIMER_VALUE(r) SCALER_GET(r, 31, 16)
319#define SCALER_TIMEOUT_CTRL_SET_TIMER_VALUE(v) SCALER_SET(v, 31, 16)
320#define SCALER_TIMEOUT_CTRL_GET_TIMER_DIV(r) SCALER_GET(r, 7, 4)
321#define SCALER_TIMEOUT_CTRL_SET_TIMER_DIV(v) SCALER_SET(v, 7, 4)
322#define SCALER_TIMEOUT_CTRL_TIMER_ENABLE (1 << 0)
323
324/* SCALER_TIMEOUT_CNT */
325#define SCALER_TIMEOUT_CTRL_GET_TIMER_COUNT(r) SCALER_GET(r, 31, 16)
326
327/* SCALER_SRC_BLEND_COLOR */
328#define SCALER_SRC_BLEND_COLOR_SEL_INV (1 << 31)
329#define SCALER_SRC_BLEND_COLOR_GET_SEL(r) SCALER_GET(r, 30, 29)
330#define SCALER_SRC_BLEND_COLOR_SET_SEL(v) SCALER_SET(v, 30, 29)
331#define SCALER_SRC_BLEND_COLOR_OP_SEL_INV (1 << 28)
332#define SCALER_SRC_BLEND_COLOR_GET_OP_SEL(r) SCALER_GET(r, 27, 24)
333#define SCALER_SRC_BLEND_COLOR_SET_OP_SEL(v) SCALER_SET(v, 27, 24)
334#define SCALER_SRC_BLEND_COLOR_GET_COLOR0(r) SCALER_GET(r, 23, 16)
335#define SCALER_SRC_BLEND_COLOR_SET_COLOR0(v) SCALER_SET(v, 23, 16)
336#define SCALER_SRC_BLEND_COLOR_GET_COLOR1(r) SCALER_GET(r, 15, 8)
337#define SCALER_SRC_BLEND_COLOR_SET_COLOR1(v) SCALER_SET(v, 15, 8)
338#define SCALER_SRC_BLEND_COLOR_GET_COLOR2(r) SCALER_GET(r, 7, 0)
339#define SCALER_SRC_BLEND_COLOR_SET_COLOR2(v) SCALER_SET(v, 7, 0)
340
341/* SCALER_SRC_BLEND_ALPHA */
342#define SCALER_SRC_BLEND_ALPHA_SEL_INV (1 << 31)
343#define SCALER_SRC_BLEND_ALPHA_GET_SEL(r) SCALER_GET(r, 30, 29)
344#define SCALER_SRC_BLEND_ALPHA_SET_SEL(v) SCALER_SET(v, 30, 29)
345#define SCALER_SRC_BLEND_ALPHA_OP_SEL_INV (1 << 28)
346#define SCALER_SRC_BLEND_ALPHA_GET_OP_SEL(r) SCALER_GET(r, 27, 24)
347#define SCALER_SRC_BLEND_ALPHA_SET_OP_SEL(v) SCALER_SET(v, 27, 24)
348#define SCALER_SRC_BLEND_ALPHA_GET_ALPHA(r) SCALER_GET(r, 7, 0)
349#define SCALER_SRC_BLEND_ALPHA_SET_ALPHA(v) SCALER_SET(v, 7, 0)
350
351/* SCALER_DST_BLEND_COLOR */
352#define SCALER_DST_BLEND_COLOR_SEL_INV (1 << 31)
353#define SCALER_DST_BLEND_COLOR_GET_SEL(r) SCALER_GET(r, 30, 29)
354#define SCALER_DST_BLEND_COLOR_SET_SEL(v) SCALER_SET(v, 30, 29)
355#define SCALER_DST_BLEND_COLOR_OP_SEL_INV (1 << 28)
356#define SCALER_DST_BLEND_COLOR_GET_OP_SEL(r) SCALER_GET(r, 27, 24)
357#define SCALER_DST_BLEND_COLOR_SET_OP_SEL(v) SCALER_SET(v, 27, 24)
358#define SCALER_DST_BLEND_COLOR_GET_COLOR0(r) SCALER_GET(r, 23, 16)
359#define SCALER_DST_BLEND_COLOR_SET_COLOR0(v) SCALER_SET(v, 23, 16)
360#define SCALER_DST_BLEND_COLOR_GET_COLOR1(r) SCALER_GET(r, 15, 8)
361#define SCALER_DST_BLEND_COLOR_SET_COLOR1(v) SCALER_SET(v, 15, 8)
362#define SCALER_DST_BLEND_COLOR_GET_COLOR2(r) SCALER_GET(r, 7, 0)
363#define SCALER_DST_BLEND_COLOR_SET_COLOR2(v) SCALER_SET(v, 7, 0)
364
365/* SCALER_DST_BLEND_ALPHA */
366#define SCALER_DST_BLEND_ALPHA_SEL_INV (1 << 31)
367#define SCALER_DST_BLEND_ALPHA_GET_SEL(r) SCALER_GET(r, 30, 29)
368#define SCALER_DST_BLEND_ALPHA_SET_SEL(v) SCALER_SET(v, 30, 29)
369#define SCALER_DST_BLEND_ALPHA_OP_SEL_INV (1 << 28)
370#define SCALER_DST_BLEND_ALPHA_GET_OP_SEL(r) SCALER_GET(r, 27, 24)
371#define SCALER_DST_BLEND_ALPHA_SET_OP_SEL(v) SCALER_SET(v, 27, 24)
372#define SCALER_DST_BLEND_ALPHA_GET_ALPHA(r) SCALER_GET(r, 7, 0)
373#define SCALER_DST_BLEND_ALPHA_SET_ALPHA(v) SCALER_SET(v, 7, 0)
374
375/* SCALER_FILL_COLOR */
376#define SCALER_FILL_COLOR_GET_ALPHA(r) SCALER_GET(r, 31, 24)
377#define SCALER_FILL_COLOR_SET_ALPHA(v) SCALER_SET(v, 31, 24)
378#define SCALER_FILL_COLOR_GET_FILL_COLOR0(r) SCALER_GET(r, 23, 16)
379#define SCALER_FILL_COLOR_SET_FILL_COLOR0(v) SCALER_SET(v, 23, 16)
380#define SCALER_FILL_COLOR_GET_FILL_COLOR1(r) SCALER_GET(r, 15, 8)
381#define SCALER_FILL_COLOR_SET_FILL_COLOR1(v) SCALER_SET(v, 15, 8)
382#define SCALER_FILL_COLOR_GET_FILL_COLOR2(r) SCALER_GET(r, 7, 0)
383#define SCALER_FILL_COLOR_SET_FILL_COLOR2(v) SCALER_SET(v, 7, 0)
384
385/* SCALER_ADDR_Q_CONFIG */
386#define SCALER_ADDR_Q_CONFIG_RST (1 << 0)
387
388/* SCALER_SRC_ADDR_Q_STATUS */
389#define SCALER_SRC_ADDR_Q_STATUS_Y_FULL (1 << 23)
390#define SCALER_SRC_ADDR_Q_STATUS_Y_EMPTY (1 << 22)
391#define SCALER_SRC_ADDR_Q_STATUS_GET_Y_WR_IDX(r) SCALER_GET(r, 21, 16)
392#define SCALER_SRC_ADDR_Q_STATUS_CB_FULL (1 << 15)
393#define SCALER_SRC_ADDR_Q_STATUS_CB_EMPTY (1 << 14)
394#define SCALER_SRC_ADDR_Q_STATUS_GET_CB_WR_IDX(r) SCALER_GET(r, 13, 8)
395#define SCALER_SRC_ADDR_Q_STATUS_CR_FULL (1 << 7)
396#define SCALER_SRC_ADDR_Q_STATUS_CR_EMPTY (1 << 6)
397#define SCALER_SRC_ADDR_Q_STATUS_GET_CR_WR_IDX(r) SCALER_GET(r, 5, 0)
398
399/* SCALER_DST_ADDR_Q_STATUS */
400#define SCALER_DST_ADDR_Q_STATUS_Y_FULL (1 << 23)
401#define SCALER_DST_ADDR_Q_STATUS_Y_EMPTY (1 << 22)
402#define SCALER_DST_ADDR_Q_STATUS_GET_Y_WR_IDX(r) SCALER_GET(r, 21, 16)
403#define SCALER_DST_ADDR_Q_STATUS_CB_FULL (1 << 15)
404#define SCALER_DST_ADDR_Q_STATUS_CB_EMPTY (1 << 14)
405#define SCALER_DST_ADDR_Q_STATUS_GET_CB_WR_IDX(r) SCALER_GET(r, 13, 8)
406#define SCALER_DST_ADDR_Q_STATUS_CR_FULL (1 << 7)
407#define SCALER_DST_ADDR_Q_STATUS_CR_EMPTY (1 << 6)
408#define SCALER_DST_ADDR_Q_STATUS_GET_CR_WR_IDX(r) SCALER_GET(r, 5, 0)
409
410/* SCALER_CRC_COLOR00_10 */
411#define SCALER_CRC_COLOR00_10_GET_00(r) SCALER_GET(r, 31, 16)
412#define SCALER_CRC_COLOR00_10_GET_10(r) SCALER_GET(r, 15, 0)
413
414/* SCALER_CRC_COLOR20_30 */
415#define SCALER_CRC_COLOR20_30_GET_20(r) SCALER_GET(r, 31, 16)
416#define SCALER_CRC_COLOR20_30_GET_30(r) SCALER_GET(r, 15, 0)
417
418/* SCALER_CRC_COLOR01_11 */
419#define SCALER_CRC_COLOR01_11_GET_01(r) SCALER_GET(r, 31, 16)
420#define SCALER_CRC_COLOR01_11_GET_11(r) SCALER_GET(r, 15, 0)
421
422/* SCALER_CRC_COLOR21_31 */
423#define SCALER_CRC_COLOR21_31_GET_21(r) SCALER_GET(r, 31, 16)
424#define SCALER_CRC_COLOR21_31_GET_31(r) SCALER_GET(r, 15, 0)
425
426#endif /* EXYNOS_REGS_SCALER_H */
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index 3a3bf752e03a..34b85767e4da 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -485,7 +485,7 @@ void cdv_intel_attach_force_audio_property(struct drm_connector *connector)
485 return; 485 return;
486 486
487 for (i = 0; i < ARRAY_SIZE(force_audio_names); i++) 487 for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
488 drm_property_add_enum(prop, i, i-1, force_audio_names[i]); 488 drm_property_add_enum(prop, i-1, force_audio_names[i]);
489 489
490 dev_priv->force_audio_property = prop; 490 dev_priv->force_audio_property = prop;
491 } 491 }
@@ -514,7 +514,7 @@ void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector)
514 return; 514 return;
515 515
516 for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++) 516 for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++)
517 drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]); 517 drm_property_add_enum(prop, i, broadcast_rgb_names[i]);
518 518
519 dev_priv->broadcast_rgb_property = prop; 519 dev_priv->broadcast_rgb_property = prop;
520 } 520 }
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index b837e7a92196..cb5a14b7ec7f 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -64,7 +64,7 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode)
64 REG_WRITE(reg, temp); 64 REG_WRITE(reg, temp);
65} 65}
66 66
67static int cdv_intel_crt_mode_valid(struct drm_connector *connector, 67static enum drm_mode_status cdv_intel_crt_mode_valid(struct drm_connector *connector,
68 struct drm_display_mode *mode) 68 struct drm_display_mode *mode)
69{ 69{
70 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 70 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c
index a4bb89b7878f..5ea785f07ba8 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_dp.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c
@@ -505,7 +505,7 @@ static void cdv_intel_edp_backlight_off (struct gma_encoder *intel_encoder)
505 msleep(intel_dp->backlight_off_delay); 505 msleep(intel_dp->backlight_off_delay);
506} 506}
507 507
508static int 508static enum drm_mode_status
509cdv_intel_dp_mode_valid(struct drm_connector *connector, 509cdv_intel_dp_mode_valid(struct drm_connector *connector,
510 struct drm_display_mode *mode) 510 struct drm_display_mode *mode)
511{ 511{
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index 563f193fcfac..f0878998526a 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -223,7 +223,7 @@ static int cdv_hdmi_get_modes(struct drm_connector *connector)
223 return ret; 223 return ret;
224} 224}
225 225
226static int cdv_hdmi_mode_valid(struct drm_connector *connector, 226static enum drm_mode_status cdv_hdmi_mode_valid(struct drm_connector *connector,
227 struct drm_display_mode *mode) 227 struct drm_display_mode *mode)
228{ 228{
229 if (mode->clock > 165000) 229 if (mode->clock > 165000)
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index e64960db3224..de9531caaca0 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -244,7 +244,7 @@ static void cdv_intel_lvds_restore(struct drm_connector *connector)
244{ 244{
245} 245}
246 246
247static int cdv_intel_lvds_mode_valid(struct drm_connector *connector, 247static enum drm_mode_status cdv_intel_lvds_mode_valid(struct drm_connector *connector,
248 struct drm_display_mode *mode) 248 struct drm_display_mode *mode)
249{ 249{
250 struct drm_device *dev = connector->dev; 250 struct drm_device *dev = connector->dev;
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
index acb3848ef1c9..fe020926ea4f 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
@@ -346,7 +346,7 @@ static int mdfld_dsi_connector_get_modes(struct drm_connector *connector)
346 return 0; 346 return 0;
347} 347}
348 348
349static int mdfld_dsi_connector_mode_valid(struct drm_connector *connector, 349static enum drm_mode_status mdfld_dsi_connector_mode_valid(struct drm_connector *connector,
350 struct drm_display_mode *mode) 350 struct drm_display_mode *mode)
351{ 351{
352 struct mdfld_dsi_connector *dsi_connector = 352 struct mdfld_dsi_connector *dsi_connector =
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
index 8b2eb32ee988..78566a80ad25 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -509,7 +509,7 @@ static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
509 HDMI_WRITE(HDMI_VIDEO_REG, temp); 509 HDMI_WRITE(HDMI_VIDEO_REG, temp);
510} 510}
511 511
512static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, 512static enum drm_mode_status oaktrail_hdmi_mode_valid(struct drm_connector *connector,
513 struct drm_display_mode *mode) 513 struct drm_display_mode *mode)
514{ 514{
515 if (mode->clock > 165000) 515 if (mode->clock > 165000)
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index e8e4ea14b12b..e05e5399af2d 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -255,7 +255,7 @@ extern int intelfb_remove(struct drm_device *dev,
255extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, 255extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
256 const struct drm_display_mode *mode, 256 const struct drm_display_mode *mode,
257 struct drm_display_mode *adjusted_mode); 257 struct drm_display_mode *adjusted_mode);
258extern int psb_intel_lvds_mode_valid(struct drm_connector *connector, 258extern enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector,
259 struct drm_display_mode *mode); 259 struct drm_display_mode *mode);
260extern int psb_intel_lvds_set_property(struct drm_connector *connector, 260extern int psb_intel_lvds_set_property(struct drm_connector *connector,
261 struct drm_property *property, 261 struct drm_property *property,
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
index be3eefec5152..8baf6325c6e4 100644
--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -343,7 +343,7 @@ static void psb_intel_lvds_restore(struct drm_connector *connector)
343 } 343 }
344} 344}
345 345
346int psb_intel_lvds_mode_valid(struct drm_connector *connector, 346enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector,
347 struct drm_display_mode *mode) 347 struct drm_display_mode *mode)
348{ 348{
349 struct drm_psb_private *dev_priv = connector->dev->dev_private; 349 struct drm_psb_private *dev_priv = connector->dev->dev_private;
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index 84507912be84..f2ee6aa10afa 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -1157,7 +1157,7 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
1157 return; 1157 return;
1158} 1158}
1159 1159
1160static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, 1160static enum drm_mode_status psb_intel_sdvo_mode_valid(struct drm_connector *connector,
1161 struct drm_display_mode *mode) 1161 struct drm_display_mode *mode)
1162{ 1162{
1163 struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); 1163 struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
@@ -2281,7 +2281,7 @@ static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_s
2281 2281
2282 for (i = 0; i < psb_intel_sdvo_connector->format_supported_num; i++) 2282 for (i = 0; i < psb_intel_sdvo_connector->format_supported_num; i++)
2283 drm_property_add_enum( 2283 drm_property_add_enum(
2284 psb_intel_sdvo_connector->tv_format, i, 2284 psb_intel_sdvo_connector->tv_format,
2285 i, tv_format_names[psb_intel_sdvo_connector->tv_format_supported[i]]); 2285 i, tv_format_names[psb_intel_sdvo_connector->tv_format_supported[i]]);
2286 2286
2287 psb_intel_sdvo->tv_format_index = psb_intel_sdvo_connector->tv_format_supported[0]; 2287 psb_intel_sdvo->tv_format_index = psb_intel_sdvo_connector->tv_format_supported[0];
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index f4eba87c96f3..d2f4749ebf8d 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -27,7 +27,7 @@ static int hibmc_connector_get_modes(struct drm_connector *connector)
27 return drm_add_modes_noedid(connector, 800, 600); 27 return drm_add_modes_noedid(connector, 800, 600);
28} 28}
29 29
30static int hibmc_connector_mode_valid(struct drm_connector *connector, 30static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *connector,
31 struct drm_display_mode *mode) 31 struct drm_display_mode *mode)
32{ 32{
33 return MODE_OK; 33 return MODE_OK;
diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
index a6c92beb410a..65d3acb61c03 100644
--- a/drivers/gpu/drm/i2c/Kconfig
+++ b/drivers/gpu/drm/i2c/Kconfig
@@ -22,8 +22,14 @@ config DRM_I2C_SIL164
22config DRM_I2C_NXP_TDA998X 22config DRM_I2C_NXP_TDA998X
23 tristate "NXP Semiconductors TDA998X HDMI encoder" 23 tristate "NXP Semiconductors TDA998X HDMI encoder"
24 default m if DRM_TILCDC 24 default m if DRM_TILCDC
25 select CEC_CORE if CEC_NOTIFIER
25 select SND_SOC_HDMI_CODEC if SND_SOC 26 select SND_SOC_HDMI_CODEC if SND_SOC
26 help 27 help
27 Support for NXP Semiconductors TDA998X HDMI encoders. 28 Support for NXP Semiconductors TDA998X HDMI encoders.
28 29
30config DRM_I2C_NXP_TDA9950
31 tristate "NXP Semiconductors TDA9950/TDA998X HDMI CEC"
32 select CEC_NOTIFIER
33 select CEC_CORE
34
29endmenu 35endmenu
diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile
index b20100c18ffb..a962f6f08568 100644
--- a/drivers/gpu/drm/i2c/Makefile
+++ b/drivers/gpu/drm/i2c/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o
7 7
8tda998x-y := tda998x_drv.o 8tda998x-y := tda998x_drv.o
9obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o 9obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o
10obj-$(CONFIG_DRM_I2C_NXP_TDA9950) += tda9950.o
diff --git a/drivers/gpu/drm/i2c/tda9950.c b/drivers/gpu/drm/i2c/tda9950.c
new file mode 100644
index 000000000000..3f7396caad48
--- /dev/null
+++ b/drivers/gpu/drm/i2c/tda9950.c
@@ -0,0 +1,509 @@
1/*
2 * TDA9950 Consumer Electronics Control driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * The NXP TDA9950 implements the HDMI Consumer Electronics Control
9 * interface. The host interface is similar to a mailbox: the data
10 * registers starting at REG_CDR0 are written to send a command to the
11 * internal CPU, and replies are read from these registers.
12 *
13 * As the data registers represent a mailbox, they must be accessed
14 * as a single I2C transaction. See the TDA9950 data sheet for details.
15 */
16#include <linux/delay.h>
17#include <linux/i2c.h>
18#include <linux/interrupt.h>
19#include <linux/module.h>
20#include <linux/platform_data/tda9950.h>
21#include <linux/slab.h>
22#include <drm/drm_edid.h>
23#include <media/cec.h>
24#include <media/cec-notifier.h>
25
26enum {
27 REG_CSR = 0x00,
28 CSR_BUSY = BIT(7),
29 CSR_INT = BIT(6),
30 CSR_ERR = BIT(5),
31
32 REG_CER = 0x01,
33
34 REG_CVR = 0x02,
35
36 REG_CCR = 0x03,
37 CCR_RESET = BIT(7),
38 CCR_ON = BIT(6),
39
40 REG_ACKH = 0x04,
41 REG_ACKL = 0x05,
42
43 REG_CCONR = 0x06,
44 CCONR_ENABLE_ERROR = BIT(4),
45 CCONR_RETRY_MASK = 7,
46
47 REG_CDR0 = 0x07,
48
49 CDR1_REQ = 0x00,
50 CDR1_CNF = 0x01,
51 CDR1_IND = 0x81,
52 CDR1_ERR = 0x82,
53 CDR1_IER = 0x83,
54
55 CDR2_CNF_SUCCESS = 0x00,
56 CDR2_CNF_OFF_STATE = 0x80,
57 CDR2_CNF_BAD_REQ = 0x81,
58 CDR2_CNF_CEC_ACCESS = 0x82,
59 CDR2_CNF_ARB_ERROR = 0x83,
60 CDR2_CNF_BAD_TIMING = 0x84,
61 CDR2_CNF_NACK_ADDR = 0x85,
62 CDR2_CNF_NACK_DATA = 0x86,
63};
64
65struct tda9950_priv {
66 struct i2c_client *client;
67 struct device *hdmi;
68 struct cec_adapter *adap;
69 struct tda9950_glue *glue;
70 u16 addresses;
71 struct cec_msg rx_msg;
72 struct cec_notifier *notify;
73 bool open;
74};
75
76static int tda9950_write_range(struct i2c_client *client, u8 addr, u8 *p, int cnt)
77{
78 struct i2c_msg msg;
79 u8 buf[cnt + 1];
80 int ret;
81
82 buf[0] = addr;
83 memcpy(buf + 1, p, cnt);
84
85 msg.addr = client->addr;
86 msg.flags = 0;
87 msg.len = cnt + 1;
88 msg.buf = buf;
89
90 dev_dbg(&client->dev, "wr 0x%02x: %*ph\n", addr, cnt, p);
91
92 ret = i2c_transfer(client->adapter, &msg, 1);
93 if (ret < 0)
94 dev_err(&client->dev, "Error %d writing to cec:0x%x\n", ret, addr);
95 return ret < 0 ? ret : 0;
96}
97
98static void tda9950_write(struct i2c_client *client, u8 addr, u8 val)
99{
100 tda9950_write_range(client, addr, &val, 1);
101}
102
103static int tda9950_read_range(struct i2c_client *client, u8 addr, u8 *p, int cnt)
104{
105 struct i2c_msg msg[2];
106 int ret;
107
108 msg[0].addr = client->addr;
109 msg[0].flags = 0;
110 msg[0].len = 1;
111 msg[0].buf = &addr;
112 msg[1].addr = client->addr;
113 msg[1].flags = I2C_M_RD;
114 msg[1].len = cnt;
115 msg[1].buf = p;
116
117 ret = i2c_transfer(client->adapter, msg, 2);
118 if (ret < 0)
119 dev_err(&client->dev, "Error %d reading from cec:0x%x\n", ret, addr);
120
121 dev_dbg(&client->dev, "rd 0x%02x: %*ph\n", addr, cnt, p);
122
123 return ret;
124}
125
126static u8 tda9950_read(struct i2c_client *client, u8 addr)
127{
128 int ret;
129 u8 val;
130
131 ret = tda9950_read_range(client, addr, &val, 1);
132 if (ret < 0)
133 val = 0;
134
135 return val;
136}
137
138static irqreturn_t tda9950_irq(int irq, void *data)
139{
140 struct tda9950_priv *priv = data;
141 unsigned int tx_status;
142 u8 csr, cconr, buf[19];
143 u8 arb_lost_cnt, nack_cnt, err_cnt;
144
145 if (!priv->open)
146 return IRQ_NONE;
147
148 csr = tda9950_read(priv->client, REG_CSR);
149 if (!(csr & CSR_INT))
150 return IRQ_NONE;
151
152 cconr = tda9950_read(priv->client, REG_CCONR) & CCONR_RETRY_MASK;
153
154 tda9950_read_range(priv->client, REG_CDR0, buf, sizeof(buf));
155
156 /*
157 * This should never happen: the data sheet says that there will
158 * always be a valid message if the interrupt line is asserted.
159 */
160 if (buf[0] == 0) {
161 dev_warn(&priv->client->dev, "interrupt pending, but no message?\n");
162 return IRQ_NONE;
163 }
164
165 switch (buf[1]) {
166 case CDR1_CNF: /* transmit result */
167 arb_lost_cnt = nack_cnt = err_cnt = 0;
168 switch (buf[2]) {
169 case CDR2_CNF_SUCCESS:
170 tx_status = CEC_TX_STATUS_OK;
171 break;
172
173 case CDR2_CNF_ARB_ERROR:
174 tx_status = CEC_TX_STATUS_ARB_LOST;
175 arb_lost_cnt = cconr;
176 break;
177
178 case CDR2_CNF_NACK_ADDR:
179 tx_status = CEC_TX_STATUS_NACK;
180 nack_cnt = cconr;
181 break;
182
183 default: /* some other error, refer to TDA9950 docs */
184 dev_err(&priv->client->dev, "CNF reply error 0x%02x\n",
185 buf[2]);
186 tx_status = CEC_TX_STATUS_ERROR;
187 err_cnt = cconr;
188 break;
189 }
190 /* TDA9950 executes all retries for us */
191 tx_status |= CEC_TX_STATUS_MAX_RETRIES;
192 cec_transmit_done(priv->adap, tx_status, arb_lost_cnt,
193 nack_cnt, 0, err_cnt);
194 break;
195
196 case CDR1_IND:
197 priv->rx_msg.len = buf[0] - 2;
198 if (priv->rx_msg.len > CEC_MAX_MSG_SIZE)
199 priv->rx_msg.len = CEC_MAX_MSG_SIZE;
200
201 memcpy(priv->rx_msg.msg, buf + 2, priv->rx_msg.len);
202 cec_received_msg(priv->adap, &priv->rx_msg);
203 break;
204
205 default: /* unknown */
206 dev_err(&priv->client->dev, "unknown service id 0x%02x\n",
207 buf[1]);
208 break;
209 }
210
211 return IRQ_HANDLED;
212}
213
214static int tda9950_cec_transmit(struct cec_adapter *adap, u8 attempts,
215 u32 signal_free_time, struct cec_msg *msg)
216{
217 struct tda9950_priv *priv = adap->priv;
218 u8 buf[CEC_MAX_MSG_SIZE + 2];
219
220 buf[0] = 2 + msg->len;
221 buf[1] = CDR1_REQ;
222 memcpy(buf + 2, msg->msg, msg->len);
223
224 if (attempts > 5)
225 attempts = 5;
226
227 tda9950_write(priv->client, REG_CCONR, attempts);
228
229 return tda9950_write_range(priv->client, REG_CDR0, buf, 2 + msg->len);
230}
231
232static int tda9950_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
233{
234 struct tda9950_priv *priv = adap->priv;
235 u16 addresses;
236 u8 buf[2];
237
238 if (addr == CEC_LOG_ADDR_INVALID)
239 addresses = priv->addresses = 0;
240 else
241 addresses = priv->addresses |= BIT(addr);
242
243 /* TDA9950 doesn't want address 15 set */
244 addresses &= 0x7fff;
245 buf[0] = addresses >> 8;
246 buf[1] = addresses;
247
248 return tda9950_write_range(priv->client, REG_ACKH, buf, 2);
249}
250
251/*
252 * When operating as part of the TDA998x, we need additional handling
253 * to initialise and shut down the TDA9950 part of the device. These
254 * two hooks are provided to allow the TDA998x code to perform those
255 * activities.
256 */
257static int tda9950_glue_open(struct tda9950_priv *priv)
258{
259 int ret = 0;
260
261 if (priv->glue && priv->glue->open)
262 ret = priv->glue->open(priv->glue->data);
263
264 priv->open = true;
265
266 return ret;
267}
268
269static void tda9950_glue_release(struct tda9950_priv *priv)
270{
271 priv->open = false;
272
273 if (priv->glue && priv->glue->release)
274 priv->glue->release(priv->glue->data);
275}
276
277static int tda9950_open(struct tda9950_priv *priv)
278{
279 struct i2c_client *client = priv->client;
280 int ret;
281
282 ret = tda9950_glue_open(priv);
283 if (ret)
284 return ret;
285
286 /* Reset the TDA9950, and wait 250ms for it to recover */
287 tda9950_write(client, REG_CCR, CCR_RESET);
288 msleep(250);
289
290 tda9950_cec_adap_log_addr(priv->adap, CEC_LOG_ADDR_INVALID);
291
292 /* Start the command processor */
293 tda9950_write(client, REG_CCR, CCR_ON);
294
295 return 0;
296}
297
298static void tda9950_release(struct tda9950_priv *priv)
299{
300 struct i2c_client *client = priv->client;
301 int timeout = 50;
302 u8 csr;
303
304 /* Stop the command processor */
305 tda9950_write(client, REG_CCR, 0);
306
307 /* Wait up to .5s for it to signal non-busy */
308 do {
309 csr = tda9950_read(client, REG_CSR);
310 if (!(csr & CSR_BUSY) || --timeout)
311 break;
312 msleep(10);
313 } while (1);
314
315 /* Warn the user that their IRQ may die if it's shared. */
316 if (csr & CSR_BUSY)
317 dev_warn(&client->dev, "command processor failed to stop, irq%d may die (csr=0x%02x)\n",
318 client->irq, csr);
319
320 tda9950_glue_release(priv);
321}
322
323static int tda9950_cec_adap_enable(struct cec_adapter *adap, bool enable)
324{
325 struct tda9950_priv *priv = adap->priv;
326
327 if (!enable) {
328 tda9950_release(priv);
329 return 0;
330 } else {
331 return tda9950_open(priv);
332 }
333}
334
335static const struct cec_adap_ops tda9950_cec_ops = {
336 .adap_enable = tda9950_cec_adap_enable,
337 .adap_log_addr = tda9950_cec_adap_log_addr,
338 .adap_transmit = tda9950_cec_transmit,
339};
340
341/*
342 * When operating as part of the TDA998x, we need to claim additional
343 * resources. These two hooks permit the management of those resources.
344 */
345static void tda9950_devm_glue_exit(void *data)
346{
347 struct tda9950_glue *glue = data;
348
349 if (glue && glue->exit)
350 glue->exit(glue->data);
351}
352
353static int tda9950_devm_glue_init(struct device *dev, struct tda9950_glue *glue)
354{
355 int ret;
356
357 if (glue && glue->init) {
358 ret = glue->init(glue->data);
359 if (ret)
360 return ret;
361 }
362
363 ret = devm_add_action(dev, tda9950_devm_glue_exit, glue);
364 if (ret)
365 tda9950_devm_glue_exit(glue);
366
367 return ret;
368}
369
370static void tda9950_cec_del(void *data)
371{
372 struct tda9950_priv *priv = data;
373
374 cec_delete_adapter(priv->adap);
375}
376
377static int tda9950_probe(struct i2c_client *client,
378 const struct i2c_device_id *id)
379{
380 struct tda9950_glue *glue = client->dev.platform_data;
381 struct device *dev = &client->dev;
382 struct tda9950_priv *priv;
383 unsigned long irqflags;
384 int ret;
385 u8 cvr;
386
387 /*
388 * We must have I2C functionality: our multi-byte accesses
389 * must be performed as a single contiguous transaction.
390 */
391 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
392 dev_err(&client->dev,
393 "adapter does not support I2C functionality\n");
394 return -ENXIO;
395 }
396
397 /* We must have an interrupt to be functional. */
398 if (client->irq <= 0) {
399 dev_err(&client->dev, "driver requires an interrupt\n");
400 return -ENXIO;
401 }
402
403 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
404 if (!priv)
405 return -ENOMEM;
406
407 priv->client = client;
408 priv->glue = glue;
409
410 i2c_set_clientdata(client, priv);
411
412 /*
413 * If we're part of a TDA998x, we want the class devices to be
414 * associated with the HDMI Tx so we have a tight relationship
415 * between the HDMI interface and the CEC interface.
416 */
417 priv->hdmi = dev;
418 if (glue && glue->parent)
419 priv->hdmi = glue->parent;
420
421 priv->adap = cec_allocate_adapter(&tda9950_cec_ops, priv, "tda9950",
422 CEC_CAP_DEFAULTS,
423 CEC_MAX_LOG_ADDRS);
424 if (IS_ERR(priv->adap))
425 return PTR_ERR(priv->adap);
426
427 ret = devm_add_action(dev, tda9950_cec_del, priv);
428 if (ret) {
429 cec_delete_adapter(priv->adap);
430 return ret;
431 }
432
433 ret = tda9950_devm_glue_init(dev, glue);
434 if (ret)
435 return ret;
436
437 ret = tda9950_glue_open(priv);
438 if (ret)
439 return ret;
440
441 cvr = tda9950_read(client, REG_CVR);
442
443 dev_info(&client->dev,
444 "TDA9950 CEC interface, hardware version %u.%u\n",
445 cvr >> 4, cvr & 15);
446
447 tda9950_glue_release(priv);
448
449 irqflags = IRQF_TRIGGER_FALLING;
450 if (glue)
451 irqflags = glue->irq_flags;
452
453 ret = devm_request_threaded_irq(dev, client->irq, NULL, tda9950_irq,
454 irqflags | IRQF_SHARED | IRQF_ONESHOT,
455 dev_name(&client->dev), priv);
456 if (ret < 0)
457 return ret;
458
459 priv->notify = cec_notifier_get(priv->hdmi);
460 if (!priv->notify)
461 return -ENOMEM;
462
463 ret = cec_register_adapter(priv->adap, priv->hdmi);
464 if (ret < 0) {
465 cec_notifier_put(priv->notify);
466 return ret;
467 }
468
469 /*
470 * CEC documentation says we must not call cec_delete_adapter
471 * after a successful call to cec_register_adapter().
472 */
473 devm_remove_action(dev, tda9950_cec_del, priv);
474
475 cec_register_cec_notifier(priv->adap, priv->notify);
476
477 return 0;
478}
479
480static int tda9950_remove(struct i2c_client *client)
481{
482 struct tda9950_priv *priv = i2c_get_clientdata(client);
483
484 cec_unregister_adapter(priv->adap);
485 cec_notifier_put(priv->notify);
486
487 return 0;
488}
489
490static struct i2c_device_id tda9950_ids[] = {
491 { "tda9950", 0 },
492 { },
493};
494MODULE_DEVICE_TABLE(i2c, tda9950_ids);
495
496static struct i2c_driver tda9950_driver = {
497 .probe = tda9950_probe,
498 .remove = tda9950_remove,
499 .driver = {
500 .name = "tda9950",
501 },
502 .id_table = tda9950_ids,
503};
504
505module_i2c_driver(tda9950_driver);
506
507MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
508MODULE_DESCRIPTION("TDA9950/TDA998x Consumer Electronics Control Driver");
509MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 9e67a7b4e3a4..6ebd8842dbcc 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -16,8 +16,10 @@
16 */ 16 */
17 17
18#include <linux/component.h> 18#include <linux/component.h>
19#include <linux/gpio/consumer.h>
19#include <linux/hdmi.h> 20#include <linux/hdmi.h>
20#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/platform_data/tda9950.h>
21#include <linux/irq.h> 23#include <linux/irq.h>
22#include <sound/asoundef.h> 24#include <sound/asoundef.h>
23#include <sound/hdmi-codec.h> 25#include <sound/hdmi-codec.h>
@@ -29,6 +31,8 @@
29#include <drm/drm_of.h> 31#include <drm/drm_of.h>
30#include <drm/i2c/tda998x.h> 32#include <drm/i2c/tda998x.h>
31 33
34#include <media/cec-notifier.h>
35
32#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 36#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
33 37
34struct tda998x_audio_port { 38struct tda998x_audio_port {
@@ -55,6 +59,7 @@ struct tda998x_priv {
55 struct platform_device *audio_pdev; 59 struct platform_device *audio_pdev;
56 struct mutex audio_mutex; 60 struct mutex audio_mutex;
57 61
62 struct mutex edid_mutex;
58 wait_queue_head_t wq_edid; 63 wait_queue_head_t wq_edid;
59 volatile int wq_edid_wait; 64 volatile int wq_edid_wait;
60 65
@@ -67,6 +72,9 @@ struct tda998x_priv {
67 struct drm_connector connector; 72 struct drm_connector connector;
68 73
69 struct tda998x_audio_port audio_port[2]; 74 struct tda998x_audio_port audio_port[2];
75 struct tda9950_glue cec_glue;
76 struct gpio_desc *calib;
77 struct cec_notifier *cec_notify;
70}; 78};
71 79
72#define conn_to_tda998x_priv(x) \ 80#define conn_to_tda998x_priv(x) \
@@ -345,6 +353,12 @@ struct tda998x_priv {
345#define REG_CEC_INTSTATUS 0xee /* read */ 353#define REG_CEC_INTSTATUS 0xee /* read */
346# define CEC_INTSTATUS_CEC (1 << 0) 354# define CEC_INTSTATUS_CEC (1 << 0)
347# define CEC_INTSTATUS_HDMI (1 << 1) 355# define CEC_INTSTATUS_HDMI (1 << 1)
356#define REG_CEC_CAL_XOSC_CTRL1 0xf2
357# define CEC_CAL_XOSC_CTRL1_ENA_CAL BIT(0)
358#define REG_CEC_DES_FREQ2 0xf5
359# define CEC_DES_FREQ2_DIS_AUTOCAL BIT(7)
360#define REG_CEC_CLK 0xf6
361# define CEC_CLK_FRO 0x11
348#define REG_CEC_FRO_IM_CLK_CTRL 0xfb /* read/write */ 362#define REG_CEC_FRO_IM_CLK_CTRL 0xfb /* read/write */
349# define CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7) 363# define CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7)
350# define CEC_FRO_IM_CLK_CTRL_ENA_OTP (1 << 6) 364# define CEC_FRO_IM_CLK_CTRL_ENA_OTP (1 << 6)
@@ -359,6 +373,7 @@ struct tda998x_priv {
359# define CEC_RXSHPDLEV_HPD (1 << 1) 373# define CEC_RXSHPDLEV_HPD (1 << 1)
360 374
361#define REG_CEC_ENAMODS 0xff /* read/write */ 375#define REG_CEC_ENAMODS 0xff /* read/write */
376# define CEC_ENAMODS_EN_CEC_CLK (1 << 7)
362# define CEC_ENAMODS_DIS_FRO (1 << 6) 377# define CEC_ENAMODS_DIS_FRO (1 << 6)
363# define CEC_ENAMODS_DIS_CCLK (1 << 5) 378# define CEC_ENAMODS_DIS_CCLK (1 << 5)
364# define CEC_ENAMODS_EN_RXSENS (1 << 2) 379# define CEC_ENAMODS_EN_RXSENS (1 << 2)
@@ -417,6 +432,114 @@ cec_read(struct tda998x_priv *priv, u8 addr)
417 return val; 432 return val;
418} 433}
419 434
435static void cec_enamods(struct tda998x_priv *priv, u8 mods, bool enable)
436{
437 int val = cec_read(priv, REG_CEC_ENAMODS);
438
439 if (val < 0)
440 return;
441
442 if (enable)
443 val |= mods;
444 else
445 val &= ~mods;
446
447 cec_write(priv, REG_CEC_ENAMODS, val);
448}
449
450static void tda998x_cec_set_calibration(struct tda998x_priv *priv, bool enable)
451{
452 if (enable) {
453 u8 val;
454
455 cec_write(priv, 0xf3, 0xc0);
456 cec_write(priv, 0xf4, 0xd4);
457
458 /* Enable automatic calibration mode */
459 val = cec_read(priv, REG_CEC_DES_FREQ2);
460 val &= ~CEC_DES_FREQ2_DIS_AUTOCAL;
461 cec_write(priv, REG_CEC_DES_FREQ2, val);
462
463 /* Enable free running oscillator */
464 cec_write(priv, REG_CEC_CLK, CEC_CLK_FRO);
465 cec_enamods(priv, CEC_ENAMODS_DIS_FRO, false);
466
467 cec_write(priv, REG_CEC_CAL_XOSC_CTRL1,
468 CEC_CAL_XOSC_CTRL1_ENA_CAL);
469 } else {
470 cec_write(priv, REG_CEC_CAL_XOSC_CTRL1, 0);
471 }
472}
473
474/*
475 * Calibration for the internal oscillator: we need to set calibration mode,
476 * and then pulse the IRQ line low for a 10ms ± 1% period.
477 */
478static void tda998x_cec_calibration(struct tda998x_priv *priv)
479{
480 struct gpio_desc *calib = priv->calib;
481
482 mutex_lock(&priv->edid_mutex);
483 if (priv->hdmi->irq > 0)
484 disable_irq(priv->hdmi->irq);
485 gpiod_direction_output(calib, 1);
486 tda998x_cec_set_calibration(priv, true);
487
488 local_irq_disable();
489 gpiod_set_value(calib, 0);
490 mdelay(10);
491 gpiod_set_value(calib, 1);
492 local_irq_enable();
493
494 tda998x_cec_set_calibration(priv, false);
495 gpiod_direction_input(calib);
496 if (priv->hdmi->irq > 0)
497 enable_irq(priv->hdmi->irq);
498 mutex_unlock(&priv->edid_mutex);
499}
500
501static int tda998x_cec_hook_init(void *data)
502{
503 struct tda998x_priv *priv = data;
504 struct gpio_desc *calib;
505
506 calib = gpiod_get(&priv->hdmi->dev, "nxp,calib", GPIOD_ASIS);
507 if (IS_ERR(calib)) {
508 dev_warn(&priv->hdmi->dev, "failed to get calibration gpio: %ld\n",
509 PTR_ERR(calib));
510 return PTR_ERR(calib);
511 }
512
513 priv->calib = calib;
514
515 return 0;
516}
517
518static void tda998x_cec_hook_exit(void *data)
519{
520 struct tda998x_priv *priv = data;
521
522 gpiod_put(priv->calib);
523 priv->calib = NULL;
524}
525
526static int tda998x_cec_hook_open(void *data)
527{
528 struct tda998x_priv *priv = data;
529
530 cec_enamods(priv, CEC_ENAMODS_EN_CEC_CLK | CEC_ENAMODS_EN_CEC, true);
531 tda998x_cec_calibration(priv);
532
533 return 0;
534}
535
536static void tda998x_cec_hook_release(void *data)
537{
538 struct tda998x_priv *priv = data;
539
540 cec_enamods(priv, CEC_ENAMODS_EN_CEC_CLK | CEC_ENAMODS_EN_CEC, false);
541}
542
420static int 543static int
421set_page(struct tda998x_priv *priv, u16 reg) 544set_page(struct tda998x_priv *priv, u16 reg)
422{ 545{
@@ -657,10 +780,13 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
657 sta, cec, lvl, flag0, flag1, flag2); 780 sta, cec, lvl, flag0, flag1, flag2);
658 781
659 if (cec & CEC_RXSHPDINT_HPD) { 782 if (cec & CEC_RXSHPDINT_HPD) {
660 if (lvl & CEC_RXSHPDLEV_HPD) 783 if (lvl & CEC_RXSHPDLEV_HPD) {
661 tda998x_edid_delay_start(priv); 784 tda998x_edid_delay_start(priv);
662 else 785 } else {
663 schedule_work(&priv->detect_work); 786 schedule_work(&priv->detect_work);
787 cec_notifier_set_phys_addr(priv->cec_notify,
788 CEC_PHYS_ADDR_INVALID);
789 }
664 790
665 handled = true; 791 handled = true;
666 } 792 }
@@ -981,6 +1107,8 @@ static int tda998x_connector_fill_modes(struct drm_connector *connector,
981 if (connector->edid_blob_ptr) { 1107 if (connector->edid_blob_ptr) {
982 struct edid *edid = (void *)connector->edid_blob_ptr->data; 1108 struct edid *edid = (void *)connector->edid_blob_ptr->data;
983 1109
1110 cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid);
1111
984 priv->sink_has_audio = drm_detect_monitor_audio(edid); 1112 priv->sink_has_audio = drm_detect_monitor_audio(edid);
985 } else { 1113 } else {
986 priv->sink_has_audio = false; 1114 priv->sink_has_audio = false;
@@ -1024,6 +1152,8 @@ static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length)
1024 offset = (blk & 1) ? 128 : 0; 1152 offset = (blk & 1) ? 128 : 0;
1025 segptr = blk / 2; 1153 segptr = blk / 2;
1026 1154
1155 mutex_lock(&priv->edid_mutex);
1156
1027 reg_write(priv, REG_DDC_ADDR, 0xa0); 1157 reg_write(priv, REG_DDC_ADDR, 0xa0);
1028 reg_write(priv, REG_DDC_OFFS, offset); 1158 reg_write(priv, REG_DDC_OFFS, offset);
1029 reg_write(priv, REG_DDC_SEGM_ADDR, 0x60); 1159 reg_write(priv, REG_DDC_SEGM_ADDR, 0x60);
@@ -1043,14 +1173,15 @@ static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length)
1043 msecs_to_jiffies(100)); 1173 msecs_to_jiffies(100));
1044 if (i < 0) { 1174 if (i < 0) {
1045 dev_err(&priv->hdmi->dev, "read edid wait err %d\n", i); 1175 dev_err(&priv->hdmi->dev, "read edid wait err %d\n", i);
1046 return i; 1176 ret = i;
1177 goto failed;
1047 } 1178 }
1048 } else { 1179 } else {
1049 for (i = 100; i > 0; i--) { 1180 for (i = 100; i > 0; i--) {
1050 msleep(1); 1181 msleep(1);
1051 ret = reg_read(priv, REG_INT_FLAGS_2); 1182 ret = reg_read(priv, REG_INT_FLAGS_2);
1052 if (ret < 0) 1183 if (ret < 0)
1053 return ret; 1184 goto failed;
1054 if (ret & INT_FLAGS_2_EDID_BLK_RD) 1185 if (ret & INT_FLAGS_2_EDID_BLK_RD)
1055 break; 1186 break;
1056 } 1187 }
@@ -1058,17 +1189,22 @@ static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length)
1058 1189
1059 if (i == 0) { 1190 if (i == 0) {
1060 dev_err(&priv->hdmi->dev, "read edid timeout\n"); 1191 dev_err(&priv->hdmi->dev, "read edid timeout\n");
1061 return -ETIMEDOUT; 1192 ret = -ETIMEDOUT;
1193 goto failed;
1062 } 1194 }
1063 1195
1064 ret = reg_read_range(priv, REG_EDID_DATA_0, buf, length); 1196 ret = reg_read_range(priv, REG_EDID_DATA_0, buf, length);
1065 if (ret != length) { 1197 if (ret != length) {
1066 dev_err(&priv->hdmi->dev, "failed to read edid block %d: %d\n", 1198 dev_err(&priv->hdmi->dev, "failed to read edid block %d: %d\n",
1067 blk, ret); 1199 blk, ret);
1068 return ret; 1200 goto failed;
1069 } 1201 }
1070 1202
1071 return 0; 1203 ret = 0;
1204
1205 failed:
1206 mutex_unlock(&priv->edid_mutex);
1207 return ret;
1072} 1208}
1073 1209
1074static int tda998x_connector_get_modes(struct drm_connector *connector) 1210static int tda998x_connector_get_modes(struct drm_connector *connector)
@@ -1106,7 +1242,7 @@ static int tda998x_connector_get_modes(struct drm_connector *connector)
1106 return n; 1242 return n;
1107} 1243}
1108 1244
1109static int tda998x_connector_mode_valid(struct drm_connector *connector, 1245static enum drm_mode_status tda998x_connector_mode_valid(struct drm_connector *connector,
1110 struct drm_display_mode *mode) 1246 struct drm_display_mode *mode)
1111{ 1247{
1112 /* TDA19988 dotclock can go up to 165MHz */ 1248 /* TDA19988 dotclock can go up to 165MHz */
@@ -1423,6 +1559,9 @@ static void tda998x_destroy(struct tda998x_priv *priv)
1423 cancel_work_sync(&priv->detect_work); 1559 cancel_work_sync(&priv->detect_work);
1424 1560
1425 i2c_unregister_device(priv->cec); 1561 i2c_unregister_device(priv->cec);
1562
1563 if (priv->cec_notify)
1564 cec_notifier_put(priv->cec_notify);
1426} 1565}
1427 1566
1428/* I2C driver functions */ 1567/* I2C driver functions */
@@ -1472,10 +1611,16 @@ static int tda998x_get_audio_ports(struct tda998x_priv *priv,
1472static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) 1611static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
1473{ 1612{
1474 struct device_node *np = client->dev.of_node; 1613 struct device_node *np = client->dev.of_node;
1614 struct i2c_board_info cec_info;
1475 u32 video; 1615 u32 video;
1476 int rev_lo, rev_hi, ret; 1616 int rev_lo, rev_hi, ret;
1477 1617
1478 mutex_init(&priv->audio_mutex); /* Protect access from audio thread */ 1618 mutex_init(&priv->mutex); /* protect the page access */
1619 mutex_init(&priv->audio_mutex); /* protect access from audio thread */
1620 mutex_init(&priv->edid_mutex);
1621 init_waitqueue_head(&priv->edid_delay_waitq);
1622 timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0);
1623 INIT_WORK(&priv->detect_work, tda998x_detect_work);
1479 1624
1480 priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); 1625 priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3);
1481 priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); 1626 priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1);
@@ -1485,14 +1630,6 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
1485 priv->cec_addr = 0x34 + (client->addr & 0x03); 1630 priv->cec_addr = 0x34 + (client->addr & 0x03);
1486 priv->current_page = 0xff; 1631 priv->current_page = 0xff;
1487 priv->hdmi = client; 1632 priv->hdmi = client;
1488 priv->cec = i2c_new_dummy(client->adapter, priv->cec_addr);
1489 if (!priv->cec)
1490 return -ENODEV;
1491
1492 mutex_init(&priv->mutex); /* protect the page access */
1493 init_waitqueue_head(&priv->edid_delay_waitq);
1494 timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0);
1495 INIT_WORK(&priv->detect_work, tda998x_detect_work);
1496 1633
1497 /* wake up the device: */ 1634 /* wake up the device: */
1498 cec_write(priv, REG_CEC_ENAMODS, 1635 cec_write(priv, REG_CEC_ENAMODS,
@@ -1502,10 +1639,15 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
1502 1639
1503 /* read version: */ 1640 /* read version: */
1504 rev_lo = reg_read(priv, REG_VERSION_LSB); 1641 rev_lo = reg_read(priv, REG_VERSION_LSB);
1642 if (rev_lo < 0) {
1643 dev_err(&client->dev, "failed to read version: %d\n", rev_lo);
1644 return rev_lo;
1645 }
1646
1505 rev_hi = reg_read(priv, REG_VERSION_MSB); 1647 rev_hi = reg_read(priv, REG_VERSION_MSB);
1506 if (rev_lo < 0 || rev_hi < 0) { 1648 if (rev_hi < 0) {
1507 ret = rev_lo < 0 ? rev_lo : rev_hi; 1649 dev_err(&client->dev, "failed to read version: %d\n", rev_hi);
1508 goto fail; 1650 return rev_hi;
1509 } 1651 }
1510 1652
1511 priv->rev = rev_lo | rev_hi << 8; 1653 priv->rev = rev_lo | rev_hi << 8;
@@ -1529,7 +1671,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
1529 default: 1671 default:
1530 dev_err(&client->dev, "found unsupported device: %04x\n", 1672 dev_err(&client->dev, "found unsupported device: %04x\n",
1531 priv->rev); 1673 priv->rev);
1532 goto fail; 1674 return -ENXIO;
1533 } 1675 }
1534 1676
1535 /* after reset, enable DDC: */ 1677 /* after reset, enable DDC: */
@@ -1545,6 +1687,15 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
1545 cec_write(priv, REG_CEC_FRO_IM_CLK_CTRL, 1687 cec_write(priv, REG_CEC_FRO_IM_CLK_CTRL,
1546 CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL); 1688 CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL);
1547 1689
1690 /* ensure interrupts are disabled */
1691 cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
1692
1693 /* clear pending interrupts */
1694 cec_read(priv, REG_CEC_RXSHPDINT);
1695 reg_read(priv, REG_INT_FLAGS_0);
1696 reg_read(priv, REG_INT_FLAGS_1);
1697 reg_read(priv, REG_INT_FLAGS_2);
1698
1548 /* initialize the optional IRQ */ 1699 /* initialize the optional IRQ */
1549 if (client->irq) { 1700 if (client->irq) {
1550 unsigned long irq_flags; 1701 unsigned long irq_flags;
@@ -1552,13 +1703,11 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
1552 /* init read EDID waitqueue and HDP work */ 1703 /* init read EDID waitqueue and HDP work */
1553 init_waitqueue_head(&priv->wq_edid); 1704 init_waitqueue_head(&priv->wq_edid);
1554 1705
1555 /* clear pending interrupts */
1556 reg_read(priv, REG_INT_FLAGS_0);
1557 reg_read(priv, REG_INT_FLAGS_1);
1558 reg_read(priv, REG_INT_FLAGS_2);
1559
1560 irq_flags = 1706 irq_flags =
1561 irqd_get_trigger_type(irq_get_irq_data(client->irq)); 1707 irqd_get_trigger_type(irq_get_irq_data(client->irq));
1708
1709 priv->cec_glue.irq_flags = irq_flags;
1710
1562 irq_flags |= IRQF_SHARED | IRQF_ONESHOT; 1711 irq_flags |= IRQF_SHARED | IRQF_ONESHOT;
1563 ret = request_threaded_irq(client->irq, NULL, 1712 ret = request_threaded_irq(client->irq, NULL,
1564 tda998x_irq_thread, irq_flags, 1713 tda998x_irq_thread, irq_flags,
@@ -1567,13 +1716,46 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
1567 dev_err(&client->dev, 1716 dev_err(&client->dev,
1568 "failed to request IRQ#%u: %d\n", 1717 "failed to request IRQ#%u: %d\n",
1569 client->irq, ret); 1718 client->irq, ret);
1570 goto fail; 1719 goto err_irq;
1571 } 1720 }
1572 1721
1573 /* enable HPD irq */ 1722 /* enable HPD irq */
1574 cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD); 1723 cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
1575 } 1724 }
1576 1725
1726 priv->cec_notify = cec_notifier_get(&client->dev);
1727 if (!priv->cec_notify) {
1728 ret = -ENOMEM;
1729 goto fail;
1730 }
1731
1732 priv->cec_glue.parent = &client->dev;
1733 priv->cec_glue.data = priv;
1734 priv->cec_glue.init = tda998x_cec_hook_init;
1735 priv->cec_glue.exit = tda998x_cec_hook_exit;
1736 priv->cec_glue.open = tda998x_cec_hook_open;
1737 priv->cec_glue.release = tda998x_cec_hook_release;
1738
1739 /*
1740 * Some TDA998x are actually two I2C devices merged onto one piece
1741 * of silicon: TDA9989 and TDA19989 combine the HDMI transmitter
1742 * with a slightly modified TDA9950 CEC device. The CEC device
1743 * is at the TDA9950 address, with the address pins strapped across
1744 * to the TDA998x address pins. Hence, it always has the same
1745 * offset.
1746 */
1747 memset(&cec_info, 0, sizeof(cec_info));
1748 strlcpy(cec_info.type, "tda9950", sizeof(cec_info.type));
1749 cec_info.addr = priv->cec_addr;
1750 cec_info.platform_data = &priv->cec_glue;
1751 cec_info.irq = client->irq;
1752
1753 priv->cec = i2c_new_device(client->adapter, &cec_info);
1754 if (!priv->cec) {
1755 ret = -ENODEV;
1756 goto fail;
1757 }
1758
1577 /* enable EDID read irq: */ 1759 /* enable EDID read irq: */
1578 reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); 1760 reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
1579 1761
@@ -1596,12 +1778,18 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
1596 tda998x_audio_codec_init(priv, &client->dev); 1778 tda998x_audio_codec_init(priv, &client->dev);
1597 1779
1598 return 0; 1780 return 0;
1781
1599fail: 1782fail:
1600 /* if encoder_init fails, the encoder slave is never registered, 1783 /* if encoder_init fails, the encoder slave is never registered,
1601 * so cleanup here: 1784 * so cleanup here:
1602 */ 1785 */
1603 i2c_unregister_device(priv->cec); 1786 i2c_unregister_device(priv->cec);
1604 return -ENXIO; 1787 if (priv->cec_notify)
1788 cec_notifier_put(priv->cec_notify);
1789 if (client->irq)
1790 free_irq(client->irq, priv);
1791err_irq:
1792 return ret;
1605} 1793}
1606 1794
1607static void tda998x_encoder_prepare(struct drm_encoder *encoder) 1795static void tda998x_encoder_prepare(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
index 108d21f34777..9de8b1c51a5c 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -25,7 +25,8 @@ config DRM_I915_DEBUG
25 select X86_MSR # used by igt/pm_rpm 25 select X86_MSR # used by igt/pm_rpm
26 select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks) 26 select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
27 select DRM_DEBUG_MM if DRM=y 27 select DRM_DEBUG_MM if DRM=y
28 select DRM_DEBUG_MM_SELFTEST 28 select STACKDEPOT if DRM=y # for DRM_DEBUG_MM
29 select DRM_DEBUG_SELFTEST
29 select SW_SYNC # signaling validation framework (igt/syncobj*) 30 select SW_SYNC # signaling validation framework (igt/syncobj*)
30 select DRM_I915_SW_FENCE_DEBUG_OBJECTS 31 select DRM_I915_SW_FENCE_DEBUG_OBJECTS
31 select DRM_I915_SELFTEST 32 select DRM_I915_SELFTEST
@@ -89,6 +90,18 @@ config DRM_I915_SW_FENCE_CHECK_DAG
89 90
90 If in doubt, say "N". 91 If in doubt, say "N".
91 92
93config DRM_I915_DEBUG_GUC
94 bool "Enable additional driver debugging for GuC"
95 depends on DRM_I915
96 default n
97 help
98 Choose this option to turn on extra driver debugging that may affect
99 performance but will help resolve GuC related issues.
100
101 Recommended for driver developers only.
102
103 If in doubt, say "N".
104
92config DRM_I915_SELFTEST 105config DRM_I915_SELFTEST
93 bool "Enable selftests upon driver load" 106 bool "Enable selftests upon driver load"
94 depends on DRM_I915 107 depends on DRM_I915
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 4eee91a3a236..4c6adae23e18 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -12,12 +12,16 @@
12# Note the danger in using -Wall -Wextra is that when CI updates gcc we 12# Note the danger in using -Wall -Wextra is that when CI updates gcc we
13# will most likely get a sudden build breakage... Hopefully we will fix 13# will most likely get a sudden build breakage... Hopefully we will fix
14# new warnings before CI updates! 14# new warnings before CI updates!
15subdir-ccflags-y := -Wall -Wextra 15subdir-ccflags-y := -Wall -Wextra -Wvla
16subdir-ccflags-y += $(call cc-disable-warning, unused-parameter) 16subdir-ccflags-y += $(call cc-disable-warning, unused-parameter)
17subdir-ccflags-y += $(call cc-disable-warning, type-limits) 17subdir-ccflags-y += $(call cc-disable-warning, type-limits)
18subdir-ccflags-y += $(call cc-disable-warning, missing-field-initializers) 18subdir-ccflags-y += $(call cc-disable-warning, missing-field-initializers)
19subdir-ccflags-y += $(call cc-disable-warning, implicit-fallthrough) 19subdir-ccflags-y += $(call cc-disable-warning, implicit-fallthrough)
20subdir-ccflags-y += $(call cc-disable-warning, unused-but-set-variable) 20subdir-ccflags-y += $(call cc-disable-warning, unused-but-set-variable)
21# clang warnings
22subdir-ccflags-y += $(call cc-disable-warning, sign-compare)
23subdir-ccflags-y += $(call cc-disable-warning, sometimes-uninitialized)
24subdir-ccflags-y += $(call cc-disable-warning, initializer-overrides)
21subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror 25subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror
22 26
23# Fine grained warnings disable 27# Fine grained warnings disable
@@ -43,7 +47,8 @@ i915-y := i915_drv.o \
43 intel_csr.o \ 47 intel_csr.o \
44 intel_device_info.o \ 48 intel_device_info.o \
45 intel_pm.o \ 49 intel_pm.o \
46 intel_runtime_pm.o 50 intel_runtime_pm.o \
51 intel_workarounds.o
47 52
48i915-$(CONFIG_COMPAT) += i915_ioc32.o 53i915-$(CONFIG_COMPAT) += i915_ioc32.o
49i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o intel_pipe_crc.o 54i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o intel_pipe_crc.o
@@ -66,11 +71,11 @@ i915-y += i915_cmd_parser.o \
66 i915_gem_shrinker.o \ 71 i915_gem_shrinker.o \
67 i915_gem_stolen.o \ 72 i915_gem_stolen.o \
68 i915_gem_tiling.o \ 73 i915_gem_tiling.o \
69 i915_gem_timeline.o \
70 i915_gem_userptr.o \ 74 i915_gem_userptr.o \
71 i915_gemfs.o \ 75 i915_gemfs.o \
72 i915_query.o \ 76 i915_query.o \
73 i915_request.o \ 77 i915_request.o \
78 i915_timeline.o \
74 i915_trace_points.o \ 79 i915_trace_points.o \
75 i915_vma.o \ 80 i915_vma.o \
76 intel_breadcrumbs.o \ 81 intel_breadcrumbs.o \
@@ -79,7 +84,8 @@ i915-y += i915_cmd_parser.o \
79 intel_lrc.o \ 84 intel_lrc.o \
80 intel_mocs.o \ 85 intel_mocs.o \
81 intel_ringbuffer.o \ 86 intel_ringbuffer.o \
82 intel_uncore.o 87 intel_uncore.o \
88 intel_wopcm.o
83 89
84# general-purpose microcontroller (GuC) support 90# general-purpose microcontroller (GuC) support
85i915-y += intel_uc.o \ 91i915-y += intel_uc.o \
@@ -152,7 +158,8 @@ i915-y += dvo_ch7017.o \
152i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o 158i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
153i915-$(CONFIG_DRM_I915_SELFTEST) += \ 159i915-$(CONFIG_DRM_I915_SELFTEST) += \
154 selftests/i915_random.o \ 160 selftests/i915_random.o \
155 selftests/i915_selftest.o 161 selftests/i915_selftest.o \
162 selftests/igt_flush_test.o
156 163
157# virtual gpu code 164# virtual gpu code
158i915-y += i915_vgpu.o 165i915-y += i915_vgpu.o
@@ -171,7 +178,8 @@ i915-y += i915_perf.o \
171 i915_oa_glk.o \ 178 i915_oa_glk.o \
172 i915_oa_cflgt2.o \ 179 i915_oa_cflgt2.o \
173 i915_oa_cflgt3.o \ 180 i915_oa_cflgt3.o \
174 i915_oa_cnl.o 181 i915_oa_cnl.o \
182 i915_oa_icl.o
175 183
176ifeq ($(CONFIG_DRM_I915_GVT),y) 184ifeq ($(CONFIG_DRM_I915_GVT),y)
177i915-y += intel_gvt.o 185i915-y += intel_gvt.o
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index d85939bd7b47..718ca08f9575 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -813,15 +813,31 @@ static inline bool is_force_nonpriv_mmio(unsigned int offset)
813} 813}
814 814
815static int force_nonpriv_reg_handler(struct parser_exec_state *s, 815static int force_nonpriv_reg_handler(struct parser_exec_state *s,
816 unsigned int offset, unsigned int index) 816 unsigned int offset, unsigned int index, char *cmd)
817{ 817{
818 struct intel_gvt *gvt = s->vgpu->gvt; 818 struct intel_gvt *gvt = s->vgpu->gvt;
819 unsigned int data = cmd_val(s, index + 1); 819 unsigned int data;
820 u32 ring_base;
821 u32 nopid;
822 struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv;
823
824 if (!strcmp(cmd, "lri"))
825 data = cmd_val(s, index + 1);
826 else {
827 gvt_err("Unexpected forcenonpriv 0x%x write from cmd %s\n",
828 offset, cmd);
829 return -EINVAL;
830 }
831
832 ring_base = dev_priv->engine[s->ring_id]->mmio_base;
833 nopid = i915_mmio_reg_offset(RING_NOPID(ring_base));
820 834
821 if (!intel_gvt_in_force_nonpriv_whitelist(gvt, data)) { 835 if (!intel_gvt_in_force_nonpriv_whitelist(gvt, data) &&
836 data != nopid) {
822 gvt_err("Unexpected forcenonpriv 0x%x LRI write, value=0x%x\n", 837 gvt_err("Unexpected forcenonpriv 0x%x LRI write, value=0x%x\n",
823 offset, data); 838 offset, data);
824 return -EPERM; 839 patch_value(s, cmd_ptr(s, index), nopid);
840 return 0;
825 } 841 }
826 return 0; 842 return 0;
827} 843}
@@ -869,7 +885,7 @@ static int cmd_reg_handler(struct parser_exec_state *s,
869 return -EINVAL; 885 return -EINVAL;
870 886
871 if (is_force_nonpriv_mmio(offset) && 887 if (is_force_nonpriv_mmio(offset) &&
872 force_nonpriv_reg_handler(s, offset, index)) 888 force_nonpriv_reg_handler(s, offset, index, cmd))
873 return -EPERM; 889 return -EPERM;
874 890
875 if (offset == i915_mmio_reg_offset(DERRMR) || 891 if (offset == i915_mmio_reg_offset(DERRMR) ||
@@ -1604,7 +1620,8 @@ static int batch_buffer_needs_scan(struct parser_exec_state *s)
1604 if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv) 1620 if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)
1605 || IS_KABYLAKE(gvt->dev_priv)) { 1621 || IS_KABYLAKE(gvt->dev_priv)) {
1606 /* BDW decides privilege based on address space */ 1622 /* BDW decides privilege based on address space */
1607 if (cmd_val(s, 0) & (1 << 8)) 1623 if (cmd_val(s, 0) & (1 << 8) &&
1624 !(s->vgpu->scan_nonprivbb & (1 << s->ring_id)))
1608 return 0; 1625 return 0;
1609 } 1626 }
1610 return 1; 1627 return 1;
@@ -1618,6 +1635,8 @@ static int find_bb_size(struct parser_exec_state *s, unsigned long *bb_size)
1618 bool bb_end = false; 1635 bool bb_end = false;
1619 struct intel_vgpu *vgpu = s->vgpu; 1636 struct intel_vgpu *vgpu = s->vgpu;
1620 u32 cmd; 1637 u32 cmd;
1638 struct intel_vgpu_mm *mm = (s->buf_addr_type == GTT_BUFFER) ?
1639 s->vgpu->gtt.ggtt_mm : s->workload->shadow_mm;
1621 1640
1622 *bb_size = 0; 1641 *bb_size = 0;
1623 1642
@@ -1629,18 +1648,22 @@ static int find_bb_size(struct parser_exec_state *s, unsigned long *bb_size)
1629 cmd = cmd_val(s, 0); 1648 cmd = cmd_val(s, 0);
1630 info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id); 1649 info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id);
1631 if (info == NULL) { 1650 if (info == NULL) {
1632 gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n", 1651 gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %d, workload=%p\n",
1633 cmd, get_opcode(cmd, s->ring_id)); 1652 cmd, get_opcode(cmd, s->ring_id),
1653 (s->buf_addr_type == PPGTT_BUFFER) ?
1654 "ppgtt" : "ggtt", s->ring_id, s->workload);
1634 return -EBADRQC; 1655 return -EBADRQC;
1635 } 1656 }
1636 do { 1657 do {
1637 if (copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm, 1658 if (copy_gma_to_hva(s->vgpu, mm,
1638 gma, gma + 4, &cmd) < 0) 1659 gma, gma + 4, &cmd) < 0)
1639 return -EFAULT; 1660 return -EFAULT;
1640 info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id); 1661 info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id);
1641 if (info == NULL) { 1662 if (info == NULL) {
1642 gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n", 1663 gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %d, workload=%p\n",
1643 cmd, get_opcode(cmd, s->ring_id)); 1664 cmd, get_opcode(cmd, s->ring_id),
1665 (s->buf_addr_type == PPGTT_BUFFER) ?
1666 "ppgtt" : "ggtt", s->ring_id, s->workload);
1644 return -EBADRQC; 1667 return -EBADRQC;
1645 } 1668 }
1646 1669
@@ -1666,6 +1689,9 @@ static int perform_bb_shadow(struct parser_exec_state *s)
1666 unsigned long gma = 0; 1689 unsigned long gma = 0;
1667 unsigned long bb_size; 1690 unsigned long bb_size;
1668 int ret = 0; 1691 int ret = 0;
1692 struct intel_vgpu_mm *mm = (s->buf_addr_type == GTT_BUFFER) ?
1693 s->vgpu->gtt.ggtt_mm : s->workload->shadow_mm;
1694 unsigned long gma_start_offset = 0;
1669 1695
1670 /* get the start gm address of the batch buffer */ 1696 /* get the start gm address of the batch buffer */
1671 gma = get_gma_bb_from_cmd(s, 1); 1697 gma = get_gma_bb_from_cmd(s, 1);
@@ -1680,8 +1706,24 @@ static int perform_bb_shadow(struct parser_exec_state *s)
1680 if (!bb) 1706 if (!bb)
1681 return -ENOMEM; 1707 return -ENOMEM;
1682 1708
1709 bb->ppgtt = (s->buf_addr_type == GTT_BUFFER) ? false : true;
1710
1711 /* the gma_start_offset stores the batch buffer's start gma's
1712 * offset relative to page boundary. so for non-privileged batch
1713 * buffer, the shadowed gem object holds exactly the same page
1714 * layout as original gem object. This is for the convience of
1715 * replacing the whole non-privilged batch buffer page to this
1716 * shadowed one in PPGTT at the same gma address. (this replacing
1717 * action is not implemented yet now, but may be necessary in
1718 * future).
1719 * for prileged batch buffer, we just change start gma address to
1720 * that of shadowed page.
1721 */
1722 if (bb->ppgtt)
1723 gma_start_offset = gma & ~I915_GTT_PAGE_MASK;
1724
1683 bb->obj = i915_gem_object_create(s->vgpu->gvt->dev_priv, 1725 bb->obj = i915_gem_object_create(s->vgpu->gvt->dev_priv,
1684 roundup(bb_size, PAGE_SIZE)); 1726 roundup(bb_size + gma_start_offset, PAGE_SIZE));
1685 if (IS_ERR(bb->obj)) { 1727 if (IS_ERR(bb->obj)) {
1686 ret = PTR_ERR(bb->obj); 1728 ret = PTR_ERR(bb->obj);
1687 goto err_free_bb; 1729 goto err_free_bb;
@@ -1702,9 +1744,9 @@ static int perform_bb_shadow(struct parser_exec_state *s)
1702 bb->clflush &= ~CLFLUSH_BEFORE; 1744 bb->clflush &= ~CLFLUSH_BEFORE;
1703 } 1745 }
1704 1746
1705 ret = copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm, 1747 ret = copy_gma_to_hva(s->vgpu, mm,
1706 gma, gma + bb_size, 1748 gma, gma + bb_size,
1707 bb->va); 1749 bb->va + gma_start_offset);
1708 if (ret < 0) { 1750 if (ret < 0) {
1709 gvt_vgpu_err("fail to copy guest ring buffer\n"); 1751 gvt_vgpu_err("fail to copy guest ring buffer\n");
1710 ret = -EFAULT; 1752 ret = -EFAULT;
@@ -1730,7 +1772,7 @@ static int perform_bb_shadow(struct parser_exec_state *s)
1730 * buffer's gma in pair. After all, we don't want to pin the shadow 1772 * buffer's gma in pair. After all, we don't want to pin the shadow
1731 * buffer here (too early). 1773 * buffer here (too early).
1732 */ 1774 */
1733 s->ip_va = bb->va; 1775 s->ip_va = bb->va + gma_start_offset;
1734 s->ip_gma = gma; 1776 s->ip_gma = gma;
1735 return 0; 1777 return 0;
1736err_unmap: 1778err_unmap:
@@ -2469,15 +2511,18 @@ static int cmd_parser_exec(struct parser_exec_state *s)
2469 2511
2470 info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id); 2512 info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id);
2471 if (info == NULL) { 2513 if (info == NULL) {
2472 gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n", 2514 gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %d, workload=%p\n",
2473 cmd, get_opcode(cmd, s->ring_id)); 2515 cmd, get_opcode(cmd, s->ring_id),
2516 (s->buf_addr_type == PPGTT_BUFFER) ?
2517 "ppgtt" : "ggtt", s->ring_id, s->workload);
2474 return -EBADRQC; 2518 return -EBADRQC;
2475 } 2519 }
2476 2520
2477 s->info = info; 2521 s->info = info;
2478 2522
2479 trace_gvt_command(vgpu->id, s->ring_id, s->ip_gma, s->ip_va, 2523 trace_gvt_command(vgpu->id, s->ring_id, s->ip_gma, s->ip_va,
2480 cmd_length(s), s->buf_type); 2524 cmd_length(s), s->buf_type, s->buf_addr_type,
2525 s->workload, info->name);
2481 2526
2482 if (info->handler) { 2527 if (info->handler) {
2483 ret = info->handler(s); 2528 ret = info->handler(s);
diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c
index 32a66dfdf112..2ec89bcb59f1 100644
--- a/drivers/gpu/drm/i915/gvt/debugfs.c
+++ b/drivers/gpu/drm/i915/gvt/debugfs.c
@@ -122,18 +122,69 @@ static int vgpu_mmio_diff_show(struct seq_file *s, void *unused)
122 seq_printf(s, "Total: %d, Diff: %d\n", param.total, param.diff); 122 seq_printf(s, "Total: %d, Diff: %d\n", param.total, param.diff);
123 return 0; 123 return 0;
124} 124}
125DEFINE_SHOW_ATTRIBUTE(vgpu_mmio_diff);
125 126
126static int vgpu_mmio_diff_open(struct inode *inode, struct file *file) 127static int
128vgpu_scan_nonprivbb_get(void *data, u64 *val)
127{ 129{
128 return single_open(file, vgpu_mmio_diff_show, inode->i_private); 130 struct intel_vgpu *vgpu = (struct intel_vgpu *)data;
131 *val = vgpu->scan_nonprivbb;
132 return 0;
129} 133}
130 134
131static const struct file_operations vgpu_mmio_diff_fops = { 135/*
132 .open = vgpu_mmio_diff_open, 136 * set/unset bit engine_id of vgpu->scan_nonprivbb to turn on/off scanning
133 .read = seq_read, 137 * of non-privileged batch buffer. e.g.
134 .llseek = seq_lseek, 138 * if vgpu->scan_nonprivbb=3, then it will scan non-privileged batch buffer
135 .release = single_release, 139 * on engine 0 and 1.
136}; 140 */
141static int
142vgpu_scan_nonprivbb_set(void *data, u64 val)
143{
144 struct intel_vgpu *vgpu = (struct intel_vgpu *)data;
145 struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
146 enum intel_engine_id id;
147 char buf[128], *s;
148 int len;
149
150 val &= (1 << I915_NUM_ENGINES) - 1;
151
152 if (vgpu->scan_nonprivbb == val)
153 return 0;
154
155 if (!val)
156 goto done;
157
158 len = sprintf(buf,
159 "gvt: vgpu %d turns on non-privileged batch buffers scanning on Engines:",
160 vgpu->id);
161
162 s = buf + len;
163
164 for (id = 0; id < I915_NUM_ENGINES; id++) {
165 struct intel_engine_cs *engine;
166
167 engine = dev_priv->engine[id];
168 if (engine && (val & (1 << id))) {
169 len = snprintf(s, 4, "%d, ", engine->id);
170 s += len;
171 } else
172 val &= ~(1 << id);
173 }
174
175 if (val)
176 sprintf(s, "low performance expected.");
177
178 pr_warn("%s\n", buf);
179
180done:
181 vgpu->scan_nonprivbb = val;
182 return 0;
183}
184
185DEFINE_SIMPLE_ATTRIBUTE(vgpu_scan_nonprivbb_fops,
186 vgpu_scan_nonprivbb_get, vgpu_scan_nonprivbb_set,
187 "0x%llx\n");
137 188
138/** 189/**
139 * intel_gvt_debugfs_add_vgpu - register debugfs entries for a vGPU 190 * intel_gvt_debugfs_add_vgpu - register debugfs entries for a vGPU
@@ -162,6 +213,11 @@ int intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu)
162 if (!ent) 213 if (!ent)
163 return -ENOMEM; 214 return -ENOMEM;
164 215
216 ent = debugfs_create_file("scan_nonprivbb", 0644, vgpu->debugfs,
217 vgpu, &vgpu_scan_nonprivbb_fops);
218 if (!ent)
219 return -ENOMEM;
220
165 return 0; 221 return 0;
166} 222}
167 223
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index efacd8abbedc..05d15a095310 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -99,7 +99,6 @@ struct intel_vgpu_fence {
99struct intel_vgpu_mmio { 99struct intel_vgpu_mmio {
100 void *vreg; 100 void *vreg;
101 void *sreg; 101 void *sreg;
102 bool disable_warn_untrack;
103}; 102};
104 103
105#define INTEL_GVT_MAX_BAR_NUM 4 104#define INTEL_GVT_MAX_BAR_NUM 4
@@ -226,6 +225,7 @@ struct intel_vgpu {
226 225
227 struct completion vblank_done; 226 struct completion vblank_done;
228 227
228 u32 scan_nonprivbb;
229}; 229};
230 230
231/* validating GM healthy status*/ 231/* validating GM healthy status*/
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index a33c1c3e4a21..4b6532fb789a 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -191,6 +191,8 @@ static int sanitize_fence_mmio_access(struct intel_vgpu *vgpu,
191 unsigned int max_fence = vgpu_fence_sz(vgpu); 191 unsigned int max_fence = vgpu_fence_sz(vgpu);
192 192
193 if (fence_num >= max_fence) { 193 if (fence_num >= max_fence) {
194 gvt_vgpu_err("access oob fence reg %d/%d\n",
195 fence_num, max_fence);
194 196
195 /* When guest access oob fence regs without access 197 /* When guest access oob fence regs without access
196 * pv_info first, we treat guest not supporting GVT, 198 * pv_info first, we treat guest not supporting GVT,
@@ -200,11 +202,6 @@ static int sanitize_fence_mmio_access(struct intel_vgpu *vgpu,
200 enter_failsafe_mode(vgpu, 202 enter_failsafe_mode(vgpu,
201 GVT_FAILSAFE_UNSUPPORTED_GUEST); 203 GVT_FAILSAFE_UNSUPPORTED_GUEST);
202 204
203 if (!vgpu->mmio.disable_warn_untrack) {
204 gvt_vgpu_err("found oob fence register access\n");
205 gvt_vgpu_err("total fence %d, access fence %d\n",
206 max_fence, fence_num);
207 }
208 memset(p_data, 0, bytes); 205 memset(p_data, 0, bytes);
209 return -EINVAL; 206 return -EINVAL;
210 } 207 }
@@ -477,22 +474,28 @@ static int force_nonpriv_write(struct intel_vgpu *vgpu,
477 unsigned int offset, void *p_data, unsigned int bytes) 474 unsigned int offset, void *p_data, unsigned int bytes)
478{ 475{
479 u32 reg_nonpriv = *(u32 *)p_data; 476 u32 reg_nonpriv = *(u32 *)p_data;
477 int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
478 u32 ring_base;
479 struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
480 int ret = -EINVAL; 480 int ret = -EINVAL;
481 481
482 if ((bytes != 4) || ((offset & (bytes - 1)) != 0)) { 482 if ((bytes != 4) || ((offset & (bytes - 1)) != 0) || ring_id < 0) {
483 gvt_err("vgpu(%d) Invalid FORCE_NONPRIV offset %x(%dB)\n", 483 gvt_err("vgpu(%d) ring %d Invalid FORCE_NONPRIV offset %x(%dB)\n",
484 vgpu->id, offset, bytes); 484 vgpu->id, ring_id, offset, bytes);
485 return ret; 485 return ret;
486 } 486 }
487 487
488 if (in_whitelist(reg_nonpriv)) { 488 ring_base = dev_priv->engine[ring_id]->mmio_base;
489
490 if (in_whitelist(reg_nonpriv) ||
491 reg_nonpriv == i915_mmio_reg_offset(RING_NOPID(ring_base))) {
489 ret = intel_vgpu_default_mmio_write(vgpu, offset, p_data, 492 ret = intel_vgpu_default_mmio_write(vgpu, offset, p_data,
490 bytes); 493 bytes);
491 } else { 494 } else
492 gvt_err("vgpu(%d) Invalid FORCE_NONPRIV write %x\n", 495 gvt_err("vgpu(%d) Invalid FORCE_NONPRIV write %x at offset %x\n",
493 vgpu->id, reg_nonpriv); 496 vgpu->id, reg_nonpriv, offset);
494 } 497
495 return ret; 498 return 0;
496} 499}
497 500
498static int ddi_buf_ctl_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, 501static int ddi_buf_ctl_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
@@ -3092,9 +3095,7 @@ int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset,
3092 */ 3095 */
3093 mmio_info = find_mmio_info(gvt, offset); 3096 mmio_info = find_mmio_info(gvt, offset);
3094 if (!mmio_info) { 3097 if (!mmio_info) {
3095 if (!vgpu->mmio.disable_warn_untrack) 3098 gvt_dbg_mmio("untracked MMIO %08x len %d\n", offset, bytes);
3096 gvt_vgpu_err("untracked MMIO %08x len %d\n",
3097 offset, bytes);
3098 goto default_rw; 3099 goto default_rw;
3099 } 3100 }
3100 3101
diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c
index 11b71b33f1c0..e4960aff68bd 100644
--- a/drivers/gpu/drm/i915/gvt/mmio.c
+++ b/drivers/gpu/drm/i915/gvt/mmio.c
@@ -244,8 +244,6 @@ void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr)
244 244
245 /* set the bit 0:2(Core C-State ) to C0 */ 245 /* set the bit 0:2(Core C-State ) to C0 */
246 vgpu_vreg_t(vgpu, GEN6_GT_CORE_STATUS) = 0; 246 vgpu_vreg_t(vgpu, GEN6_GT_CORE_STATUS) = 0;
247
248 vgpu->mmio.disable_warn_untrack = false;
249 } else { 247 } else {
250#define GVT_GEN8_MMIO_RESET_OFFSET (0x44200) 248#define GVT_GEN8_MMIO_RESET_OFFSET (0x44200)
251 /* only reset the engine related, so starting with 0x44200 249 /* only reset the engine related, so starting with 0x44200
diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c
index a5bac83d53a9..0f949554d118 100644
--- a/drivers/gpu/drm/i915/gvt/mmio_context.c
+++ b/drivers/gpu/drm/i915/gvt/mmio_context.c
@@ -448,7 +448,7 @@ static void switch_mocs(struct intel_vgpu *pre, struct intel_vgpu *next,
448 448
449bool is_inhibit_context(struct i915_gem_context *ctx, int ring_id) 449bool is_inhibit_context(struct i915_gem_context *ctx, int ring_id)
450{ 450{
451 u32 *reg_state = ctx->engine[ring_id].lrc_reg_state; 451 u32 *reg_state = ctx->__engine[ring_id].lrc_reg_state;
452 u32 inhibit_mask = 452 u32 inhibit_mask =
453 _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); 453 _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
454 454
diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c
index 75b7bc7b344c..d053cbe1dc94 100644
--- a/drivers/gpu/drm/i915/gvt/sched_policy.c
+++ b/drivers/gpu/drm/i915/gvt/sched_policy.c
@@ -53,7 +53,6 @@ struct vgpu_sched_data {
53 bool active; 53 bool active;
54 54
55 ktime_t sched_in_time; 55 ktime_t sched_in_time;
56 ktime_t sched_out_time;
57 ktime_t sched_time; 56 ktime_t sched_time;
58 ktime_t left_ts; 57 ktime_t left_ts;
59 ktime_t allocated_ts; 58 ktime_t allocated_ts;
@@ -66,17 +65,22 @@ struct gvt_sched_data {
66 struct hrtimer timer; 65 struct hrtimer timer;
67 unsigned long period; 66 unsigned long period;
68 struct list_head lru_runq_head; 67 struct list_head lru_runq_head;
68 ktime_t expire_time;
69}; 69};
70 70
71static void vgpu_update_timeslice(struct intel_vgpu *pre_vgpu) 71static void vgpu_update_timeslice(struct intel_vgpu *vgpu, ktime_t cur_time)
72{ 72{
73 ktime_t delta_ts; 73 ktime_t delta_ts;
74 struct vgpu_sched_data *vgpu_data = pre_vgpu->sched_data; 74 struct vgpu_sched_data *vgpu_data;
75 75
76 delta_ts = vgpu_data->sched_out_time - vgpu_data->sched_in_time; 76 if (!vgpu || vgpu == vgpu->gvt->idle_vgpu)
77 return;
77 78
78 vgpu_data->sched_time += delta_ts; 79 vgpu_data = vgpu->sched_data;
79 vgpu_data->left_ts -= delta_ts; 80 delta_ts = ktime_sub(cur_time, vgpu_data->sched_in_time);
81 vgpu_data->sched_time = ktime_add(vgpu_data->sched_time, delta_ts);
82 vgpu_data->left_ts = ktime_sub(vgpu_data->left_ts, delta_ts);
83 vgpu_data->sched_in_time = cur_time;
80} 84}
81 85
82#define GVT_TS_BALANCE_PERIOD_MS 100 86#define GVT_TS_BALANCE_PERIOD_MS 100
@@ -150,11 +154,7 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
150 } 154 }
151 155
152 cur_time = ktime_get(); 156 cur_time = ktime_get();
153 if (scheduler->current_vgpu) { 157 vgpu_update_timeslice(scheduler->current_vgpu, cur_time);
154 vgpu_data = scheduler->current_vgpu->sched_data;
155 vgpu_data->sched_out_time = cur_time;
156 vgpu_update_timeslice(scheduler->current_vgpu);
157 }
158 vgpu_data = scheduler->next_vgpu->sched_data; 158 vgpu_data = scheduler->next_vgpu->sched_data;
159 vgpu_data->sched_in_time = cur_time; 159 vgpu_data->sched_in_time = cur_time;
160 160
@@ -226,17 +226,22 @@ out:
226void intel_gvt_schedule(struct intel_gvt *gvt) 226void intel_gvt_schedule(struct intel_gvt *gvt)
227{ 227{
228 struct gvt_sched_data *sched_data = gvt->scheduler.sched_data; 228 struct gvt_sched_data *sched_data = gvt->scheduler.sched_data;
229 static uint64_t timer_check; 229 ktime_t cur_time;
230 230
231 mutex_lock(&gvt->lock); 231 mutex_lock(&gvt->lock);
232 cur_time = ktime_get();
232 233
233 if (test_and_clear_bit(INTEL_GVT_REQUEST_SCHED, 234 if (test_and_clear_bit(INTEL_GVT_REQUEST_SCHED,
234 (void *)&gvt->service_request)) { 235 (void *)&gvt->service_request)) {
235 if (!(timer_check++ % GVT_TS_BALANCE_PERIOD_MS)) 236 if (cur_time >= sched_data->expire_time) {
236 gvt_balance_timeslice(sched_data); 237 gvt_balance_timeslice(sched_data);
238 sched_data->expire_time = ktime_add_ms(
239 cur_time, GVT_TS_BALANCE_PERIOD_MS);
240 }
237 } 241 }
238 clear_bit(INTEL_GVT_REQUEST_EVENT_SCHED, (void *)&gvt->service_request); 242 clear_bit(INTEL_GVT_REQUEST_EVENT_SCHED, (void *)&gvt->service_request);
239 243
244 vgpu_update_timeslice(gvt->scheduler.current_vgpu, cur_time);
240 tbs_sched_func(sched_data); 245 tbs_sched_func(sched_data);
241 246
242 mutex_unlock(&gvt->lock); 247 mutex_unlock(&gvt->lock);
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 638abe84857c..c2d183b91500 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -58,7 +58,7 @@ static void update_shadow_pdps(struct intel_vgpu_workload *workload)
58 int ring_id = workload->ring_id; 58 int ring_id = workload->ring_id;
59 struct i915_gem_context *shadow_ctx = vgpu->submission.shadow_ctx; 59 struct i915_gem_context *shadow_ctx = vgpu->submission.shadow_ctx;
60 struct drm_i915_gem_object *ctx_obj = 60 struct drm_i915_gem_object *ctx_obj =
61 shadow_ctx->engine[ring_id].state->obj; 61 shadow_ctx->__engine[ring_id].state->obj;
62 struct execlist_ring_context *shadow_ring_context; 62 struct execlist_ring_context *shadow_ring_context;
63 struct page *page; 63 struct page *page;
64 64
@@ -97,7 +97,7 @@ static void sr_oa_regs(struct intel_vgpu_workload *workload,
97 i915_mmio_reg_offset(EU_PERF_CNTL6), 97 i915_mmio_reg_offset(EU_PERF_CNTL6),
98 }; 98 };
99 99
100 if (!workload || !reg_state || workload->ring_id != RCS) 100 if (workload->ring_id != RCS)
101 return; 101 return;
102 102
103 if (save) { 103 if (save) {
@@ -130,7 +130,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
130 int ring_id = workload->ring_id; 130 int ring_id = workload->ring_id;
131 struct i915_gem_context *shadow_ctx = vgpu->submission.shadow_ctx; 131 struct i915_gem_context *shadow_ctx = vgpu->submission.shadow_ctx;
132 struct drm_i915_gem_object *ctx_obj = 132 struct drm_i915_gem_object *ctx_obj =
133 shadow_ctx->engine[ring_id].state->obj; 133 shadow_ctx->__engine[ring_id].state->obj;
134 struct execlist_ring_context *shadow_ring_context; 134 struct execlist_ring_context *shadow_ring_context;
135 struct page *page; 135 struct page *page;
136 void *dst; 136 void *dst;
@@ -283,7 +283,7 @@ static int shadow_context_status_change(struct notifier_block *nb,
283static void shadow_context_descriptor_update(struct i915_gem_context *ctx, 283static void shadow_context_descriptor_update(struct i915_gem_context *ctx,
284 struct intel_engine_cs *engine) 284 struct intel_engine_cs *engine)
285{ 285{
286 struct intel_context *ce = &ctx->engine[engine->id]; 286 struct intel_context *ce = to_intel_context(ctx, engine);
287 u64 desc = 0; 287 u64 desc = 0;
288 288
289 desc = ce->lrc_desc; 289 desc = ce->lrc_desc;
@@ -389,7 +389,7 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
389 * shadow_ctx pages invalid. So gvt need to pin itself. After update 389 * shadow_ctx pages invalid. So gvt need to pin itself. After update
390 * the guest context, gvt can unpin the shadow_ctx safely. 390 * the guest context, gvt can unpin the shadow_ctx safely.
391 */ 391 */
392 ring = engine->context_pin(engine, shadow_ctx); 392 ring = intel_context_pin(shadow_ctx, engine);
393 if (IS_ERR(ring)) { 393 if (IS_ERR(ring)) {
394 ret = PTR_ERR(ring); 394 ret = PTR_ERR(ring);
395 gvt_vgpu_err("fail to pin shadow context\n"); 395 gvt_vgpu_err("fail to pin shadow context\n");
@@ -403,7 +403,7 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
403 return 0; 403 return 0;
404 404
405err_unpin: 405err_unpin:
406 engine->context_unpin(engine, shadow_ctx); 406 intel_context_unpin(shadow_ctx, engine);
407err_shadow: 407err_shadow:
408 release_shadow_wa_ctx(&workload->wa_ctx); 408 release_shadow_wa_ctx(&workload->wa_ctx);
409err_scan: 409err_scan:
@@ -437,7 +437,7 @@ static int intel_gvt_generate_request(struct intel_vgpu_workload *workload)
437 return 0; 437 return 0;
438 438
439err_unpin: 439err_unpin:
440 engine->context_unpin(engine, shadow_ctx); 440 intel_context_unpin(shadow_ctx, engine);
441 release_shadow_wa_ctx(&workload->wa_ctx); 441 release_shadow_wa_ctx(&workload->wa_ctx);
442 return ret; 442 return ret;
443} 443}
@@ -452,12 +452,6 @@ static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
452 int ret; 452 int ret;
453 453
454 list_for_each_entry(bb, &workload->shadow_bb, list) { 454 list_for_each_entry(bb, &workload->shadow_bb, list) {
455 bb->vma = i915_gem_object_ggtt_pin(bb->obj, NULL, 0, 0, 0);
456 if (IS_ERR(bb->vma)) {
457 ret = PTR_ERR(bb->vma);
458 goto err;
459 }
460
461 /* For privilge batch buffer and not wa_ctx, the bb_start_cmd_va 455 /* For privilge batch buffer and not wa_ctx, the bb_start_cmd_va
462 * is only updated into ring_scan_buffer, not real ring address 456 * is only updated into ring_scan_buffer, not real ring address
463 * allocated in later copy_workload_to_ring_buffer. pls be noted 457 * allocated in later copy_workload_to_ring_buffer. pls be noted
@@ -469,25 +463,53 @@ static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
469 bb->bb_start_cmd_va = workload->shadow_ring_buffer_va 463 bb->bb_start_cmd_va = workload->shadow_ring_buffer_va
470 + bb->bb_offset; 464 + bb->bb_offset;
471 465
472 /* relocate shadow batch buffer */ 466 if (bb->ppgtt) {
473 bb->bb_start_cmd_va[1] = i915_ggtt_offset(bb->vma); 467 /* for non-priv bb, scan&shadow is only for
474 if (gmadr_bytes == 8) 468 * debugging purpose, so the content of shadow bb
475 bb->bb_start_cmd_va[2] = 0; 469 * is the same as original bb. Therefore,
470 * here, rather than switch to shadow bb's gma
471 * address, we directly use original batch buffer's
472 * gma address, and send original bb to hardware
473 * directly
474 */
475 if (bb->clflush & CLFLUSH_AFTER) {
476 drm_clflush_virt_range(bb->va,
477 bb->obj->base.size);
478 bb->clflush &= ~CLFLUSH_AFTER;
479 }
480 i915_gem_obj_finish_shmem_access(bb->obj);
481 bb->accessing = false;
482
483 } else {
484 bb->vma = i915_gem_object_ggtt_pin(bb->obj,
485 NULL, 0, 0, 0);
486 if (IS_ERR(bb->vma)) {
487 ret = PTR_ERR(bb->vma);
488 goto err;
489 }
476 490
477 /* No one is going to touch shadow bb from now on. */ 491 /* relocate shadow batch buffer */
478 if (bb->clflush & CLFLUSH_AFTER) { 492 bb->bb_start_cmd_va[1] = i915_ggtt_offset(bb->vma);
479 drm_clflush_virt_range(bb->va, bb->obj->base.size); 493 if (gmadr_bytes == 8)
480 bb->clflush &= ~CLFLUSH_AFTER; 494 bb->bb_start_cmd_va[2] = 0;
481 }
482 495
483 ret = i915_gem_object_set_to_gtt_domain(bb->obj, false); 496 /* No one is going to touch shadow bb from now on. */
484 if (ret) 497 if (bb->clflush & CLFLUSH_AFTER) {
485 goto err; 498 drm_clflush_virt_range(bb->va,
499 bb->obj->base.size);
500 bb->clflush &= ~CLFLUSH_AFTER;
501 }
486 502
487 i915_gem_obj_finish_shmem_access(bb->obj); 503 ret = i915_gem_object_set_to_gtt_domain(bb->obj,
488 bb->accessing = false; 504 false);
505 if (ret)
506 goto err;
489 507
490 i915_vma_move_to_active(bb->vma, workload->req, 0); 508 i915_gem_obj_finish_shmem_access(bb->obj);
509 bb->accessing = false;
510
511 i915_vma_move_to_active(bb->vma, workload->req, 0);
512 }
491 } 513 }
492 return 0; 514 return 0;
493err: 515err:
@@ -504,7 +526,7 @@ static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx)
504 struct intel_vgpu_submission *s = &workload->vgpu->submission; 526 struct intel_vgpu_submission *s = &workload->vgpu->submission;
505 struct i915_gem_context *shadow_ctx = s->shadow_ctx; 527 struct i915_gem_context *shadow_ctx = s->shadow_ctx;
506 struct drm_i915_gem_object *ctx_obj = 528 struct drm_i915_gem_object *ctx_obj =
507 shadow_ctx->engine[ring_id].state->obj; 529 shadow_ctx->__engine[ring_id].state->obj;
508 struct execlist_ring_context *shadow_ring_context; 530 struct execlist_ring_context *shadow_ring_context;
509 struct page *page; 531 struct page *page;
510 532
@@ -666,7 +688,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
666 688
667 ret = prepare_workload(workload); 689 ret = prepare_workload(workload);
668 if (ret) { 690 if (ret) {
669 engine->context_unpin(engine, shadow_ctx); 691 intel_context_unpin(shadow_ctx, engine);
670 goto out; 692 goto out;
671 } 693 }
672 694
@@ -749,7 +771,7 @@ static void update_guest_context(struct intel_vgpu_workload *workload)
749 struct i915_gem_context *shadow_ctx = s->shadow_ctx; 771 struct i915_gem_context *shadow_ctx = s->shadow_ctx;
750 int ring_id = workload->ring_id; 772 int ring_id = workload->ring_id;
751 struct drm_i915_gem_object *ctx_obj = 773 struct drm_i915_gem_object *ctx_obj =
752 shadow_ctx->engine[ring_id].state->obj; 774 shadow_ctx->__engine[ring_id].state->obj;
753 struct execlist_ring_context *shadow_ring_context; 775 struct execlist_ring_context *shadow_ring_context;
754 struct page *page; 776 struct page *page;
755 void *src; 777 void *src;
@@ -876,7 +898,7 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
876 } 898 }
877 mutex_lock(&dev_priv->drm.struct_mutex); 899 mutex_lock(&dev_priv->drm.struct_mutex);
878 /* unpin shadow ctx as the shadow_ctx update is done */ 900 /* unpin shadow ctx as the shadow_ctx update is done */
879 engine->context_unpin(engine, s->shadow_ctx); 901 intel_context_unpin(s->shadow_ctx, engine);
880 mutex_unlock(&dev_priv->drm.struct_mutex); 902 mutex_unlock(&dev_priv->drm.struct_mutex);
881 } 903 }
882 904
@@ -1134,9 +1156,6 @@ int intel_vgpu_setup_submission(struct intel_vgpu *vgpu)
1134 if (IS_ERR(s->shadow_ctx)) 1156 if (IS_ERR(s->shadow_ctx))
1135 return PTR_ERR(s->shadow_ctx); 1157 return PTR_ERR(s->shadow_ctx);
1136 1158
1137 if (HAS_LOGICAL_RING_PREEMPTION(vgpu->gvt->dev_priv))
1138 s->shadow_ctx->priority = INT_MAX;
1139
1140 bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES); 1159 bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES);
1141 1160
1142 s->workloads = kmem_cache_create_usercopy("gvt-g_vgpu_workload", 1161 s->workloads = kmem_cache_create_usercopy("gvt-g_vgpu_workload",
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h
index 486ed57a4ad1..6c644782193e 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.h
+++ b/drivers/gpu/drm/i915/gvt/scheduler.h
@@ -125,6 +125,7 @@ struct intel_vgpu_shadow_bb {
125 unsigned int clflush; 125 unsigned int clflush;
126 bool accessing; 126 bool accessing;
127 unsigned long bb_offset; 127 unsigned long bb_offset;
128 bool ppgtt;
128}; 129};
129 130
130#define workload_q_head(vgpu, ring_id) \ 131#define workload_q_head(vgpu, ring_id) \
diff --git a/drivers/gpu/drm/i915/gvt/trace.h b/drivers/gpu/drm/i915/gvt/trace.h
index 82093f1e8612..1fd64202d74e 100644
--- a/drivers/gpu/drm/i915/gvt/trace.h
+++ b/drivers/gpu/drm/i915/gvt/trace.h
@@ -224,19 +224,25 @@ TRACE_EVENT(oos_sync,
224 TP_printk("%s", __entry->buf) 224 TP_printk("%s", __entry->buf)
225); 225);
226 226
227#define GVT_CMD_STR_LEN 40
227TRACE_EVENT(gvt_command, 228TRACE_EVENT(gvt_command,
228 TP_PROTO(u8 vgpu_id, u8 ring_id, u32 ip_gma, u32 *cmd_va, u32 cmd_len, 229 TP_PROTO(u8 vgpu_id, u8 ring_id, u32 ip_gma, u32 *cmd_va,
229 u32 buf_type), 230 u32 cmd_len, u32 buf_type, u32 buf_addr_type,
231 void *workload, char *cmd_name),
230 232
231 TP_ARGS(vgpu_id, ring_id, ip_gma, cmd_va, cmd_len, buf_type), 233 TP_ARGS(vgpu_id, ring_id, ip_gma, cmd_va, cmd_len, buf_type,
234 buf_addr_type, workload, cmd_name),
232 235
233 TP_STRUCT__entry( 236 TP_STRUCT__entry(
234 __field(u8, vgpu_id) 237 __field(u8, vgpu_id)
235 __field(u8, ring_id) 238 __field(u8, ring_id)
236 __field(u32, ip_gma) 239 __field(u32, ip_gma)
237 __field(u32, buf_type) 240 __field(u32, buf_type)
241 __field(u32, buf_addr_type)
238 __field(u32, cmd_len) 242 __field(u32, cmd_len)
243 __field(void*, workload)
239 __dynamic_array(u32, raw_cmd, cmd_len) 244 __dynamic_array(u32, raw_cmd, cmd_len)
245 __array(char, cmd_name, GVT_CMD_STR_LEN)
240 ), 246 ),
241 247
242 TP_fast_assign( 248 TP_fast_assign(
@@ -244,17 +250,25 @@ TRACE_EVENT(gvt_command,
244 __entry->ring_id = ring_id; 250 __entry->ring_id = ring_id;
245 __entry->ip_gma = ip_gma; 251 __entry->ip_gma = ip_gma;
246 __entry->buf_type = buf_type; 252 __entry->buf_type = buf_type;
253 __entry->buf_addr_type = buf_addr_type;
247 __entry->cmd_len = cmd_len; 254 __entry->cmd_len = cmd_len;
255 __entry->workload = workload;
256 snprintf(__entry->cmd_name, GVT_CMD_STR_LEN, "%s", cmd_name);
248 memcpy(__get_dynamic_array(raw_cmd), cmd_va, cmd_len * sizeof(*cmd_va)); 257 memcpy(__get_dynamic_array(raw_cmd), cmd_va, cmd_len * sizeof(*cmd_va));
249 ), 258 ),
250 259
251 260
252 TP_printk("vgpu%d ring %d: buf_type %u, ip_gma %08x, raw cmd %s", 261 TP_printk("vgpu%d ring %d: address_type %u, buf_type %u, ip_gma %08x,cmd (name=%s,len=%u,raw cmd=%s), workload=%p\n",
253 __entry->vgpu_id, 262 __entry->vgpu_id,
254 __entry->ring_id, 263 __entry->ring_id,
264 __entry->buf_addr_type,
255 __entry->buf_type, 265 __entry->buf_type,
256 __entry->ip_gma, 266 __entry->ip_gma,
257 __print_array(__get_dynamic_array(raw_cmd), __entry->cmd_len, 4)) 267 __entry->cmd_name,
268 __entry->cmd_len,
269 __print_array(__get_dynamic_array(raw_cmd),
270 __entry->cmd_len, 4),
271 __entry->workload)
258); 272);
259 273
260#define GVT_TEMP_STR_LEN 10 274#define GVT_TEMP_STR_LEN 10
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 89f7ff2c652e..13e7b9e4a6e6 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -377,16 +377,19 @@ static void print_batch_pool_stats(struct seq_file *m,
377 print_file_stats(m, "[k]batch pool", stats); 377 print_file_stats(m, "[k]batch pool", stats);
378} 378}
379 379
380static int per_file_ctx_stats(int id, void *ptr, void *data) 380static int per_file_ctx_stats(int idx, void *ptr, void *data)
381{ 381{
382 struct i915_gem_context *ctx = ptr; 382 struct i915_gem_context *ctx = ptr;
383 int n; 383 struct intel_engine_cs *engine;
384 enum intel_engine_id id;
385
386 for_each_engine(engine, ctx->i915, id) {
387 struct intel_context *ce = to_intel_context(ctx, engine);
384 388
385 for (n = 0; n < ARRAY_SIZE(ctx->engine); n++) { 389 if (ce->state)
386 if (ctx->engine[n].state) 390 per_file_stats(0, ce->state->obj, data);
387 per_file_stats(0, ctx->engine[n].state->obj, data); 391 if (ce->ring)
388 if (ctx->engine[n].ring) 392 per_file_stats(0, ce->ring->vma->obj, data);
389 per_file_stats(0, ctx->engine[n].ring->vma->obj, data);
390 } 393 }
391 394
392 return 0; 395 return 0;
@@ -1215,20 +1218,20 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
1215 max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 : 1218 max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 :
1216 rp_state_cap >> 16) & 0xff; 1219 rp_state_cap >> 16) & 0xff;
1217 max_freq *= (IS_GEN9_BC(dev_priv) || 1220 max_freq *= (IS_GEN9_BC(dev_priv) ||
1218 IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1); 1221 INTEL_GEN(dev_priv) >= 10 ? GEN9_FREQ_SCALER : 1);
1219 seq_printf(m, "Lowest (RPN) frequency: %dMHz\n", 1222 seq_printf(m, "Lowest (RPN) frequency: %dMHz\n",
1220 intel_gpu_freq(dev_priv, max_freq)); 1223 intel_gpu_freq(dev_priv, max_freq));
1221 1224
1222 max_freq = (rp_state_cap & 0xff00) >> 8; 1225 max_freq = (rp_state_cap & 0xff00) >> 8;
1223 max_freq *= (IS_GEN9_BC(dev_priv) || 1226 max_freq *= (IS_GEN9_BC(dev_priv) ||
1224 IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1); 1227 INTEL_GEN(dev_priv) >= 10 ? GEN9_FREQ_SCALER : 1);
1225 seq_printf(m, "Nominal (RP1) frequency: %dMHz\n", 1228 seq_printf(m, "Nominal (RP1) frequency: %dMHz\n",
1226 intel_gpu_freq(dev_priv, max_freq)); 1229 intel_gpu_freq(dev_priv, max_freq));
1227 1230
1228 max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 16 : 1231 max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 16 :
1229 rp_state_cap >> 0) & 0xff; 1232 rp_state_cap >> 0) & 0xff;
1230 max_freq *= (IS_GEN9_BC(dev_priv) || 1233 max_freq *= (IS_GEN9_BC(dev_priv) ||
1231 IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1); 1234 INTEL_GEN(dev_priv) >= 10 ? GEN9_FREQ_SCALER : 1);
1232 seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", 1235 seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
1233 intel_gpu_freq(dev_priv, max_freq)); 1236 intel_gpu_freq(dev_priv, max_freq));
1234 seq_printf(m, "Max overclocked frequency: %dMHz\n", 1237 seq_printf(m, "Max overclocked frequency: %dMHz\n",
@@ -1340,10 +1343,9 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
1340 struct rb_node *rb; 1343 struct rb_node *rb;
1341 1344
1342 seq_printf(m, "%s:\n", engine->name); 1345 seq_printf(m, "%s:\n", engine->name);
1343 seq_printf(m, "\tseqno = %x [current %x, last %x], inflight %d\n", 1346 seq_printf(m, "\tseqno = %x [current %x, last %x]\n",
1344 engine->hangcheck.seqno, seqno[id], 1347 engine->hangcheck.seqno, seqno[id],
1345 intel_engine_last_submit(engine), 1348 intel_engine_last_submit(engine));
1346 engine->timeline->inflight_seqnos);
1347 seq_printf(m, "\twaiters? %s, fake irq active? %s, stalled? %s\n", 1349 seq_printf(m, "\twaiters? %s, fake irq active? %s, stalled? %s\n",
1348 yesno(intel_engine_has_waiter(engine)), 1350 yesno(intel_engine_has_waiter(engine)),
1349 yesno(test_bit(engine->id, 1351 yesno(test_bit(engine->id,
@@ -1796,9 +1798,9 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
1796{ 1798{
1797 struct drm_i915_private *dev_priv = node_to_i915(m->private); 1799 struct drm_i915_private *dev_priv = node_to_i915(m->private);
1798 struct intel_rps *rps = &dev_priv->gt_pm.rps; 1800 struct intel_rps *rps = &dev_priv->gt_pm.rps;
1799 int ret = 0;
1800 int gpu_freq, ia_freq;
1801 unsigned int max_gpu_freq, min_gpu_freq; 1801 unsigned int max_gpu_freq, min_gpu_freq;
1802 int gpu_freq, ia_freq;
1803 int ret;
1802 1804
1803 if (!HAS_LLC(dev_priv)) 1805 if (!HAS_LLC(dev_priv))
1804 return -ENODEV; 1806 return -ENODEV;
@@ -1809,13 +1811,12 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
1809 if (ret) 1811 if (ret)
1810 goto out; 1812 goto out;
1811 1813
1812 if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { 1814 min_gpu_freq = rps->min_freq;
1815 max_gpu_freq = rps->max_freq;
1816 if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
1813 /* Convert GT frequency to 50 HZ units */ 1817 /* Convert GT frequency to 50 HZ units */
1814 min_gpu_freq = rps->min_freq_softlimit / GEN9_FREQ_SCALER; 1818 min_gpu_freq /= GEN9_FREQ_SCALER;
1815 max_gpu_freq = rps->max_freq_softlimit / GEN9_FREQ_SCALER; 1819 max_gpu_freq /= GEN9_FREQ_SCALER;
1816 } else {
1817 min_gpu_freq = rps->min_freq_softlimit;
1818 max_gpu_freq = rps->max_freq_softlimit;
1819 } 1820 }
1820 1821
1821 seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n"); 1822 seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n");
@@ -1828,7 +1829,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
1828 seq_printf(m, "%d\t\t%d\t\t\t\t%d\n", 1829 seq_printf(m, "%d\t\t%d\t\t\t\t%d\n",
1829 intel_gpu_freq(dev_priv, (gpu_freq * 1830 intel_gpu_freq(dev_priv, (gpu_freq *
1830 (IS_GEN9_BC(dev_priv) || 1831 (IS_GEN9_BC(dev_priv) ||
1831 IS_CANNONLAKE(dev_priv) ? 1832 INTEL_GEN(dev_priv) >= 10 ?
1832 GEN9_FREQ_SCALER : 1))), 1833 GEN9_FREQ_SCALER : 1))),
1833 ((ia_freq >> 0) & 0xff) * 100, 1834 ((ia_freq >> 0) & 0xff) * 100,
1834 ((ia_freq >> 8) & 0xff) * 100); 1835 ((ia_freq >> 8) & 0xff) * 100);
@@ -1923,8 +1924,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
1923 1924
1924static void describe_ctx_ring(struct seq_file *m, struct intel_ring *ring) 1925static void describe_ctx_ring(struct seq_file *m, struct intel_ring *ring)
1925{ 1926{
1926 seq_printf(m, " (ringbuffer, space: %d, head: %u, tail: %u)", 1927 seq_printf(m, " (ringbuffer, space: %d, head: %u, tail: %u, emit: %u)",
1927 ring->space, ring->head, ring->tail); 1928 ring->space, ring->head, ring->tail, ring->emit);
1928} 1929}
1929 1930
1930static int i915_context_status(struct seq_file *m, void *unused) 1931static int i915_context_status(struct seq_file *m, void *unused)
@@ -1961,7 +1962,8 @@ static int i915_context_status(struct seq_file *m, void *unused)
1961 seq_putc(m, '\n'); 1962 seq_putc(m, '\n');
1962 1963
1963 for_each_engine(engine, dev_priv, id) { 1964 for_each_engine(engine, dev_priv, id) {
1964 struct intel_context *ce = &ctx->engine[engine->id]; 1965 struct intel_context *ce =
1966 to_intel_context(ctx, engine);
1965 1967
1966 seq_printf(m, "%s: ", engine->name); 1968 seq_printf(m, "%s: ", engine->name);
1967 if (ce->state) 1969 if (ce->state)
@@ -2326,30 +2328,45 @@ static int i915_guc_load_status_info(struct seq_file *m, void *data)
2326 return 0; 2328 return 0;
2327} 2329}
2328 2330
2329static void i915_guc_log_info(struct seq_file *m, 2331static const char *
2330 struct drm_i915_private *dev_priv) 2332stringify_guc_log_type(enum guc_log_buffer_type type)
2331{ 2333{
2332 struct intel_guc *guc = &dev_priv->guc; 2334 switch (type) {
2335 case GUC_ISR_LOG_BUFFER:
2336 return "ISR";
2337 case GUC_DPC_LOG_BUFFER:
2338 return "DPC";
2339 case GUC_CRASH_DUMP_LOG_BUFFER:
2340 return "CRASH";
2341 default:
2342 MISSING_CASE(type);
2343 }
2333 2344
2334 seq_puts(m, "\nGuC logging stats:\n"); 2345 return "";
2346}
2335 2347
2336 seq_printf(m, "\tISR: flush count %10u, overflow count %10u\n", 2348static void i915_guc_log_info(struct seq_file *m,
2337 guc->log.flush_count[GUC_ISR_LOG_BUFFER], 2349 struct drm_i915_private *dev_priv)
2338 guc->log.total_overflow_count[GUC_ISR_LOG_BUFFER]); 2350{
2351 struct intel_guc_log *log = &dev_priv->guc.log;
2352 enum guc_log_buffer_type type;
2339 2353
2340 seq_printf(m, "\tDPC: flush count %10u, overflow count %10u\n", 2354 if (!intel_guc_log_relay_enabled(log)) {
2341 guc->log.flush_count[GUC_DPC_LOG_BUFFER], 2355 seq_puts(m, "GuC log relay disabled\n");
2342 guc->log.total_overflow_count[GUC_DPC_LOG_BUFFER]); 2356 return;
2357 }
2343 2358
2344 seq_printf(m, "\tCRASH: flush count %10u, overflow count %10u\n", 2359 seq_puts(m, "GuC logging stats:\n");
2345 guc->log.flush_count[GUC_CRASH_DUMP_LOG_BUFFER],
2346 guc->log.total_overflow_count[GUC_CRASH_DUMP_LOG_BUFFER]);
2347 2360
2348 seq_printf(m, "\tTotal flush interrupt count: %u\n", 2361 seq_printf(m, "\tRelay full count: %u\n",
2349 guc->log.flush_interrupt_count); 2362 log->relay.full_count);
2350 2363
2351 seq_printf(m, "\tCapture miss count: %u\n", 2364 for (type = GUC_ISR_LOG_BUFFER; type < GUC_MAX_LOG_BUFFER; type++) {
2352 guc->log.capture_miss_count); 2365 seq_printf(m, "\t%s:\tflush count %10u, overflow count %10u\n",
2366 stringify_guc_log_type(type),
2367 log->stats[type].flush,
2368 log->stats[type].sampled_overflow);
2369 }
2353} 2370}
2354 2371
2355static void i915_guc_client_info(struct seq_file *m, 2372static void i915_guc_client_info(struct seq_file *m,
@@ -2379,14 +2396,19 @@ static int i915_guc_info(struct seq_file *m, void *data)
2379 struct drm_i915_private *dev_priv = node_to_i915(m->private); 2396 struct drm_i915_private *dev_priv = node_to_i915(m->private);
2380 const struct intel_guc *guc = &dev_priv->guc; 2397 const struct intel_guc *guc = &dev_priv->guc;
2381 2398
2382 if (!USES_GUC_SUBMISSION(dev_priv)) 2399 if (!USES_GUC(dev_priv))
2383 return -ENODEV; 2400 return -ENODEV;
2384 2401
2402 i915_guc_log_info(m, dev_priv);
2403
2404 if (!USES_GUC_SUBMISSION(dev_priv))
2405 return 0;
2406
2385 GEM_BUG_ON(!guc->execbuf_client); 2407 GEM_BUG_ON(!guc->execbuf_client);
2386 2408
2387 seq_printf(m, "Doorbell map:\n"); 2409 seq_printf(m, "\nDoorbell map:\n");
2388 seq_printf(m, "\t%*pb\n", GUC_NUM_DOORBELLS, guc->doorbell_bitmap); 2410 seq_printf(m, "\t%*pb\n", GUC_NUM_DOORBELLS, guc->doorbell_bitmap);
2389 seq_printf(m, "Doorbell next cacheline: 0x%x\n\n", guc->db_cacheline); 2411 seq_printf(m, "Doorbell next cacheline: 0x%x\n", guc->db_cacheline);
2390 2412
2391 seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->execbuf_client); 2413 seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->execbuf_client);
2392 i915_guc_client_info(m, dev_priv, guc->execbuf_client); 2414 i915_guc_client_info(m, dev_priv, guc->execbuf_client);
@@ -2396,8 +2418,6 @@ static int i915_guc_info(struct seq_file *m, void *data)
2396 i915_guc_client_info(m, dev_priv, guc->preempt_client); 2418 i915_guc_client_info(m, dev_priv, guc->preempt_client);
2397 } 2419 }
2398 2420
2399 i915_guc_log_info(m, dev_priv);
2400
2401 /* Add more as required ... */ 2421 /* Add more as required ... */
2402 2422
2403 return 0; 2423 return 0;
@@ -2496,35 +2516,73 @@ static int i915_guc_log_dump(struct seq_file *m, void *data)
2496 return 0; 2516 return 0;
2497} 2517}
2498 2518
2499static int i915_guc_log_control_get(void *data, u64 *val) 2519static int i915_guc_log_level_get(void *data, u64 *val)
2500{ 2520{
2501 struct drm_i915_private *dev_priv = data; 2521 struct drm_i915_private *dev_priv = data;
2502 2522
2503 if (!HAS_GUC(dev_priv)) 2523 if (!USES_GUC(dev_priv))
2504 return -ENODEV; 2524 return -ENODEV;
2505 2525
2506 if (!dev_priv->guc.log.vma) 2526 *val = intel_guc_log_level_get(&dev_priv->guc.log);
2507 return -EINVAL;
2508
2509 *val = i915_modparams.guc_log_level;
2510 2527
2511 return 0; 2528 return 0;
2512} 2529}
2513 2530
2514static int i915_guc_log_control_set(void *data, u64 val) 2531static int i915_guc_log_level_set(void *data, u64 val)
2515{ 2532{
2516 struct drm_i915_private *dev_priv = data; 2533 struct drm_i915_private *dev_priv = data;
2517 2534
2518 if (!HAS_GUC(dev_priv)) 2535 if (!USES_GUC(dev_priv))
2519 return -ENODEV; 2536 return -ENODEV;
2520 2537
2521 return intel_guc_log_control(&dev_priv->guc, val); 2538 return intel_guc_log_level_set(&dev_priv->guc.log, val);
2522} 2539}
2523 2540
2524DEFINE_SIMPLE_ATTRIBUTE(i915_guc_log_control_fops, 2541DEFINE_SIMPLE_ATTRIBUTE(i915_guc_log_level_fops,
2525 i915_guc_log_control_get, i915_guc_log_control_set, 2542 i915_guc_log_level_get, i915_guc_log_level_set,
2526 "%lld\n"); 2543 "%lld\n");
2527 2544
2545static int i915_guc_log_relay_open(struct inode *inode, struct file *file)
2546{
2547 struct drm_i915_private *dev_priv = inode->i_private;
2548
2549 if (!USES_GUC(dev_priv))
2550 return -ENODEV;
2551
2552 file->private_data = &dev_priv->guc.log;
2553
2554 return intel_guc_log_relay_open(&dev_priv->guc.log);
2555}
2556
2557static ssize_t
2558i915_guc_log_relay_write(struct file *filp,
2559 const char __user *ubuf,
2560 size_t cnt,
2561 loff_t *ppos)
2562{
2563 struct intel_guc_log *log = filp->private_data;
2564
2565 intel_guc_log_relay_flush(log);
2566
2567 return cnt;
2568}
2569
2570static int i915_guc_log_relay_release(struct inode *inode, struct file *file)
2571{
2572 struct drm_i915_private *dev_priv = inode->i_private;
2573
2574 intel_guc_log_relay_close(&dev_priv->guc.log);
2575
2576 return 0;
2577}
2578
2579static const struct file_operations i915_guc_log_relay_fops = {
2580 .owner = THIS_MODULE,
2581 .open = i915_guc_log_relay_open,
2582 .write = i915_guc_log_relay_write,
2583 .release = i915_guc_log_relay_release,
2584};
2585
2528static const char *psr2_live_status(u32 val) 2586static const char *psr2_live_status(u32 val)
2529{ 2587{
2530 static const char * const live_status[] = { 2588 static const char * const live_status[] = {
@@ -2548,6 +2606,26 @@ static const char *psr2_live_status(u32 val)
2548 return "unknown"; 2606 return "unknown";
2549} 2607}
2550 2608
2609static const char *psr_sink_status(u8 val)
2610{
2611 static const char * const sink_status[] = {
2612 "inactive",
2613 "transition to active, capture and display",
2614 "active, display from RFB",
2615 "active, capture and display on sink device timings",
2616 "transition to inactive, capture and display, timing re-sync",
2617 "reserved",
2618 "reserved",
2619 "sink internal error"
2620 };
2621
2622 val &= DP_PSR_SINK_STATE_MASK;
2623 if (val < ARRAY_SIZE(sink_status))
2624 return sink_status[val];
2625
2626 return "unknown";
2627}
2628
2551static int i915_edp_psr_status(struct seq_file *m, void *data) 2629static int i915_edp_psr_status(struct seq_file *m, void *data)
2552{ 2630{
2553 struct drm_i915_private *dev_priv = node_to_i915(m->private); 2631 struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -2569,14 +2647,13 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
2569 2647
2570 mutex_lock(&dev_priv->psr.lock); 2648 mutex_lock(&dev_priv->psr.lock);
2571 seq_printf(m, "Enabled: %s\n", yesno((bool)dev_priv->psr.enabled)); 2649 seq_printf(m, "Enabled: %s\n", yesno((bool)dev_priv->psr.enabled));
2572 seq_printf(m, "Active: %s\n", yesno(dev_priv->psr.active));
2573 seq_printf(m, "Busy frontbuffer bits: 0x%03x\n", 2650 seq_printf(m, "Busy frontbuffer bits: 0x%03x\n",
2574 dev_priv->psr.busy_frontbuffer_bits); 2651 dev_priv->psr.busy_frontbuffer_bits);
2575 seq_printf(m, "Re-enable work scheduled: %s\n", 2652 seq_printf(m, "Re-enable work scheduled: %s\n",
2576 yesno(work_busy(&dev_priv->psr.work.work))); 2653 yesno(work_busy(&dev_priv->psr.work.work)));
2577 2654
2578 if (HAS_DDI(dev_priv)) { 2655 if (HAS_DDI(dev_priv)) {
2579 if (dev_priv->psr.psr2_support) 2656 if (dev_priv->psr.psr2_enabled)
2580 enabled = I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE; 2657 enabled = I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE;
2581 else 2658 else
2582 enabled = I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE; 2659 enabled = I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE;
@@ -2624,18 +2701,67 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
2624 2701
2625 seq_printf(m, "Performance_Counter: %u\n", psrperf); 2702 seq_printf(m, "Performance_Counter: %u\n", psrperf);
2626 } 2703 }
2627 if (dev_priv->psr.psr2_support) { 2704 if (dev_priv->psr.psr2_enabled) {
2628 u32 psr2 = I915_READ(EDP_PSR2_STATUS); 2705 u32 psr2 = I915_READ(EDP_PSR2_STATUS);
2629 2706
2630 seq_printf(m, "EDP_PSR2_STATUS: %x [%s]\n", 2707 seq_printf(m, "EDP_PSR2_STATUS: %x [%s]\n",
2631 psr2, psr2_live_status(psr2)); 2708 psr2, psr2_live_status(psr2));
2632 } 2709 }
2710
2711 if (dev_priv->psr.enabled) {
2712 struct drm_dp_aux *aux = &dev_priv->psr.enabled->aux;
2713 u8 val;
2714
2715 if (drm_dp_dpcd_readb(aux, DP_PSR_STATUS, &val) == 1)
2716 seq_printf(m, "Sink PSR status: 0x%x [%s]\n", val,
2717 psr_sink_status(val));
2718 }
2633 mutex_unlock(&dev_priv->psr.lock); 2719 mutex_unlock(&dev_priv->psr.lock);
2634 2720
2721 if (READ_ONCE(dev_priv->psr.debug)) {
2722 seq_printf(m, "Last attempted entry at: %lld\n",
2723 dev_priv->psr.last_entry_attempt);
2724 seq_printf(m, "Last exit at: %lld\n",
2725 dev_priv->psr.last_exit);
2726 }
2727
2635 intel_runtime_pm_put(dev_priv); 2728 intel_runtime_pm_put(dev_priv);
2636 return 0; 2729 return 0;
2637} 2730}
2638 2731
2732static int
2733i915_edp_psr_debug_set(void *data, u64 val)
2734{
2735 struct drm_i915_private *dev_priv = data;
2736
2737 if (!CAN_PSR(dev_priv))
2738 return -ENODEV;
2739
2740 DRM_DEBUG_KMS("PSR debug %s\n", enableddisabled(val));
2741
2742 intel_runtime_pm_get(dev_priv);
2743 intel_psr_irq_control(dev_priv, !!val);
2744 intel_runtime_pm_put(dev_priv);
2745
2746 return 0;
2747}
2748
2749static int
2750i915_edp_psr_debug_get(void *data, u64 *val)
2751{
2752 struct drm_i915_private *dev_priv = data;
2753
2754 if (!CAN_PSR(dev_priv))
2755 return -ENODEV;
2756
2757 *val = READ_ONCE(dev_priv->psr.debug);
2758 return 0;
2759}
2760
2761DEFINE_SIMPLE_ATTRIBUTE(i915_edp_psr_debug_fops,
2762 i915_edp_psr_debug_get, i915_edp_psr_debug_set,
2763 "%llu\n");
2764
2639static int i915_sink_crc(struct seq_file *m, void *data) 2765static int i915_sink_crc(struct seq_file *m, void *data)
2640{ 2766{
2641 struct drm_i915_private *dev_priv = node_to_i915(m->private); 2767 struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -3231,7 +3357,8 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
3231 for (i = 0; i < dev_priv->num_shared_dpll; i++) { 3357 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
3232 struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; 3358 struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
3233 3359
3234 seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->name, pll->id); 3360 seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->info->name,
3361 pll->info->id);
3235 seq_printf(m, " crtc_mask: 0x%08x, active: 0x%x, on: %s\n", 3362 seq_printf(m, " crtc_mask: 0x%08x, active: 0x%x, on: %s\n",
3236 pll->state.crtc_mask, pll->active_mask, yesno(pll->on)); 3363 pll->state.crtc_mask, pll->active_mask, yesno(pll->on));
3237 seq_printf(m, " tracked hardware state:\n"); 3364 seq_printf(m, " tracked hardware state:\n");
@@ -3241,6 +3368,28 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
3241 seq_printf(m, " fp0: 0x%08x\n", pll->state.hw_state.fp0); 3368 seq_printf(m, " fp0: 0x%08x\n", pll->state.hw_state.fp0);
3242 seq_printf(m, " fp1: 0x%08x\n", pll->state.hw_state.fp1); 3369 seq_printf(m, " fp1: 0x%08x\n", pll->state.hw_state.fp1);
3243 seq_printf(m, " wrpll: 0x%08x\n", pll->state.hw_state.wrpll); 3370 seq_printf(m, " wrpll: 0x%08x\n", pll->state.hw_state.wrpll);
3371 seq_printf(m, " cfgcr0: 0x%08x\n", pll->state.hw_state.cfgcr0);
3372 seq_printf(m, " cfgcr1: 0x%08x\n", pll->state.hw_state.cfgcr1);
3373 seq_printf(m, " mg_refclkin_ctl: 0x%08x\n",
3374 pll->state.hw_state.mg_refclkin_ctl);
3375 seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
3376 pll->state.hw_state.mg_clktop2_coreclkctl1);
3377 seq_printf(m, " mg_clktop2_hsclkctl: 0x%08x\n",
3378 pll->state.hw_state.mg_clktop2_hsclkctl);
3379 seq_printf(m, " mg_pll_div0: 0x%08x\n",
3380 pll->state.hw_state.mg_pll_div0);
3381 seq_printf(m, " mg_pll_div1: 0x%08x\n",
3382 pll->state.hw_state.mg_pll_div1);
3383 seq_printf(m, " mg_pll_lf: 0x%08x\n",
3384 pll->state.hw_state.mg_pll_lf);
3385 seq_printf(m, " mg_pll_frac_lock: 0x%08x\n",
3386 pll->state.hw_state.mg_pll_frac_lock);
3387 seq_printf(m, " mg_pll_ssc: 0x%08x\n",
3388 pll->state.hw_state.mg_pll_ssc);
3389 seq_printf(m, " mg_pll_bias: 0x%08x\n",
3390 pll->state.hw_state.mg_pll_bias);
3391 seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
3392 pll->state.hw_state.mg_pll_tdc_coldst_bias);
3244 } 3393 }
3245 drm_modeset_unlock_all(dev); 3394 drm_modeset_unlock_all(dev);
3246 3395
@@ -3249,24 +3398,13 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
3249 3398
3250static int i915_wa_registers(struct seq_file *m, void *unused) 3399static int i915_wa_registers(struct seq_file *m, void *unused)
3251{ 3400{
3252 int i;
3253 int ret;
3254 struct intel_engine_cs *engine;
3255 struct drm_i915_private *dev_priv = node_to_i915(m->private); 3401 struct drm_i915_private *dev_priv = node_to_i915(m->private);
3256 struct drm_device *dev = &dev_priv->drm;
3257 struct i915_workarounds *workarounds = &dev_priv->workarounds; 3402 struct i915_workarounds *workarounds = &dev_priv->workarounds;
3258 enum intel_engine_id id; 3403 int i;
3259
3260 ret = mutex_lock_interruptible(&dev->struct_mutex);
3261 if (ret)
3262 return ret;
3263 3404
3264 intel_runtime_pm_get(dev_priv); 3405 intel_runtime_pm_get(dev_priv);
3265 3406
3266 seq_printf(m, "Workarounds applied: %d\n", workarounds->count); 3407 seq_printf(m, "Workarounds applied: %d\n", workarounds->count);
3267 for_each_engine(engine, dev_priv, id)
3268 seq_printf(m, "HW whitelist count for %s: %d\n",
3269 engine->name, workarounds->hw_whitelist_count[id]);
3270 for (i = 0; i < workarounds->count; ++i) { 3408 for (i = 0; i < workarounds->count; ++i) {
3271 i915_reg_t addr; 3409 i915_reg_t addr;
3272 u32 mask, value, read; 3410 u32 mask, value, read;
@@ -3282,7 +3420,6 @@ static int i915_wa_registers(struct seq_file *m, void *unused)
3282 } 3420 }
3283 3421
3284 intel_runtime_pm_put(dev_priv); 3422 intel_runtime_pm_put(dev_priv);
3285 mutex_unlock(&dev->struct_mutex);
3286 3423
3287 return 0; 3424 return 0;
3288} 3425}
@@ -3567,7 +3704,8 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
3567 3704
3568static int i915_displayport_test_active_show(struct seq_file *m, void *data) 3705static int i915_displayport_test_active_show(struct seq_file *m, void *data)
3569{ 3706{
3570 struct drm_device *dev = m->private; 3707 struct drm_i915_private *dev_priv = m->private;
3708 struct drm_device *dev = &dev_priv->drm;
3571 struct drm_connector *connector; 3709 struct drm_connector *connector;
3572 struct drm_connector_list_iter conn_iter; 3710 struct drm_connector_list_iter conn_iter;
3573 struct intel_dp *intel_dp; 3711 struct intel_dp *intel_dp;
@@ -3601,10 +3739,8 @@ static int i915_displayport_test_active_show(struct seq_file *m, void *data)
3601static int i915_displayport_test_active_open(struct inode *inode, 3739static int i915_displayport_test_active_open(struct inode *inode,
3602 struct file *file) 3740 struct file *file)
3603{ 3741{
3604 struct drm_i915_private *dev_priv = inode->i_private;
3605
3606 return single_open(file, i915_displayport_test_active_show, 3742 return single_open(file, i915_displayport_test_active_show,
3607 &dev_priv->drm); 3743 inode->i_private);
3608} 3744}
3609 3745
3610static const struct file_operations i915_displayport_test_active_fops = { 3746static const struct file_operations i915_displayport_test_active_fops = {
@@ -3618,7 +3754,8 @@ static const struct file_operations i915_displayport_test_active_fops = {
3618 3754
3619static int i915_displayport_test_data_show(struct seq_file *m, void *data) 3755static int i915_displayport_test_data_show(struct seq_file *m, void *data)
3620{ 3756{
3621 struct drm_device *dev = m->private; 3757 struct drm_i915_private *dev_priv = m->private;
3758 struct drm_device *dev = &dev_priv->drm;
3622 struct drm_connector *connector; 3759 struct drm_connector *connector;
3623 struct drm_connector_list_iter conn_iter; 3760 struct drm_connector_list_iter conn_iter;
3624 struct intel_dp *intel_dp; 3761 struct intel_dp *intel_dp;
@@ -3657,26 +3794,12 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data)
3657 3794
3658 return 0; 3795 return 0;
3659} 3796}
3660static int i915_displayport_test_data_open(struct inode *inode, 3797DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
3661 struct file *file)
3662{
3663 struct drm_i915_private *dev_priv = inode->i_private;
3664
3665 return single_open(file, i915_displayport_test_data_show,
3666 &dev_priv->drm);
3667}
3668
3669static const struct file_operations i915_displayport_test_data_fops = {
3670 .owner = THIS_MODULE,
3671 .open = i915_displayport_test_data_open,
3672 .read = seq_read,
3673 .llseek = seq_lseek,
3674 .release = single_release
3675};
3676 3798
3677static int i915_displayport_test_type_show(struct seq_file *m, void *data) 3799static int i915_displayport_test_type_show(struct seq_file *m, void *data)
3678{ 3800{
3679 struct drm_device *dev = m->private; 3801 struct drm_i915_private *dev_priv = m->private;
3802 struct drm_device *dev = &dev_priv->drm;
3680 struct drm_connector *connector; 3803 struct drm_connector *connector;
3681 struct drm_connector_list_iter conn_iter; 3804 struct drm_connector_list_iter conn_iter;
3682 struct intel_dp *intel_dp; 3805 struct intel_dp *intel_dp;
@@ -3703,23 +3826,7 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data)
3703 3826
3704 return 0; 3827 return 0;
3705} 3828}
3706 3829DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
3707static int i915_displayport_test_type_open(struct inode *inode,
3708 struct file *file)
3709{
3710 struct drm_i915_private *dev_priv = inode->i_private;
3711
3712 return single_open(file, i915_displayport_test_type_show,
3713 &dev_priv->drm);
3714}
3715
3716static const struct file_operations i915_displayport_test_type_fops = {
3717 .owner = THIS_MODULE,
3718 .open = i915_displayport_test_type_open,
3719 .read = seq_read,
3720 .llseek = seq_lseek,
3721 .release = single_release
3722};
3723 3830
3724static void wm_latency_show(struct seq_file *m, const uint16_t wm[8]) 3831static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
3725{ 3832{
@@ -3987,8 +4094,8 @@ i915_wedged_set(void *data, u64 val)
3987 engine->hangcheck.stalled = true; 4094 engine->hangcheck.stalled = true;
3988 } 4095 }
3989 4096
3990 i915_handle_error(i915, val, "Manually set wedged engine mask = %llx", 4097 i915_handle_error(i915, val, I915_ERROR_CAPTURE,
3991 val); 4098 "Manually set wedged engine mask = %llx", val);
3992 4099
3993 wait_on_bit(&i915->gpu_error.flags, 4100 wait_on_bit(&i915->gpu_error.flags,
3994 I915_RESET_HANDOFF, 4101 I915_RESET_HANDOFF,
@@ -4152,119 +4259,6 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_drop_caches_fops,
4152 "0x%08llx\n"); 4259 "0x%08llx\n");
4153 4260
4154static int 4261static int
4155i915_max_freq_get(void *data, u64 *val)
4156{
4157 struct drm_i915_private *dev_priv = data;
4158
4159 if (INTEL_GEN(dev_priv) < 6)
4160 return -ENODEV;
4161
4162 *val = intel_gpu_freq(dev_priv, dev_priv->gt_pm.rps.max_freq_softlimit);
4163 return 0;
4164}
4165
4166static int
4167i915_max_freq_set(void *data, u64 val)
4168{
4169 struct drm_i915_private *dev_priv = data;
4170 struct intel_rps *rps = &dev_priv->gt_pm.rps;
4171 u32 hw_max, hw_min;
4172 int ret;
4173
4174 if (INTEL_GEN(dev_priv) < 6)
4175 return -ENODEV;
4176
4177 DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val);
4178
4179 ret = mutex_lock_interruptible(&dev_priv->pcu_lock);
4180 if (ret)
4181 return ret;
4182
4183 /*
4184 * Turbo will still be enabled, but won't go above the set value.
4185 */
4186 val = intel_freq_opcode(dev_priv, val);
4187
4188 hw_max = rps->max_freq;
4189 hw_min = rps->min_freq;
4190
4191 if (val < hw_min || val > hw_max || val < rps->min_freq_softlimit) {
4192 mutex_unlock(&dev_priv->pcu_lock);
4193 return -EINVAL;
4194 }
4195
4196 rps->max_freq_softlimit = val;
4197
4198 if (intel_set_rps(dev_priv, val))
4199 DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n");
4200
4201 mutex_unlock(&dev_priv->pcu_lock);
4202
4203 return 0;
4204}
4205
4206DEFINE_SIMPLE_ATTRIBUTE(i915_max_freq_fops,
4207 i915_max_freq_get, i915_max_freq_set,
4208 "%llu\n");
4209
4210static int
4211i915_min_freq_get(void *data, u64 *val)
4212{
4213 struct drm_i915_private *dev_priv = data;
4214
4215 if (INTEL_GEN(dev_priv) < 6)
4216 return -ENODEV;
4217
4218 *val = intel_gpu_freq(dev_priv, dev_priv->gt_pm.rps.min_freq_softlimit);
4219 return 0;
4220}
4221
4222static int
4223i915_min_freq_set(void *data, u64 val)
4224{
4225 struct drm_i915_private *dev_priv = data;
4226 struct intel_rps *rps = &dev_priv->gt_pm.rps;
4227 u32 hw_max, hw_min;
4228 int ret;
4229
4230 if (INTEL_GEN(dev_priv) < 6)
4231 return -ENODEV;
4232
4233 DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val);
4234
4235 ret = mutex_lock_interruptible(&dev_priv->pcu_lock);
4236 if (ret)
4237 return ret;
4238
4239 /*
4240 * Turbo will still be enabled, but won't go below the set value.
4241 */
4242 val = intel_freq_opcode(dev_priv, val);
4243
4244 hw_max = rps->max_freq;
4245 hw_min = rps->min_freq;
4246
4247 if (val < hw_min ||
4248 val > hw_max || val > rps->max_freq_softlimit) {
4249 mutex_unlock(&dev_priv->pcu_lock);
4250 return -EINVAL;
4251 }
4252
4253 rps->min_freq_softlimit = val;
4254
4255 if (intel_set_rps(dev_priv, val))
4256 DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n");
4257
4258 mutex_unlock(&dev_priv->pcu_lock);
4259
4260 return 0;
4261}
4262
4263DEFINE_SIMPLE_ATTRIBUTE(i915_min_freq_fops,
4264 i915_min_freq_get, i915_min_freq_set,
4265 "%llu\n");
4266
4267static int
4268i915_cache_sharing_get(void *data, u64 *val) 4262i915_cache_sharing_get(void *data, u64 *val)
4269{ 4263{
4270 struct drm_i915_private *dev_priv = data; 4264 struct drm_i915_private *dev_priv = data;
@@ -4316,9 +4310,10 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_cache_sharing_fops,
4316static void cherryview_sseu_device_status(struct drm_i915_private *dev_priv, 4310static void cherryview_sseu_device_status(struct drm_i915_private *dev_priv,
4317 struct sseu_dev_info *sseu) 4311 struct sseu_dev_info *sseu)
4318{ 4312{
4319 int ss_max = 2; 4313#define SS_MAX 2
4314 const int ss_max = SS_MAX;
4315 u32 sig1[SS_MAX], sig2[SS_MAX];
4320 int ss; 4316 int ss;
4321 u32 sig1[ss_max], sig2[ss_max];
4322 4317
4323 sig1[0] = I915_READ(CHV_POWER_SS0_SIG1); 4318 sig1[0] = I915_READ(CHV_POWER_SS0_SIG1);
4324 sig1[1] = I915_READ(CHV_POWER_SS1_SIG1); 4319 sig1[1] = I915_READ(CHV_POWER_SS1_SIG1);
@@ -4342,15 +4337,16 @@ static void cherryview_sseu_device_status(struct drm_i915_private *dev_priv,
4342 sseu->eu_per_subslice = max_t(unsigned int, 4337 sseu->eu_per_subslice = max_t(unsigned int,
4343 sseu->eu_per_subslice, eu_cnt); 4338 sseu->eu_per_subslice, eu_cnt);
4344 } 4339 }
4340#undef SS_MAX
4345} 4341}
4346 4342
4347static void gen10_sseu_device_status(struct drm_i915_private *dev_priv, 4343static void gen10_sseu_device_status(struct drm_i915_private *dev_priv,
4348 struct sseu_dev_info *sseu) 4344 struct sseu_dev_info *sseu)
4349{ 4345{
4346#define SS_MAX 6
4350 const struct intel_device_info *info = INTEL_INFO(dev_priv); 4347 const struct intel_device_info *info = INTEL_INFO(dev_priv);
4348 u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2];
4351 int s, ss; 4349 int s, ss;
4352 u32 s_reg[info->sseu.max_slices];
4353 u32 eu_reg[2 * info->sseu.max_subslices], eu_mask[2];
4354 4350
4355 for (s = 0; s < info->sseu.max_slices; s++) { 4351 for (s = 0; s < info->sseu.max_slices; s++) {
4356 /* 4352 /*
@@ -4397,15 +4393,16 @@ static void gen10_sseu_device_status(struct drm_i915_private *dev_priv,
4397 eu_cnt); 4393 eu_cnt);
4398 } 4394 }
4399 } 4395 }
4396#undef SS_MAX
4400} 4397}
4401 4398
4402static void gen9_sseu_device_status(struct drm_i915_private *dev_priv, 4399static void gen9_sseu_device_status(struct drm_i915_private *dev_priv,
4403 struct sseu_dev_info *sseu) 4400 struct sseu_dev_info *sseu)
4404{ 4401{
4402#define SS_MAX 3
4405 const struct intel_device_info *info = INTEL_INFO(dev_priv); 4403 const struct intel_device_info *info = INTEL_INFO(dev_priv);
4404 u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2];
4406 int s, ss; 4405 int s, ss;
4407 u32 s_reg[info->sseu.max_slices];
4408 u32 eu_reg[2 * info->sseu.max_subslices], eu_mask[2];
4409 4406
4410 for (s = 0; s < info->sseu.max_slices; s++) { 4407 for (s = 0; s < info->sseu.max_slices; s++) {
4411 s_reg[s] = I915_READ(GEN9_SLICE_PGCTL_ACK(s)); 4408 s_reg[s] = I915_READ(GEN9_SLICE_PGCTL_ACK(s));
@@ -4452,6 +4449,7 @@ static void gen9_sseu_device_status(struct drm_i915_private *dev_priv,
4452 eu_cnt); 4449 eu_cnt);
4453 } 4450 }
4454 } 4451 }
4452#undef SS_MAX
4455} 4453}
4456 4454
4457static void broadwell_sseu_device_status(struct drm_i915_private *dev_priv, 4455static void broadwell_sseu_device_status(struct drm_i915_private *dev_priv,
@@ -4703,6 +4701,67 @@ static int i915_drrs_ctl_set(void *data, u64 val)
4703 4701
4704DEFINE_SIMPLE_ATTRIBUTE(i915_drrs_ctl_fops, NULL, i915_drrs_ctl_set, "%llu\n"); 4702DEFINE_SIMPLE_ATTRIBUTE(i915_drrs_ctl_fops, NULL, i915_drrs_ctl_set, "%llu\n");
4705 4703
4704static ssize_t
4705i915_fifo_underrun_reset_write(struct file *filp,
4706 const char __user *ubuf,
4707 size_t cnt, loff_t *ppos)
4708{
4709 struct drm_i915_private *dev_priv = filp->private_data;
4710 struct intel_crtc *intel_crtc;
4711 struct drm_device *dev = &dev_priv->drm;
4712 int ret;
4713 bool reset;
4714
4715 ret = kstrtobool_from_user(ubuf, cnt, &reset);
4716 if (ret)
4717 return ret;
4718
4719 if (!reset)
4720 return cnt;
4721
4722 for_each_intel_crtc(dev, intel_crtc) {
4723 struct drm_crtc_commit *commit;
4724 struct intel_crtc_state *crtc_state;
4725
4726 ret = drm_modeset_lock_single_interruptible(&intel_crtc->base.mutex);
4727 if (ret)
4728 return ret;
4729
4730 crtc_state = to_intel_crtc_state(intel_crtc->base.state);
4731 commit = crtc_state->base.commit;
4732 if (commit) {
4733 ret = wait_for_completion_interruptible(&commit->hw_done);
4734 if (!ret)
4735 ret = wait_for_completion_interruptible(&commit->flip_done);
4736 }
4737
4738 if (!ret && crtc_state->base.active) {
4739 DRM_DEBUG_KMS("Re-arming FIFO underruns on pipe %c\n",
4740 pipe_name(intel_crtc->pipe));
4741
4742 intel_crtc_arm_fifo_underrun(intel_crtc, crtc_state);
4743 }
4744
4745 drm_modeset_unlock(&intel_crtc->base.mutex);
4746
4747 if (ret)
4748 return ret;
4749 }
4750
4751 ret = intel_fbc_reset_underrun(dev_priv);
4752 if (ret)
4753 return ret;
4754
4755 return cnt;
4756}
4757
4758static const struct file_operations i915_fifo_underrun_reset_ops = {
4759 .owner = THIS_MODULE,
4760 .open = simple_open,
4761 .write = i915_fifo_underrun_reset_write,
4762 .llseek = default_llseek,
4763};
4764
4706static const struct drm_info_list i915_debugfs_list[] = { 4765static const struct drm_info_list i915_debugfs_list[] = {
4707 {"i915_capabilities", i915_capabilities, 0}, 4766 {"i915_capabilities", i915_capabilities, 0},
4708 {"i915_gem_objects", i915_gem_object_info, 0}, 4767 {"i915_gem_objects", i915_gem_object_info, 0},
@@ -4760,8 +4819,6 @@ static const struct i915_debugfs_files {
4760 const struct file_operations *fops; 4819 const struct file_operations *fops;
4761} i915_debugfs_files[] = { 4820} i915_debugfs_files[] = {
4762 {"i915_wedged", &i915_wedged_fops}, 4821 {"i915_wedged", &i915_wedged_fops},
4763 {"i915_max_freq", &i915_max_freq_fops},
4764 {"i915_min_freq", &i915_min_freq_fops},
4765 {"i915_cache_sharing", &i915_cache_sharing_fops}, 4822 {"i915_cache_sharing", &i915_cache_sharing_fops},
4766 {"i915_ring_missed_irq", &i915_ring_missed_irq_fops}, 4823 {"i915_ring_missed_irq", &i915_ring_missed_irq_fops},
4767 {"i915_ring_test_irq", &i915_ring_test_irq_fops}, 4824 {"i915_ring_test_irq", &i915_ring_test_irq_fops},
@@ -4770,6 +4827,7 @@ static const struct i915_debugfs_files {
4770 {"i915_error_state", &i915_error_state_fops}, 4827 {"i915_error_state", &i915_error_state_fops},
4771 {"i915_gpu_info", &i915_gpu_info_fops}, 4828 {"i915_gpu_info", &i915_gpu_info_fops},
4772#endif 4829#endif
4830 {"i915_fifo_underrun_reset", &i915_fifo_underrun_reset_ops},
4773 {"i915_next_seqno", &i915_next_seqno_fops}, 4831 {"i915_next_seqno", &i915_next_seqno_fops},
4774 {"i915_display_crc_ctl", &i915_display_crc_ctl_fops}, 4832 {"i915_display_crc_ctl", &i915_display_crc_ctl_fops},
4775 {"i915_pri_wm_latency", &i915_pri_wm_latency_fops}, 4833 {"i915_pri_wm_latency", &i915_pri_wm_latency_fops},
@@ -4779,10 +4837,12 @@ static const struct i915_debugfs_files {
4779 {"i915_dp_test_data", &i915_displayport_test_data_fops}, 4837 {"i915_dp_test_data", &i915_displayport_test_data_fops},
4780 {"i915_dp_test_type", &i915_displayport_test_type_fops}, 4838 {"i915_dp_test_type", &i915_displayport_test_type_fops},
4781 {"i915_dp_test_active", &i915_displayport_test_active_fops}, 4839 {"i915_dp_test_active", &i915_displayport_test_active_fops},
4782 {"i915_guc_log_control", &i915_guc_log_control_fops}, 4840 {"i915_guc_log_level", &i915_guc_log_level_fops},
4841 {"i915_guc_log_relay", &i915_guc_log_relay_fops},
4783 {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops}, 4842 {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
4784 {"i915_ipc_status", &i915_ipc_status_fops}, 4843 {"i915_ipc_status", &i915_ipc_status_fops},
4785 {"i915_drrs_ctl", &i915_drrs_ctl_fops} 4844 {"i915_drrs_ctl", &i915_drrs_ctl_fops},
4845 {"i915_edp_psr_debug", &i915_edp_psr_debug_fops}
4786}; 4846};
4787 4847
4788int i915_debugfs_register(struct drm_i915_private *dev_priv) 4848int i915_debugfs_register(struct drm_i915_private *dev_priv)
@@ -4876,19 +4936,7 @@ static int i915_dpcd_show(struct seq_file *m, void *data)
4876 4936
4877 return 0; 4937 return 0;
4878} 4938}
4879 4939DEFINE_SHOW_ATTRIBUTE(i915_dpcd);
4880static int i915_dpcd_open(struct inode *inode, struct file *file)
4881{
4882 return single_open(file, i915_dpcd_show, inode->i_private);
4883}
4884
4885static const struct file_operations i915_dpcd_fops = {
4886 .owner = THIS_MODULE,
4887 .open = i915_dpcd_open,
4888 .read = seq_read,
4889 .llseek = seq_lseek,
4890 .release = single_release,
4891};
4892 4940
4893static int i915_panel_show(struct seq_file *m, void *data) 4941static int i915_panel_show(struct seq_file *m, void *data)
4894{ 4942{
@@ -4910,19 +4958,7 @@ static int i915_panel_show(struct seq_file *m, void *data)
4910 4958
4911 return 0; 4959 return 0;
4912} 4960}
4913 4961DEFINE_SHOW_ATTRIBUTE(i915_panel);
4914static int i915_panel_open(struct inode *inode, struct file *file)
4915{
4916 return single_open(file, i915_panel_show, inode->i_private);
4917}
4918
4919static const struct file_operations i915_panel_fops = {
4920 .owner = THIS_MODULE,
4921 .open = i915_panel_open,
4922 .read = seq_read,
4923 .llseek = seq_lseek,
4924 .release = single_release,
4925};
4926 4962
4927/** 4963/**
4928 * i915_debugfs_connector_add - add i915 specific connector debugfs files 4964 * i915_debugfs_connector_add - add i915 specific connector debugfs files
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 3b4daafebdcb..9c449b8d8eab 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -101,7 +101,13 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level,
101 __builtin_return_address(0), &vaf); 101 __builtin_return_address(0), &vaf);
102 102
103 if (is_error && !shown_bug_once) { 103 if (is_error && !shown_bug_once) {
104 dev_notice(kdev, "%s", FDO_BUG_MSG); 104 /*
105 * Ask the user to file a bug report for the error, except
106 * if they may have caused the bug by fiddling with unsafe
107 * module parameters.
108 */
109 if (!test_taint(TAINT_USER))
110 dev_notice(kdev, "%s", FDO_BUG_MSG);
105 shown_bug_once = true; 111 shown_bug_once = true;
106 } 112 }
107 113
@@ -377,9 +383,9 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data,
377 value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool; 383 value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
378 break; 384 break;
379 case I915_PARAM_HUC_STATUS: 385 case I915_PARAM_HUC_STATUS:
380 intel_runtime_pm_get(dev_priv); 386 value = intel_huc_check_status(&dev_priv->huc);
381 value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED; 387 if (value < 0)
382 intel_runtime_pm_put(dev_priv); 388 return value;
383 break; 389 break;
384 case I915_PARAM_MMAP_GTT_VERSION: 390 case I915_PARAM_MMAP_GTT_VERSION:
385 /* Though we've started our numbering from 1, and so class all 391 /* Though we've started our numbering from 1, and so class all
@@ -695,11 +701,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
695 if (ret) 701 if (ret)
696 goto cleanup_irq; 702 goto cleanup_irq;
697 703
698 intel_uc_init_fw(dev_priv);
699
700 ret = i915_gem_init(dev_priv); 704 ret = i915_gem_init(dev_priv);
701 if (ret) 705 if (ret)
702 goto cleanup_uc; 706 goto cleanup_irq;
703 707
704 intel_setup_overlay(dev_priv); 708 intel_setup_overlay(dev_priv);
705 709
@@ -719,8 +723,6 @@ cleanup_gem:
719 if (i915_gem_suspend(dev_priv)) 723 if (i915_gem_suspend(dev_priv))
720 DRM_ERROR("failed to idle hardware; continuing to unload!\n"); 724 DRM_ERROR("failed to idle hardware; continuing to unload!\n");
721 i915_gem_fini(dev_priv); 725 i915_gem_fini(dev_priv);
722cleanup_uc:
723 intel_uc_fini_fw(dev_priv);
724cleanup_irq: 726cleanup_irq:
725 drm_irq_uninstall(dev); 727 drm_irq_uninstall(dev);
726 intel_teardown_gmbus(dev_priv); 728 intel_teardown_gmbus(dev_priv);
@@ -922,16 +924,21 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
922 mutex_init(&dev_priv->wm.wm_mutex); 924 mutex_init(&dev_priv->wm.wm_mutex);
923 mutex_init(&dev_priv->pps_mutex); 925 mutex_init(&dev_priv->pps_mutex);
924 926
925 intel_uc_init_early(dev_priv);
926 i915_memcpy_init_early(dev_priv); 927 i915_memcpy_init_early(dev_priv);
927 928
928 ret = i915_workqueues_init(dev_priv); 929 ret = i915_workqueues_init(dev_priv);
929 if (ret < 0) 930 if (ret < 0)
930 goto err_engines; 931 goto err_engines;
931 932
933 ret = i915_gem_init_early(dev_priv);
934 if (ret < 0)
935 goto err_workqueues;
936
932 /* This must be called before any calls to HAS_PCH_* */ 937 /* This must be called before any calls to HAS_PCH_* */
933 intel_detect_pch(dev_priv); 938 intel_detect_pch(dev_priv);
934 939
940 intel_wopcm_init_early(&dev_priv->wopcm);
941 intel_uc_init_early(dev_priv);
935 intel_pm_setup(dev_priv); 942 intel_pm_setup(dev_priv);
936 intel_init_dpio(dev_priv); 943 intel_init_dpio(dev_priv);
937 intel_power_domains_init(dev_priv); 944 intel_power_domains_init(dev_priv);
@@ -940,18 +947,13 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
940 intel_init_display_hooks(dev_priv); 947 intel_init_display_hooks(dev_priv);
941 intel_init_clock_gating_hooks(dev_priv); 948 intel_init_clock_gating_hooks(dev_priv);
942 intel_init_audio_hooks(dev_priv); 949 intel_init_audio_hooks(dev_priv);
943 ret = i915_gem_load_init(dev_priv);
944 if (ret < 0)
945 goto err_irq;
946
947 intel_display_crc_init(dev_priv); 950 intel_display_crc_init(dev_priv);
948 951
949 intel_detect_preproduction_hw(dev_priv); 952 intel_detect_preproduction_hw(dev_priv);
950 953
951 return 0; 954 return 0;
952 955
953err_irq: 956err_workqueues:
954 intel_irq_fini(dev_priv);
955 i915_workqueues_cleanup(dev_priv); 957 i915_workqueues_cleanup(dev_priv);
956err_engines: 958err_engines:
957 i915_engines_cleanup(dev_priv); 959 i915_engines_cleanup(dev_priv);
@@ -964,8 +966,9 @@ err_engines:
964 */ 966 */
965static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) 967static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
966{ 968{
967 i915_gem_load_cleanup(dev_priv);
968 intel_irq_fini(dev_priv); 969 intel_irq_fini(dev_priv);
970 intel_uc_cleanup_early(dev_priv);
971 i915_gem_cleanup_early(dev_priv);
969 i915_workqueues_cleanup(dev_priv); 972 i915_workqueues_cleanup(dev_priv);
970 i915_engines_cleanup(dev_priv); 973 i915_engines_cleanup(dev_priv);
971} 974}
@@ -1035,6 +1038,10 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
1035 1038
1036 intel_uncore_init(dev_priv); 1039 intel_uncore_init(dev_priv);
1037 1040
1041 intel_device_info_init_mmio(dev_priv);
1042
1043 intel_uncore_prune(dev_priv);
1044
1038 intel_uc_init_mmio(dev_priv); 1045 intel_uc_init_mmio(dev_priv);
1039 1046
1040 ret = intel_engines_init_mmio(dev_priv); 1047 ret = intel_engines_init_mmio(dev_priv);
@@ -1077,8 +1084,6 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv)
1077 i915_modparams.enable_ppgtt); 1084 i915_modparams.enable_ppgtt);
1078 DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915_modparams.enable_ppgtt); 1085 DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915_modparams.enable_ppgtt);
1079 1086
1080 intel_uc_sanitize_options(dev_priv);
1081
1082 intel_gvt_sanitize_options(dev_priv); 1087 intel_gvt_sanitize_options(dev_priv);
1083} 1088}
1084 1089
@@ -1244,7 +1249,6 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
1244 /* Reveal our presence to userspace */ 1249 /* Reveal our presence to userspace */
1245 if (drm_dev_register(dev, 0) == 0) { 1250 if (drm_dev_register(dev, 0) == 0) {
1246 i915_debugfs_register(dev_priv); 1251 i915_debugfs_register(dev_priv);
1247 i915_guc_log_register(dev_priv);
1248 i915_setup_sysfs(dev_priv); 1252 i915_setup_sysfs(dev_priv);
1249 1253
1250 /* Depends on sysfs having been initialized */ 1254 /* Depends on sysfs having been initialized */
@@ -1304,7 +1308,6 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv)
1304 i915_pmu_unregister(dev_priv); 1308 i915_pmu_unregister(dev_priv);
1305 1309
1306 i915_teardown_sysfs(dev_priv); 1310 i915_teardown_sysfs(dev_priv);
1307 i915_guc_log_unregister(dev_priv);
1308 drm_dev_unregister(&dev_priv->drm); 1311 drm_dev_unregister(&dev_priv->drm);
1309 1312
1310 i915_gem_shrinker_unregister(dev_priv); 1313 i915_gem_shrinker_unregister(dev_priv);
@@ -1463,7 +1466,6 @@ void i915_driver_unload(struct drm_device *dev)
1463 i915_reset_error_state(dev_priv); 1466 i915_reset_error_state(dev_priv);
1464 1467
1465 i915_gem_fini(dev_priv); 1468 i915_gem_fini(dev_priv);
1466 intel_uc_fini_fw(dev_priv);
1467 intel_fbc_cleanup_cfb(dev_priv); 1469 intel_fbc_cleanup_cfb(dev_priv);
1468 1470
1469 intel_power_domains_fini(dev_priv); 1471 intel_power_domains_fini(dev_priv);
@@ -1876,7 +1878,8 @@ static int i915_resume_switcheroo(struct drm_device *dev)
1876/** 1878/**
1877 * i915_reset - reset chip after a hang 1879 * i915_reset - reset chip after a hang
1878 * @i915: #drm_i915_private to reset 1880 * @i915: #drm_i915_private to reset
1879 * @flags: Instructions 1881 * @stalled_mask: mask of the stalled engines with the guilty requests
1882 * @reason: user error message for why we are resetting
1880 * 1883 *
1881 * Reset the chip. Useful if a hang is detected. Marks the device as wedged 1884 * Reset the chip. Useful if a hang is detected. Marks the device as wedged
1882 * on failure. 1885 * on failure.
@@ -1891,12 +1894,16 @@ static int i915_resume_switcheroo(struct drm_device *dev)
1891 * - re-init interrupt state 1894 * - re-init interrupt state
1892 * - re-init display 1895 * - re-init display
1893 */ 1896 */
1894void i915_reset(struct drm_i915_private *i915, unsigned int flags) 1897void i915_reset(struct drm_i915_private *i915,
1898 unsigned int stalled_mask,
1899 const char *reason)
1895{ 1900{
1896 struct i915_gpu_error *error = &i915->gpu_error; 1901 struct i915_gpu_error *error = &i915->gpu_error;
1897 int ret; 1902 int ret;
1898 int i; 1903 int i;
1899 1904
1905 GEM_TRACE("flags=%lx\n", error->flags);
1906
1900 might_sleep(); 1907 might_sleep();
1901 lockdep_assert_held(&i915->drm.struct_mutex); 1908 lockdep_assert_held(&i915->drm.struct_mutex);
1902 GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags)); 1909 GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags));
@@ -1908,8 +1915,8 @@ void i915_reset(struct drm_i915_private *i915, unsigned int flags)
1908 if (!i915_gem_unset_wedged(i915)) 1915 if (!i915_gem_unset_wedged(i915))
1909 goto wakeup; 1916 goto wakeup;
1910 1917
1911 if (!(flags & I915_RESET_QUIET)) 1918 if (reason)
1912 dev_notice(i915->drm.dev, "Resetting chip after gpu hang\n"); 1919 dev_notice(i915->drm.dev, "Resetting chip for %s\n", reason);
1913 error->reset_count++; 1920 error->reset_count++;
1914 1921
1915 disable_irq(i915->drm.irq); 1922 disable_irq(i915->drm.irq);
@@ -1952,7 +1959,7 @@ void i915_reset(struct drm_i915_private *i915, unsigned int flags)
1952 goto error; 1959 goto error;
1953 } 1960 }
1954 1961
1955 i915_gem_reset(i915); 1962 i915_gem_reset(i915, stalled_mask);
1956 intel_overlay_reset(i915); 1963 intel_overlay_reset(i915);
1957 1964
1958 /* 1965 /*
@@ -1998,7 +2005,6 @@ taint:
1998error: 2005error:
1999 i915_gem_set_wedged(i915); 2006 i915_gem_set_wedged(i915);
2000 i915_retire_requests(i915); 2007 i915_retire_requests(i915);
2001 intel_gpu_reset(i915, ALL_ENGINES);
2002 goto finish; 2008 goto finish;
2003} 2009}
2004 2010
@@ -2011,7 +2017,7 @@ static inline int intel_gt_reset_engine(struct drm_i915_private *dev_priv,
2011/** 2017/**
2012 * i915_reset_engine - reset GPU engine to recover from a hang 2018 * i915_reset_engine - reset GPU engine to recover from a hang
2013 * @engine: engine to reset 2019 * @engine: engine to reset
2014 * @flags: options 2020 * @msg: reason for GPU reset; or NULL for no dev_notice()
2015 * 2021 *
2016 * Reset a specific GPU engine. Useful if a hang is detected. 2022 * Reset a specific GPU engine. Useful if a hang is detected.
2017 * Returns zero on successful reset or otherwise an error code. 2023 * Returns zero on successful reset or otherwise an error code.
@@ -2021,12 +2027,13 @@ static inline int intel_gt_reset_engine(struct drm_i915_private *dev_priv,
2021 * - reset engine (which will force the engine to idle) 2027 * - reset engine (which will force the engine to idle)
2022 * - re-init/configure engine 2028 * - re-init/configure engine
2023 */ 2029 */
2024int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags) 2030int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
2025{ 2031{
2026 struct i915_gpu_error *error = &engine->i915->gpu_error; 2032 struct i915_gpu_error *error = &engine->i915->gpu_error;
2027 struct i915_request *active_request; 2033 struct i915_request *active_request;
2028 int ret; 2034 int ret;
2029 2035
2036 GEM_TRACE("%s flags=%lx\n", engine->name, error->flags);
2030 GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags)); 2037 GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
2031 2038
2032 active_request = i915_gem_reset_prepare_engine(engine); 2039 active_request = i915_gem_reset_prepare_engine(engine);
@@ -2036,10 +2043,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags)
2036 goto out; 2043 goto out;
2037 } 2044 }
2038 2045
2039 if (!(flags & I915_RESET_QUIET)) { 2046 if (msg)
2040 dev_notice(engine->i915->drm.dev, 2047 dev_notice(engine->i915->drm.dev,
2041 "Resetting %s after gpu hang\n", engine->name); 2048 "Resetting %s for %s\n", engine->name, msg);
2042 }
2043 error->reset_engine_count[engine->id]++; 2049 error->reset_engine_count[engine->id]++;
2044 2050
2045 if (!engine->i915->guc.execbuf_client) 2051 if (!engine->i915->guc.execbuf_client)
@@ -2059,7 +2065,7 @@ int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags)
2059 * active request and can drop it, adjust head to skip the offending 2065 * active request and can drop it, adjust head to skip the offending
2060 * request to resume executing remaining requests in the queue. 2066 * request to resume executing remaining requests in the queue.
2061 */ 2067 */
2062 i915_gem_reset_engine(engine, active_request); 2068 i915_gem_reset_engine(engine, active_request, true);
2063 2069
2064 /* 2070 /*
2065 * The engine and its registers (and workarounds in case of render) 2071 * The engine and its registers (and workarounds in case of render)
@@ -2468,10 +2474,13 @@ static void vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv,
2468 /* 2474 /*
2469 * RC6 transitioning can be delayed up to 2 msec (see 2475 * RC6 transitioning can be delayed up to 2 msec (see
2470 * valleyview_enable_rps), use 3 msec for safety. 2476 * valleyview_enable_rps), use 3 msec for safety.
2477 *
2478 * This can fail to turn off the rc6 if the GPU is stuck after a failed
2479 * reset and we are trying to force the machine to sleep.
2471 */ 2480 */
2472 if (vlv_wait_for_pw_status(dev_priv, mask, val)) 2481 if (vlv_wait_for_pw_status(dev_priv, mask, val))
2473 DRM_ERROR("timeout waiting for GT wells to go %s\n", 2482 DRM_DEBUG_DRIVER("timeout waiting for GT wells to go %s\n",
2474 onoff(wait_for_on)); 2483 onoff(wait_for_on));
2475} 2484}
2476 2485
2477static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv) 2486static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv)
@@ -2822,10 +2831,10 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
2822 DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW), 2831 DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW),
2823 DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id_ioctl, 0), 2832 DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id_ioctl, 0),
2824 DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW), 2833 DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW),
2825 DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), 2834 DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image_ioctl, DRM_MASTER),
2826 DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), 2835 DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER),
2827 DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), 2836 DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey_ioctl, DRM_MASTER),
2828 DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW), 2837 DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER),
2829 DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 2838 DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
2830 DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW), 2839 DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
2831 DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW), 2840 DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ce18b6cf6e68..34c125e2d90c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -64,6 +64,7 @@
64#include "intel_opregion.h" 64#include "intel_opregion.h"
65#include "intel_ringbuffer.h" 65#include "intel_ringbuffer.h"
66#include "intel_uncore.h" 66#include "intel_uncore.h"
67#include "intel_wopcm.h"
67#include "intel_uc.h" 68#include "intel_uc.h"
68 69
69#include "i915_gem.h" 70#include "i915_gem.h"
@@ -71,9 +72,10 @@
71#include "i915_gem_fence_reg.h" 72#include "i915_gem_fence_reg.h"
72#include "i915_gem_object.h" 73#include "i915_gem_object.h"
73#include "i915_gem_gtt.h" 74#include "i915_gem_gtt.h"
74#include "i915_gem_timeline.h" 75#include "i915_gpu_error.h"
75
76#include "i915_request.h" 76#include "i915_request.h"
77#include "i915_scheduler.h"
78#include "i915_timeline.h"
77#include "i915_vma.h" 79#include "i915_vma.h"
78 80
79#include "intel_gvt.h" 81#include "intel_gvt.h"
@@ -83,8 +85,8 @@
83 85
84#define DRIVER_NAME "i915" 86#define DRIVER_NAME "i915"
85#define DRIVER_DESC "Intel Graphics" 87#define DRIVER_DESC "Intel Graphics"
86#define DRIVER_DATE "20180308" 88#define DRIVER_DATE "20180514"
87#define DRIVER_TIMESTAMP 1520513379 89#define DRIVER_TIMESTAMP 1526300884
88 90
89/* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and 91/* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
90 * WARN_ON()) for hw state sanity checks to check for unexpected conditions 92 * WARN_ON()) for hw state sanity checks to check for unexpected conditions
@@ -261,6 +263,7 @@ enum hpd_pin {
261 HPD_PORT_C, 263 HPD_PORT_C,
262 HPD_PORT_D, 264 HPD_PORT_D,
263 HPD_PORT_E, 265 HPD_PORT_E,
266 HPD_PORT_F,
264 HPD_NUM_PINS 267 HPD_NUM_PINS
265}; 268};
266 269
@@ -453,172 +456,6 @@ struct intel_csr {
453 uint32_t allowed_dc_mask; 456 uint32_t allowed_dc_mask;
454}; 457};
455 458
456struct intel_display_error_state;
457
458struct i915_gpu_state {
459 struct kref ref;
460 ktime_t time;
461 ktime_t boottime;
462 ktime_t uptime;
463
464 struct drm_i915_private *i915;
465
466 char error_msg[128];
467 bool simulated;
468 bool awake;
469 bool wakelock;
470 bool suspended;
471 int iommu;
472 u32 reset_count;
473 u32 suspend_count;
474 struct intel_device_info device_info;
475 struct intel_driver_caps driver_caps;
476 struct i915_params params;
477
478 struct i915_error_uc {
479 struct intel_uc_fw guc_fw;
480 struct intel_uc_fw huc_fw;
481 struct drm_i915_error_object *guc_log;
482 } uc;
483
484 /* Generic register state */
485 u32 eir;
486 u32 pgtbl_er;
487 u32 ier;
488 u32 gtier[4], ngtier;
489 u32 ccid;
490 u32 derrmr;
491 u32 forcewake;
492 u32 error; /* gen6+ */
493 u32 err_int; /* gen7 */
494 u32 fault_data0; /* gen8, gen9 */
495 u32 fault_data1; /* gen8, gen9 */
496 u32 done_reg;
497 u32 gac_eco;
498 u32 gam_ecochk;
499 u32 gab_ctl;
500 u32 gfx_mode;
501
502 u32 nfence;
503 u64 fence[I915_MAX_NUM_FENCES];
504 struct intel_overlay_error_state *overlay;
505 struct intel_display_error_state *display;
506
507 struct drm_i915_error_engine {
508 int engine_id;
509 /* Software tracked state */
510 bool idle;
511 bool waiting;
512 int num_waiters;
513 unsigned long hangcheck_timestamp;
514 bool hangcheck_stalled;
515 enum intel_engine_hangcheck_action hangcheck_action;
516 struct i915_address_space *vm;
517 int num_requests;
518 u32 reset_count;
519
520 /* position of active request inside the ring */
521 u32 rq_head, rq_post, rq_tail;
522
523 /* our own tracking of ring head and tail */
524 u32 cpu_ring_head;
525 u32 cpu_ring_tail;
526
527 u32 last_seqno;
528
529 /* Register state */
530 u32 start;
531 u32 tail;
532 u32 head;
533 u32 ctl;
534 u32 mode;
535 u32 hws;
536 u32 ipeir;
537 u32 ipehr;
538 u32 bbstate;
539 u32 instpm;
540 u32 instps;
541 u32 seqno;
542 u64 bbaddr;
543 u64 acthd;
544 u32 fault_reg;
545 u64 faddr;
546 u32 rc_psmi; /* sleep state */
547 u32 semaphore_mboxes[I915_NUM_ENGINES - 1];
548 struct intel_instdone instdone;
549
550 struct drm_i915_error_context {
551 char comm[TASK_COMM_LEN];
552 pid_t pid;
553 u32 handle;
554 u32 hw_id;
555 int priority;
556 int ban_score;
557 int active;
558 int guilty;
559 bool bannable;
560 } context;
561
562 struct drm_i915_error_object {
563 u64 gtt_offset;
564 u64 gtt_size;
565 int page_count;
566 int unused;
567 u32 *pages[0];
568 } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
569
570 struct drm_i915_error_object **user_bo;
571 long user_bo_count;
572
573 struct drm_i915_error_object *wa_ctx;
574 struct drm_i915_error_object *default_state;
575
576 struct drm_i915_error_request {
577 long jiffies;
578 pid_t pid;
579 u32 context;
580 int priority;
581 int ban_score;
582 u32 seqno;
583 u32 head;
584 u32 tail;
585 } *requests, execlist[EXECLIST_MAX_PORTS];
586 unsigned int num_ports;
587
588 struct drm_i915_error_waiter {
589 char comm[TASK_COMM_LEN];
590 pid_t pid;
591 u32 seqno;
592 } *waiters;
593
594 struct {
595 u32 gfx_mode;
596 union {
597 u64 pdp[4];
598 u32 pp_dir_base;
599 };
600 } vm_info;
601 } engine[I915_NUM_ENGINES];
602
603 struct drm_i915_error_buffer {
604 u32 size;
605 u32 name;
606 u32 rseqno[I915_NUM_ENGINES], wseqno;
607 u64 gtt_offset;
608 u32 read_domains;
609 u32 write_domain;
610 s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
611 u32 tiling:2;
612 u32 dirty:1;
613 u32 purgeable:1;
614 u32 userptr:1;
615 s32 engine:4;
616 u32 cache_level:3;
617 } *active_bo[I915_NUM_ENGINES], *pinned_bo;
618 u32 active_bo_count[I915_NUM_ENGINES], pinned_bo_count;
619 struct i915_address_space *active_vm[I915_NUM_ENGINES];
620};
621
622enum i915_cache_level { 459enum i915_cache_level {
623 I915_CACHE_NONE = 0, 460 I915_CACHE_NONE = 0,
624 I915_CACHE_LLC, /* also used for snoopable memory on non-LLC */ 461 I915_CACHE_LLC, /* also used for snoopable memory on non-LLC */
@@ -766,12 +603,16 @@ struct i915_psr {
766 bool active; 603 bool active;
767 struct delayed_work work; 604 struct delayed_work work;
768 unsigned busy_frontbuffer_bits; 605 unsigned busy_frontbuffer_bits;
769 bool psr2_support; 606 bool sink_psr2_support;
770 bool aux_frame_sync;
771 bool link_standby; 607 bool link_standby;
772 bool y_cord_support;
773 bool colorimetry_support; 608 bool colorimetry_support;
774 bool alpm; 609 bool alpm;
610 bool has_hw_tracking;
611 bool psr2_enabled;
612 u8 sink_sync_latency;
613 bool debug;
614 ktime_t last_entry_attempt;
615 ktime_t last_exit;
775 616
776 void (*enable_source)(struct intel_dp *, 617 void (*enable_source)(struct intel_dp *,
777 const struct intel_crtc_state *); 618 const struct intel_crtc_state *);
@@ -1146,16 +987,6 @@ struct i915_gem_mm {
1146 u32 object_count; 987 u32 object_count;
1147}; 988};
1148 989
1149struct drm_i915_error_state_buf {
1150 struct drm_i915_private *i915;
1151 unsigned bytes;
1152 unsigned size;
1153 int err;
1154 u8 *buf;
1155 loff_t start;
1156 loff_t pos;
1157};
1158
1159#define I915_IDLE_ENGINES_TIMEOUT (200) /* in ms */ 990#define I915_IDLE_ENGINES_TIMEOUT (200) /* in ms */
1160 991
1161#define I915_RESET_TIMEOUT (10 * HZ) /* 10s */ 992#define I915_RESET_TIMEOUT (10 * HZ) /* 10s */
@@ -1164,102 +995,6 @@ struct drm_i915_error_state_buf {
1164#define I915_ENGINE_DEAD_TIMEOUT (4 * HZ) /* Seqno, head and subunits dead */ 995#define I915_ENGINE_DEAD_TIMEOUT (4 * HZ) /* Seqno, head and subunits dead */
1165#define I915_SEQNO_DEAD_TIMEOUT (12 * HZ) /* Seqno dead with active head */ 996#define I915_SEQNO_DEAD_TIMEOUT (12 * HZ) /* Seqno dead with active head */
1166 997
1167struct i915_gpu_error {
1168 /* For hangcheck timer */
1169#define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */
1170#define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)
1171
1172 struct delayed_work hangcheck_work;
1173
1174 /* For reset and error_state handling. */
1175 spinlock_t lock;
1176 /* Protected by the above dev->gpu_error.lock. */
1177 struct i915_gpu_state *first_error;
1178
1179 atomic_t pending_fb_pin;
1180
1181 unsigned long missed_irq_rings;
1182
1183 /**
1184 * State variable controlling the reset flow and count
1185 *
1186 * This is a counter which gets incremented when reset is triggered,
1187 *
1188 * Before the reset commences, the I915_RESET_BACKOFF bit is set
1189 * meaning that any waiters holding onto the struct_mutex should
1190 * relinquish the lock immediately in order for the reset to start.
1191 *
1192 * If reset is not completed succesfully, the I915_WEDGE bit is
1193 * set meaning that hardware is terminally sour and there is no
1194 * recovery. All waiters on the reset_queue will be woken when
1195 * that happens.
1196 *
1197 * This counter is used by the wait_seqno code to notice that reset
1198 * event happened and it needs to restart the entire ioctl (since most
1199 * likely the seqno it waited for won't ever signal anytime soon).
1200 *
1201 * This is important for lock-free wait paths, where no contended lock
1202 * naturally enforces the correct ordering between the bail-out of the
1203 * waiter and the gpu reset work code.
1204 */
1205 unsigned long reset_count;
1206
1207 /**
1208 * flags: Control various stages of the GPU reset
1209 *
1210 * #I915_RESET_BACKOFF - When we start a reset, we want to stop any
1211 * other users acquiring the struct_mutex. To do this we set the
1212 * #I915_RESET_BACKOFF bit in the error flags when we detect a reset
1213 * and then check for that bit before acquiring the struct_mutex (in
1214 * i915_mutex_lock_interruptible()?). I915_RESET_BACKOFF serves a
1215 * secondary role in preventing two concurrent global reset attempts.
1216 *
1217 * #I915_RESET_HANDOFF - To perform the actual GPU reset, we need the
1218 * struct_mutex. We try to acquire the struct_mutex in the reset worker,
1219 * but it may be held by some long running waiter (that we cannot
1220 * interrupt without causing trouble). Once we are ready to do the GPU
1221 * reset, we set the I915_RESET_HANDOFF bit and wakeup any waiters. If
1222 * they already hold the struct_mutex and want to participate they can
1223 * inspect the bit and do the reset directly, otherwise the worker
1224 * waits for the struct_mutex.
1225 *
1226 * #I915_RESET_ENGINE[num_engines] - Since the driver doesn't need to
1227 * acquire the struct_mutex to reset an engine, we need an explicit
1228 * flag to prevent two concurrent reset attempts in the same engine.
1229 * As the number of engines continues to grow, allocate the flags from
1230 * the most significant bits.
1231 *
1232 * #I915_WEDGED - If reset fails and we can no longer use the GPU,
1233 * we set the #I915_WEDGED bit. Prior to command submission, e.g.
1234 * i915_request_alloc(), this bit is checked and the sequence
1235 * aborted (with -EIO reported to userspace) if set.
1236 */
1237 unsigned long flags;
1238#define I915_RESET_BACKOFF 0
1239#define I915_RESET_HANDOFF 1
1240#define I915_RESET_MODESET 2
1241#define I915_WEDGED (BITS_PER_LONG - 1)
1242#define I915_RESET_ENGINE (I915_WEDGED - I915_NUM_ENGINES)
1243
1244 /** Number of times an engine has been reset */
1245 u32 reset_engine_count[I915_NUM_ENGINES];
1246
1247 /**
1248 * Waitqueue to signal when a hang is detected. Used to for waiters
1249 * to release the struct_mutex for the reset to procede.
1250 */
1251 wait_queue_head_t wait_queue;
1252
1253 /**
1254 * Waitqueue to signal when the reset has completed. Used by clients
1255 * that wait for dev_priv->mm.wedged to settle.
1256 */
1257 wait_queue_head_t reset_queue;
1258
1259 /* For missed irq/seqno simulation. */
1260 unsigned long test_irq_rings;
1261};
1262
1263enum modeset_restore { 998enum modeset_restore {
1264 MODESET_ON_LID_OPEN, 999 MODESET_ON_LID_OPEN,
1265 MODESET_DONE, 1000 MODESET_DONE,
@@ -1338,6 +1073,7 @@ struct intel_vbt_data {
1338 } edp; 1073 } edp;
1339 1074
1340 struct { 1075 struct {
1076 bool enable;
1341 bool full_link; 1077 bool full_link;
1342 bool require_aux_wakeup; 1078 bool require_aux_wakeup;
1343 int idle_frames; 1079 int idle_frames;
@@ -1451,11 +1187,13 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
1451} 1187}
1452 1188
1453struct skl_ddb_allocation { 1189struct skl_ddb_allocation {
1454 struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* packed/uv */ 1190 /* packed/y */
1455 struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES]; 1191 struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
1192 struct skl_ddb_entry uv_plane[I915_MAX_PIPES][I915_MAX_PLANES];
1193 u8 enabled_slices; /* GEN11 has configurable 2 slices */
1456}; 1194};
1457 1195
1458struct skl_wm_values { 1196struct skl_ddb_values {
1459 unsigned dirty_pipes; 1197 unsigned dirty_pipes;
1460 struct skl_ddb_allocation ddb; 1198 struct skl_ddb_allocation ddb;
1461}; 1199};
@@ -1470,6 +1208,7 @@ struct skl_wm_level {
1470struct skl_wm_params { 1208struct skl_wm_params {
1471 bool x_tiled, y_tiled; 1209 bool x_tiled, y_tiled;
1472 bool rc_surface; 1210 bool rc_surface;
1211 bool is_planar;
1473 uint32_t width; 1212 uint32_t width;
1474 uint8_t cpp; 1213 uint8_t cpp;
1475 uint32_t plane_pixel_rate; 1214 uint32_t plane_pixel_rate;
@@ -1564,7 +1303,6 @@ struct i915_wa_reg {
1564struct i915_workarounds { 1303struct i915_workarounds {
1565 struct i915_wa_reg reg[I915_MAX_WA_REGS]; 1304 struct i915_wa_reg reg[I915_MAX_WA_REGS];
1566 u32 count; 1305 u32 count;
1567 u32 hw_whitelist_count[I915_NUM_ENGINES];
1568}; 1306};
1569 1307
1570struct i915_virtual_gpu { 1308struct i915_virtual_gpu {
@@ -1860,6 +1598,8 @@ struct drm_i915_private {
1860 1598
1861 struct intel_gvt *gvt; 1599 struct intel_gvt *gvt;
1862 1600
1601 struct intel_wopcm wopcm;
1602
1863 struct intel_huc huc; 1603 struct intel_huc huc;
1864 struct intel_guc guc; 1604 struct intel_guc guc;
1865 1605
@@ -2152,7 +1892,7 @@ struct drm_i915_private {
2152 /* current hardware state */ 1892 /* current hardware state */
2153 union { 1893 union {
2154 struct ilk_wm_values hw; 1894 struct ilk_wm_values hw;
2155 struct skl_wm_values skl_hw; 1895 struct skl_ddb_values skl_hw;
2156 struct vlv_wm_values vlv; 1896 struct vlv_wm_values vlv;
2157 struct g4x_wm_values g4x; 1897 struct g4x_wm_values g4x;
2158 }; 1898 };
@@ -2321,8 +2061,11 @@ struct drm_i915_private {
2321 void (*cleanup_engine)(struct intel_engine_cs *engine); 2061 void (*cleanup_engine)(struct intel_engine_cs *engine);
2322 2062
2323 struct list_head timelines; 2063 struct list_head timelines;
2324 struct i915_gem_timeline global_timeline; 2064
2065 struct list_head active_rings;
2066 struct list_head closed_vma;
2325 u32 active_requests; 2067 u32 active_requests;
2068 u32 request_serial;
2326 2069
2327 /** 2070 /**
2328 * Is the GPU currently considered idle, or busy executing 2071 * Is the GPU currently considered idle, or busy executing
@@ -2392,6 +2135,11 @@ static inline struct drm_i915_private *kdev_to_i915(struct device *kdev)
2392 return to_i915(dev_get_drvdata(kdev)); 2135 return to_i915(dev_get_drvdata(kdev));
2393} 2136}
2394 2137
2138static inline struct drm_i915_private *wopcm_to_i915(struct intel_wopcm *wopcm)
2139{
2140 return container_of(wopcm, struct drm_i915_private, wopcm);
2141}
2142
2395static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc) 2143static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
2396{ 2144{
2397 return container_of(guc, struct drm_i915_private, guc); 2145 return container_of(guc, struct drm_i915_private, guc);
@@ -2411,8 +2159,10 @@ static inline struct drm_i915_private *huc_to_i915(struct intel_huc *huc)
2411 2159
2412/* Iterator over subset of engines selected by mask */ 2160/* Iterator over subset of engines selected by mask */
2413#define for_each_engine_masked(engine__, dev_priv__, mask__, tmp__) \ 2161#define for_each_engine_masked(engine__, dev_priv__, mask__, tmp__) \
2414 for (tmp__ = mask__ & INTEL_INFO(dev_priv__)->ring_mask; \ 2162 for ((tmp__) = (mask__) & INTEL_INFO(dev_priv__)->ring_mask; \
2415 tmp__ ? (engine__ = (dev_priv__)->engine[__mask_next_bit(tmp__)]), 1 : 0; ) 2163 (tmp__) ? \
2164 ((engine__) = (dev_priv__)->engine[__mask_next_bit(tmp__)]), 1 : \
2165 0;)
2416 2166
2417enum hdmi_force_audio { 2167enum hdmi_force_audio {
2418 HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */ 2168 HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */
@@ -2720,6 +2470,15 @@ intel_info(const struct drm_i915_private *dev_priv)
2720#define IS_CNL_REVID(p, since, until) \ 2470#define IS_CNL_REVID(p, since, until) \
2721 (IS_CANNONLAKE(p) && IS_REVID(p, since, until)) 2471 (IS_CANNONLAKE(p) && IS_REVID(p, since, until))
2722 2472
2473#define ICL_REVID_A0 0x0
2474#define ICL_REVID_A2 0x1
2475#define ICL_REVID_B0 0x3
2476#define ICL_REVID_B2 0x4
2477#define ICL_REVID_C0 0x5
2478
2479#define IS_ICL_REVID(p, since, until) \
2480 (IS_ICELAKE(p) && IS_REVID(p, since, until))
2481
2723/* 2482/*
2724 * The genX designation typically refers to the render engine, so render 2483 * The genX designation typically refers to the render engine, so render
2725 * capability related checks should use IS_GEN, while display and other checks 2484 * capability related checks should use IS_GEN, while display and other checks
@@ -2963,10 +2722,11 @@ extern void i915_driver_unload(struct drm_device *dev);
2963extern int intel_gpu_reset(struct drm_i915_private *dev_priv, u32 engine_mask); 2722extern int intel_gpu_reset(struct drm_i915_private *dev_priv, u32 engine_mask);
2964extern bool intel_has_gpu_reset(struct drm_i915_private *dev_priv); 2723extern bool intel_has_gpu_reset(struct drm_i915_private *dev_priv);
2965 2724
2966#define I915_RESET_QUIET BIT(0) 2725extern void i915_reset(struct drm_i915_private *i915,
2967extern void i915_reset(struct drm_i915_private *i915, unsigned int flags); 2726 unsigned int stalled_mask,
2727 const char *reason);
2968extern int i915_reset_engine(struct intel_engine_cs *engine, 2728extern int i915_reset_engine(struct intel_engine_cs *engine,
2969 unsigned int flags); 2729 const char *reason);
2970 2730
2971extern bool intel_has_reset_engine(struct drm_i915_private *dev_priv); 2731extern bool intel_has_reset_engine(struct drm_i915_private *dev_priv);
2972extern int intel_reset_guc(struct drm_i915_private *dev_priv); 2732extern int intel_reset_guc(struct drm_i915_private *dev_priv);
@@ -3014,10 +2774,12 @@ static inline void i915_queue_hangcheck(struct drm_i915_private *dev_priv)
3014 &dev_priv->gpu_error.hangcheck_work, delay); 2774 &dev_priv->gpu_error.hangcheck_work, delay);
3015} 2775}
3016 2776
3017__printf(3, 4) 2777__printf(4, 5)
3018void i915_handle_error(struct drm_i915_private *dev_priv, 2778void i915_handle_error(struct drm_i915_private *dev_priv,
3019 u32 engine_mask, 2779 u32 engine_mask,
2780 unsigned long flags,
3020 const char *fmt, ...); 2781 const char *fmt, ...);
2782#define I915_ERROR_CAPTURE BIT(0)
3021 2783
3022extern void intel_irq_init(struct drm_i915_private *dev_priv); 2784extern void intel_irq_init(struct drm_i915_private *dev_priv);
3023extern void intel_irq_fini(struct drm_i915_private *dev_priv); 2785extern void intel_irq_fini(struct drm_i915_private *dev_priv);
@@ -3132,8 +2894,8 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
3132int i915_gem_wait_ioctl(struct drm_device *dev, void *data, 2894int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
3133 struct drm_file *file_priv); 2895 struct drm_file *file_priv);
3134void i915_gem_sanitize(struct drm_i915_private *i915); 2896void i915_gem_sanitize(struct drm_i915_private *i915);
3135int i915_gem_load_init(struct drm_i915_private *dev_priv); 2897int i915_gem_init_early(struct drm_i915_private *dev_priv);
3136void i915_gem_load_cleanup(struct drm_i915_private *dev_priv); 2898void i915_gem_cleanup_early(struct drm_i915_private *dev_priv);
3137void i915_gem_load_init_fences(struct drm_i915_private *dev_priv); 2899void i915_gem_load_init_fences(struct drm_i915_private *dev_priv);
3138int i915_gem_freeze(struct drm_i915_private *dev_priv); 2900int i915_gem_freeze(struct drm_i915_private *dev_priv);
3139int i915_gem_freeze_late(struct drm_i915_private *dev_priv); 2901int i915_gem_freeze_late(struct drm_i915_private *dev_priv);
@@ -3388,13 +3150,15 @@ static inline u32 i915_reset_engine_count(struct i915_gpu_error *error,
3388struct i915_request * 3150struct i915_request *
3389i915_gem_reset_prepare_engine(struct intel_engine_cs *engine); 3151i915_gem_reset_prepare_engine(struct intel_engine_cs *engine);
3390int i915_gem_reset_prepare(struct drm_i915_private *dev_priv); 3152int i915_gem_reset_prepare(struct drm_i915_private *dev_priv);
3391void i915_gem_reset(struct drm_i915_private *dev_priv); 3153void i915_gem_reset(struct drm_i915_private *dev_priv,
3154 unsigned int stalled_mask);
3392void i915_gem_reset_finish_engine(struct intel_engine_cs *engine); 3155void i915_gem_reset_finish_engine(struct intel_engine_cs *engine);
3393void i915_gem_reset_finish(struct drm_i915_private *dev_priv); 3156void i915_gem_reset_finish(struct drm_i915_private *dev_priv);
3394void i915_gem_set_wedged(struct drm_i915_private *dev_priv); 3157void i915_gem_set_wedged(struct drm_i915_private *dev_priv);
3395bool i915_gem_unset_wedged(struct drm_i915_private *dev_priv); 3158bool i915_gem_unset_wedged(struct drm_i915_private *dev_priv);
3396void i915_gem_reset_engine(struct intel_engine_cs *engine, 3159void i915_gem_reset_engine(struct intel_engine_cs *engine,
3397 struct i915_request *request); 3160 struct i915_request *request,
3161 bool stalled);
3398 3162
3399void i915_gem_init_mmio(struct drm_i915_private *i915); 3163void i915_gem_init_mmio(struct drm_i915_private *i915);
3400int __must_check i915_gem_init(struct drm_i915_private *dev_priv); 3164int __must_check i915_gem_init(struct drm_i915_private *dev_priv);
@@ -3412,7 +3176,7 @@ int i915_gem_object_wait(struct drm_i915_gem_object *obj,
3412 struct intel_rps_client *rps); 3176 struct intel_rps_client *rps);
3413int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, 3177int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj,
3414 unsigned int flags, 3178 unsigned int flags,
3415 int priority); 3179 const struct i915_sched_attr *attr);
3416#define I915_PRIORITY_DISPLAY I915_PRIORITY_MAX 3180#define I915_PRIORITY_DISPLAY I915_PRIORITY_MAX
3417 3181
3418int __must_check 3182int __must_check
@@ -3481,16 +3245,6 @@ i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
3481 return ctx; 3245 return ctx;
3482} 3246}
3483 3247
3484static inline struct intel_timeline *
3485i915_gem_context_lookup_timeline(struct i915_gem_context *ctx,
3486 struct intel_engine_cs *engine)
3487{
3488 struct i915_address_space *vm;
3489
3490 vm = ctx->ppgtt ? &ctx->ppgtt->base : &ctx->i915->ggtt.base;
3491 return &vm->timeline.engine[engine->id];
3492}
3493
3494int i915_perf_open_ioctl(struct drm_device *dev, void *data, 3248int i915_perf_open_ioctl(struct drm_device *dev, void *data,
3495 struct drm_file *file); 3249 struct drm_file *file);
3496int i915_perf_add_config_ioctl(struct drm_device *dev, void *data, 3250int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
@@ -3589,64 +3343,6 @@ static inline int i915_debugfs_connector_add(struct drm_connector *connector)
3589static inline void intel_display_crc_init(struct drm_i915_private *dev_priv) {} 3343static inline void intel_display_crc_init(struct drm_i915_private *dev_priv) {}
3590#endif 3344#endif
3591 3345
3592/* i915_gpu_error.c */
3593#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
3594
3595__printf(2, 3)
3596void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...);
3597int i915_error_state_to_str(struct drm_i915_error_state_buf *estr,
3598 const struct i915_gpu_state *gpu);
3599int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb,
3600 struct drm_i915_private *i915,
3601 size_t count, loff_t pos);
3602static inline void i915_error_state_buf_release(
3603 struct drm_i915_error_state_buf *eb)
3604{
3605 kfree(eb->buf);
3606}
3607
3608struct i915_gpu_state *i915_capture_gpu_state(struct drm_i915_private *i915);
3609void i915_capture_error_state(struct drm_i915_private *dev_priv,
3610 u32 engine_mask,
3611 const char *error_msg);
3612
3613static inline struct i915_gpu_state *
3614i915_gpu_state_get(struct i915_gpu_state *gpu)
3615{
3616 kref_get(&gpu->ref);
3617 return gpu;
3618}
3619
3620void __i915_gpu_state_free(struct kref *kref);
3621static inline void i915_gpu_state_put(struct i915_gpu_state *gpu)
3622{
3623 if (gpu)
3624 kref_put(&gpu->ref, __i915_gpu_state_free);
3625}
3626
3627struct i915_gpu_state *i915_first_error_state(struct drm_i915_private *i915);
3628void i915_reset_error_state(struct drm_i915_private *i915);
3629
3630#else
3631
3632static inline void i915_capture_error_state(struct drm_i915_private *dev_priv,
3633 u32 engine_mask,
3634 const char *error_msg)
3635{
3636}
3637
3638static inline struct i915_gpu_state *
3639i915_first_error_state(struct drm_i915_private *i915)
3640{
3641 return NULL;
3642}
3643
3644static inline void i915_reset_error_state(struct drm_i915_private *i915)
3645{
3646}
3647
3648#endif
3649
3650const char *i915_cache_level_str(struct drm_i915_private *i915, int type); 3346const char *i915_cache_level_str(struct drm_i915_private *i915, int type);
3651 3347
3652/* i915_cmd_parser.c */ 3348/* i915_cmd_parser.c */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7b5a9d7c9593..0a2070112b66 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -35,6 +35,7 @@
35#include "intel_drv.h" 35#include "intel_drv.h"
36#include "intel_frontbuffer.h" 36#include "intel_frontbuffer.h"
37#include "intel_mocs.h" 37#include "intel_mocs.h"
38#include "intel_workarounds.h"
38#include "i915_gemfs.h" 39#include "i915_gemfs.h"
39#include <linux/dma-fence-array.h> 40#include <linux/dma-fence-array.h>
40#include <linux/kthread.h> 41#include <linux/kthread.h>
@@ -136,6 +137,102 @@ int i915_mutex_lock_interruptible(struct drm_device *dev)
136 return 0; 137 return 0;
137} 138}
138 139
140static u32 __i915_gem_park(struct drm_i915_private *i915)
141{
142 lockdep_assert_held(&i915->drm.struct_mutex);
143 GEM_BUG_ON(i915->gt.active_requests);
144 GEM_BUG_ON(!list_empty(&i915->gt.active_rings));
145
146 if (!i915->gt.awake)
147 return I915_EPOCH_INVALID;
148
149 GEM_BUG_ON(i915->gt.epoch == I915_EPOCH_INVALID);
150
151 /*
152 * Be paranoid and flush a concurrent interrupt to make sure
153 * we don't reactivate any irq tasklets after parking.
154 *
155 * FIXME: Note that even though we have waited for execlists to be idle,
156 * there may still be an in-flight interrupt even though the CSB
157 * is now empty. synchronize_irq() makes sure that a residual interrupt
158 * is completed before we continue, but it doesn't prevent the HW from
159 * raising a spurious interrupt later. To complete the shield we should
160 * coordinate disabling the CS irq with flushing the interrupts.
161 */
162 synchronize_irq(i915->drm.irq);
163
164 intel_engines_park(i915);
165 i915_timelines_park(i915);
166
167 i915_pmu_gt_parked(i915);
168 i915_vma_parked(i915);
169
170 i915->gt.awake = false;
171
172 if (INTEL_GEN(i915) >= 6)
173 gen6_rps_idle(i915);
174
175 intel_display_power_put(i915, POWER_DOMAIN_GT_IRQ);
176
177 intel_runtime_pm_put(i915);
178
179 return i915->gt.epoch;
180}
181
182void i915_gem_park(struct drm_i915_private *i915)
183{
184 lockdep_assert_held(&i915->drm.struct_mutex);
185 GEM_BUG_ON(i915->gt.active_requests);
186
187 if (!i915->gt.awake)
188 return;
189
190 /* Defer the actual call to __i915_gem_park() to prevent ping-pongs */
191 mod_delayed_work(i915->wq, &i915->gt.idle_work, msecs_to_jiffies(100));
192}
193
194void i915_gem_unpark(struct drm_i915_private *i915)
195{
196 lockdep_assert_held(&i915->drm.struct_mutex);
197 GEM_BUG_ON(!i915->gt.active_requests);
198
199 if (i915->gt.awake)
200 return;
201
202 intel_runtime_pm_get_noresume(i915);
203
204 /*
205 * It seems that the DMC likes to transition between the DC states a lot
206 * when there are no connected displays (no active power domains) during
207 * command submission.
208 *
209 * This activity has negative impact on the performance of the chip with
210 * huge latencies observed in the interrupt handler and elsewhere.
211 *
212 * Work around it by grabbing a GT IRQ power domain whilst there is any
213 * GT activity, preventing any DC state transitions.
214 */
215 intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ);
216
217 i915->gt.awake = true;
218 if (unlikely(++i915->gt.epoch == 0)) /* keep 0 as invalid */
219 i915->gt.epoch = 1;
220
221 intel_enable_gt_powersave(i915);
222 i915_update_gfx_val(i915);
223 if (INTEL_GEN(i915) >= 6)
224 gen6_rps_busy(i915);
225 i915_pmu_gt_unparked(i915);
226
227 intel_engines_unpark(i915);
228
229 i915_queue_hangcheck(i915);
230
231 queue_delayed_work(i915->wq,
232 &i915->gt.retire_work,
233 round_jiffies_up_relative(HZ));
234}
235
139int 236int
140i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, 237i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
141 struct drm_file *file) 238 struct drm_file *file)
@@ -469,7 +566,8 @@ i915_gem_object_wait_reservation(struct reservation_object *resv,
469 return timeout; 566 return timeout;
470} 567}
471 568
472static void __fence_set_priority(struct dma_fence *fence, int prio) 569static void __fence_set_priority(struct dma_fence *fence,
570 const struct i915_sched_attr *attr)
473{ 571{
474 struct i915_request *rq; 572 struct i915_request *rq;
475 struct intel_engine_cs *engine; 573 struct intel_engine_cs *engine;
@@ -480,13 +578,16 @@ static void __fence_set_priority(struct dma_fence *fence, int prio)
480 rq = to_request(fence); 578 rq = to_request(fence);
481 engine = rq->engine; 579 engine = rq->engine;
482 580
483 rcu_read_lock(); 581 local_bh_disable();
582 rcu_read_lock(); /* RCU serialisation for set-wedged protection */
484 if (engine->schedule) 583 if (engine->schedule)
485 engine->schedule(rq, prio); 584 engine->schedule(rq, attr);
486 rcu_read_unlock(); 585 rcu_read_unlock();
586 local_bh_enable(); /* kick the tasklets if queues were reprioritised */
487} 587}
488 588
489static void fence_set_priority(struct dma_fence *fence, int prio) 589static void fence_set_priority(struct dma_fence *fence,
590 const struct i915_sched_attr *attr)
490{ 591{
491 /* Recurse once into a fence-array */ 592 /* Recurse once into a fence-array */
492 if (dma_fence_is_array(fence)) { 593 if (dma_fence_is_array(fence)) {
@@ -494,16 +595,16 @@ static void fence_set_priority(struct dma_fence *fence, int prio)
494 int i; 595 int i;
495 596
496 for (i = 0; i < array->num_fences; i++) 597 for (i = 0; i < array->num_fences; i++)
497 __fence_set_priority(array->fences[i], prio); 598 __fence_set_priority(array->fences[i], attr);
498 } else { 599 } else {
499 __fence_set_priority(fence, prio); 600 __fence_set_priority(fence, attr);
500 } 601 }
501} 602}
502 603
503int 604int
504i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, 605i915_gem_object_wait_priority(struct drm_i915_gem_object *obj,
505 unsigned int flags, 606 unsigned int flags,
506 int prio) 607 const struct i915_sched_attr *attr)
507{ 608{
508 struct dma_fence *excl; 609 struct dma_fence *excl;
509 610
@@ -518,7 +619,7 @@ i915_gem_object_wait_priority(struct drm_i915_gem_object *obj,
518 return ret; 619 return ret;
519 620
520 for (i = 0; i < count; i++) { 621 for (i = 0; i < count; i++) {
521 fence_set_priority(shared[i], prio); 622 fence_set_priority(shared[i], attr);
522 dma_fence_put(shared[i]); 623 dma_fence_put(shared[i]);
523 } 624 }
524 625
@@ -528,7 +629,7 @@ i915_gem_object_wait_priority(struct drm_i915_gem_object *obj,
528 } 629 }
529 630
530 if (excl) { 631 if (excl) {
531 fence_set_priority(excl, prio); 632 fence_set_priority(excl, attr);
532 dma_fence_put(excl); 633 dma_fence_put(excl);
533 } 634 }
534 return 0; 635 return 0;
@@ -2879,8 +2980,8 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
2879 * extra delay for a recent interrupt is pointless. Hence, we do 2980 * extra delay for a recent interrupt is pointless. Hence, we do
2880 * not need an engine->irq_seqno_barrier() before the seqno reads. 2981 * not need an engine->irq_seqno_barrier() before the seqno reads.
2881 */ 2982 */
2882 spin_lock_irqsave(&engine->timeline->lock, flags); 2983 spin_lock_irqsave(&engine->timeline.lock, flags);
2883 list_for_each_entry(request, &engine->timeline->requests, link) { 2984 list_for_each_entry(request, &engine->timeline.requests, link) {
2884 if (__i915_request_completed(request, request->global_seqno)) 2985 if (__i915_request_completed(request, request->global_seqno))
2885 continue; 2986 continue;
2886 2987
@@ -2891,25 +2992,11 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
2891 active = request; 2992 active = request;
2892 break; 2993 break;
2893 } 2994 }
2894 spin_unlock_irqrestore(&engine->timeline->lock, flags); 2995 spin_unlock_irqrestore(&engine->timeline.lock, flags);
2895 2996
2896 return active; 2997 return active;
2897} 2998}
2898 2999
2899static bool engine_stalled(struct intel_engine_cs *engine)
2900{
2901 if (!engine->hangcheck.stalled)
2902 return false;
2903
2904 /* Check for possible seqno movement after hang declaration */
2905 if (engine->hangcheck.seqno != intel_engine_get_seqno(engine)) {
2906 DRM_DEBUG_DRIVER("%s pardoned\n", engine->name);
2907 return false;
2908 }
2909
2910 return true;
2911}
2912
2913/* 3000/*
2914 * Ensure irq handler finishes, and not run again. 3001 * Ensure irq handler finishes, and not run again.
2915 * Also return the active request so that we only search for it once. 3002 * Also return the active request so that we only search for it once.
@@ -2998,6 +3085,7 @@ int i915_gem_reset_prepare(struct drm_i915_private *dev_priv)
2998 } 3085 }
2999 3086
3000 i915_gem_revoke_fences(dev_priv); 3087 i915_gem_revoke_fences(dev_priv);
3088 intel_uc_sanitize(dev_priv);
3001 3089
3002 return err; 3090 return err;
3003} 3091}
@@ -3025,15 +3113,15 @@ static void engine_skip_context(struct i915_request *request)
3025{ 3113{
3026 struct intel_engine_cs *engine = request->engine; 3114 struct intel_engine_cs *engine = request->engine;
3027 struct i915_gem_context *hung_ctx = request->ctx; 3115 struct i915_gem_context *hung_ctx = request->ctx;
3028 struct intel_timeline *timeline; 3116 struct i915_timeline *timeline = request->timeline;
3029 unsigned long flags; 3117 unsigned long flags;
3030 3118
3031 timeline = i915_gem_context_lookup_timeline(hung_ctx, engine); 3119 GEM_BUG_ON(timeline == &engine->timeline);
3032 3120
3033 spin_lock_irqsave(&engine->timeline->lock, flags); 3121 spin_lock_irqsave(&engine->timeline.lock, flags);
3034 spin_lock(&timeline->lock); 3122 spin_lock_nested(&timeline->lock, SINGLE_DEPTH_NESTING);
3035 3123
3036 list_for_each_entry_continue(request, &engine->timeline->requests, link) 3124 list_for_each_entry_continue(request, &engine->timeline.requests, link)
3037 if (request->ctx == hung_ctx) 3125 if (request->ctx == hung_ctx)
3038 skip_request(request); 3126 skip_request(request);
3039 3127
@@ -3041,13 +3129,14 @@ static void engine_skip_context(struct i915_request *request)
3041 skip_request(request); 3129 skip_request(request);
3042 3130
3043 spin_unlock(&timeline->lock); 3131 spin_unlock(&timeline->lock);
3044 spin_unlock_irqrestore(&engine->timeline->lock, flags); 3132 spin_unlock_irqrestore(&engine->timeline.lock, flags);
3045} 3133}
3046 3134
3047/* Returns the request if it was guilty of the hang */ 3135/* Returns the request if it was guilty of the hang */
3048static struct i915_request * 3136static struct i915_request *
3049i915_gem_reset_request(struct intel_engine_cs *engine, 3137i915_gem_reset_request(struct intel_engine_cs *engine,
3050 struct i915_request *request) 3138 struct i915_request *request,
3139 bool stalled)
3051{ 3140{
3052 /* The guilty request will get skipped on a hung engine. 3141 /* The guilty request will get skipped on a hung engine.
3053 * 3142 *
@@ -3070,7 +3159,15 @@ i915_gem_reset_request(struct intel_engine_cs *engine,
3070 * subsequent hangs. 3159 * subsequent hangs.
3071 */ 3160 */
3072 3161
3073 if (engine_stalled(engine)) { 3162 if (i915_request_completed(request)) {
3163 GEM_TRACE("%s pardoned global=%d (fence %llx:%d), current %d\n",
3164 engine->name, request->global_seqno,
3165 request->fence.context, request->fence.seqno,
3166 intel_engine_get_seqno(engine));
3167 stalled = false;
3168 }
3169
3170 if (stalled) {
3074 i915_gem_context_mark_guilty(request->ctx); 3171 i915_gem_context_mark_guilty(request->ctx);
3075 skip_request(request); 3172 skip_request(request);
3076 3173
@@ -3089,11 +3186,11 @@ i915_gem_reset_request(struct intel_engine_cs *engine,
3089 dma_fence_set_error(&request->fence, -EAGAIN); 3186 dma_fence_set_error(&request->fence, -EAGAIN);
3090 3187
3091 /* Rewind the engine to replay the incomplete rq */ 3188 /* Rewind the engine to replay the incomplete rq */
3092 spin_lock_irq(&engine->timeline->lock); 3189 spin_lock_irq(&engine->timeline.lock);
3093 request = list_prev_entry(request, link); 3190 request = list_prev_entry(request, link);
3094 if (&request->link == &engine->timeline->requests) 3191 if (&request->link == &engine->timeline.requests)
3095 request = NULL; 3192 request = NULL;
3096 spin_unlock_irq(&engine->timeline->lock); 3193 spin_unlock_irq(&engine->timeline.lock);
3097 } 3194 }
3098 } 3195 }
3099 3196
@@ -3101,7 +3198,8 @@ i915_gem_reset_request(struct intel_engine_cs *engine,
3101} 3198}
3102 3199
3103void i915_gem_reset_engine(struct intel_engine_cs *engine, 3200void i915_gem_reset_engine(struct intel_engine_cs *engine,
3104 struct i915_request *request) 3201 struct i915_request *request,
3202 bool stalled)
3105{ 3203{
3106 /* 3204 /*
3107 * Make sure this write is visible before we re-enable the interrupt 3205 * Make sure this write is visible before we re-enable the interrupt
@@ -3111,7 +3209,7 @@ void i915_gem_reset_engine(struct intel_engine_cs *engine,
3111 smp_store_mb(engine->irq_posted, 0); 3209 smp_store_mb(engine->irq_posted, 0);
3112 3210
3113 if (request) 3211 if (request)
3114 request = i915_gem_reset_request(engine, request); 3212 request = i915_gem_reset_request(engine, request, stalled);
3115 3213
3116 if (request) { 3214 if (request) {
3117 DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n", 3215 DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n",
@@ -3122,7 +3220,8 @@ void i915_gem_reset_engine(struct intel_engine_cs *engine,
3122 engine->reset_hw(engine, request); 3220 engine->reset_hw(engine, request);
3123} 3221}
3124 3222
3125void i915_gem_reset(struct drm_i915_private *dev_priv) 3223void i915_gem_reset(struct drm_i915_private *dev_priv,
3224 unsigned int stalled_mask)
3126{ 3225{
3127 struct intel_engine_cs *engine; 3226 struct intel_engine_cs *engine;
3128 enum intel_engine_id id; 3227 enum intel_engine_id id;
@@ -3134,10 +3233,12 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)
3134 for_each_engine(engine, dev_priv, id) { 3233 for_each_engine(engine, dev_priv, id) {
3135 struct i915_gem_context *ctx; 3234 struct i915_gem_context *ctx;
3136 3235
3137 i915_gem_reset_engine(engine, engine->hangcheck.active_request); 3236 i915_gem_reset_engine(engine,
3237 engine->hangcheck.active_request,
3238 stalled_mask & ENGINE_MASK(id));
3138 ctx = fetch_and_zero(&engine->last_retired_context); 3239 ctx = fetch_and_zero(&engine->last_retired_context);
3139 if (ctx) 3240 if (ctx)
3140 engine->context_unpin(engine, ctx); 3241 intel_context_unpin(ctx, engine);
3141 3242
3142 /* 3243 /*
3143 * Ostensibily, we always want a context loaded for powersaving, 3244 * Ostensibily, we always want a context loaded for powersaving,
@@ -3160,13 +3261,6 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)
3160 } 3261 }
3161 3262
3162 i915_gem_restore_fences(dev_priv); 3263 i915_gem_restore_fences(dev_priv);
3163
3164 if (dev_priv->gt.awake) {
3165 intel_sanitize_gt_powersave(dev_priv);
3166 intel_enable_gt_powersave(dev_priv);
3167 if (INTEL_GEN(dev_priv) >= 6)
3168 gen6_rps_busy(dev_priv);
3169 }
3170} 3264}
3171 3265
3172void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) 3266void i915_gem_reset_finish_engine(struct intel_engine_cs *engine)
@@ -3192,6 +3286,9 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
3192 3286
3193static void nop_submit_request(struct i915_request *request) 3287static void nop_submit_request(struct i915_request *request)
3194{ 3288{
3289 GEM_TRACE("%s fence %llx:%d -> -EIO\n",
3290 request->engine->name,
3291 request->fence.context, request->fence.seqno);
3195 dma_fence_set_error(&request->fence, -EIO); 3292 dma_fence_set_error(&request->fence, -EIO);
3196 3293
3197 i915_request_submit(request); 3294 i915_request_submit(request);
@@ -3201,12 +3298,15 @@ static void nop_complete_submit_request(struct i915_request *request)
3201{ 3298{
3202 unsigned long flags; 3299 unsigned long flags;
3203 3300
3301 GEM_TRACE("%s fence %llx:%d -> -EIO\n",
3302 request->engine->name,
3303 request->fence.context, request->fence.seqno);
3204 dma_fence_set_error(&request->fence, -EIO); 3304 dma_fence_set_error(&request->fence, -EIO);
3205 3305
3206 spin_lock_irqsave(&request->engine->timeline->lock, flags); 3306 spin_lock_irqsave(&request->engine->timeline.lock, flags);
3207 __i915_request_submit(request); 3307 __i915_request_submit(request);
3208 intel_engine_init_global_seqno(request->engine, request->global_seqno); 3308 intel_engine_init_global_seqno(request->engine, request->global_seqno);
3209 spin_unlock_irqrestore(&request->engine->timeline->lock, flags); 3309 spin_unlock_irqrestore(&request->engine->timeline.lock, flags);
3210} 3310}
3211 3311
3212void i915_gem_set_wedged(struct drm_i915_private *i915) 3312void i915_gem_set_wedged(struct drm_i915_private *i915)
@@ -3214,7 +3314,9 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
3214 struct intel_engine_cs *engine; 3314 struct intel_engine_cs *engine;
3215 enum intel_engine_id id; 3315 enum intel_engine_id id;
3216 3316
3217 if (drm_debug & DRM_UT_DRIVER) { 3317 GEM_TRACE("start\n");
3318
3319 if (GEM_SHOW_DEBUG()) {
3218 struct drm_printer p = drm_debug_printer(__func__); 3320 struct drm_printer p = drm_debug_printer(__func__);
3219 3321
3220 for_each_engine(engine, i915, id) 3322 for_each_engine(engine, i915, id)
@@ -3237,6 +3339,9 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
3237 } 3339 }
3238 i915->caps.scheduler = 0; 3340 i915->caps.scheduler = 0;
3239 3341
3342 /* Even if the GPU reset fails, it should still stop the engines */
3343 intel_gpu_reset(i915, ALL_ENGINES);
3344
3240 /* 3345 /*
3241 * Make sure no one is running the old callback before we proceed with 3346 * Make sure no one is running the old callback before we proceed with
3242 * cancelling requests and resetting the completion tracking. Otherwise 3347 * cancelling requests and resetting the completion tracking. Otherwise
@@ -3270,27 +3375,31 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
3270 * (lockless) lookup doesn't try and wait upon the request as we 3375 * (lockless) lookup doesn't try and wait upon the request as we
3271 * reset it. 3376 * reset it.
3272 */ 3377 */
3273 spin_lock_irqsave(&engine->timeline->lock, flags); 3378 spin_lock_irqsave(&engine->timeline.lock, flags);
3274 intel_engine_init_global_seqno(engine, 3379 intel_engine_init_global_seqno(engine,
3275 intel_engine_last_submit(engine)); 3380 intel_engine_last_submit(engine));
3276 spin_unlock_irqrestore(&engine->timeline->lock, flags); 3381 spin_unlock_irqrestore(&engine->timeline.lock, flags);
3277 3382
3278 i915_gem_reset_finish_engine(engine); 3383 i915_gem_reset_finish_engine(engine);
3279 } 3384 }
3280 3385
3386 GEM_TRACE("end\n");
3387
3281 wake_up_all(&i915->gpu_error.reset_queue); 3388 wake_up_all(&i915->gpu_error.reset_queue);
3282} 3389}
3283 3390
3284bool i915_gem_unset_wedged(struct drm_i915_private *i915) 3391bool i915_gem_unset_wedged(struct drm_i915_private *i915)
3285{ 3392{
3286 struct i915_gem_timeline *tl; 3393 struct i915_timeline *tl;
3287 int i;
3288 3394
3289 lockdep_assert_held(&i915->drm.struct_mutex); 3395 lockdep_assert_held(&i915->drm.struct_mutex);
3290 if (!test_bit(I915_WEDGED, &i915->gpu_error.flags)) 3396 if (!test_bit(I915_WEDGED, &i915->gpu_error.flags))
3291 return true; 3397 return true;
3292 3398
3293 /* Before unwedging, make sure that all pending operations 3399 GEM_TRACE("start\n");
3400
3401 /*
3402 * Before unwedging, make sure that all pending operations
3294 * are flushed and errored out - we may have requests waiting upon 3403 * are flushed and errored out - we may have requests waiting upon
3295 * third party fences. We marked all inflight requests as EIO, and 3404 * third party fences. We marked all inflight requests as EIO, and
3296 * every execbuf since returned EIO, for consistency we want all 3405 * every execbuf since returned EIO, for consistency we want all
@@ -3300,31 +3409,33 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
3300 * No more can be submitted until we reset the wedged bit. 3409 * No more can be submitted until we reset the wedged bit.
3301 */ 3410 */
3302 list_for_each_entry(tl, &i915->gt.timelines, link) { 3411 list_for_each_entry(tl, &i915->gt.timelines, link) {
3303 for (i = 0; i < ARRAY_SIZE(tl->engine); i++) { 3412 struct i915_request *rq;
3304 struct i915_request *rq;
3305 3413
3306 rq = i915_gem_active_peek(&tl->engine[i].last_request, 3414 rq = i915_gem_active_peek(&tl->last_request,
3307 &i915->drm.struct_mutex); 3415 &i915->drm.struct_mutex);
3308 if (!rq) 3416 if (!rq)
3309 continue; 3417 continue;
3310 3418
3311 /* We can't use our normal waiter as we want to 3419 /*
3312 * avoid recursively trying to handle the current 3420 * We can't use our normal waiter as we want to
3313 * reset. The basic dma_fence_default_wait() installs 3421 * avoid recursively trying to handle the current
3314 * a callback for dma_fence_signal(), which is 3422 * reset. The basic dma_fence_default_wait() installs
3315 * triggered by our nop handler (indirectly, the 3423 * a callback for dma_fence_signal(), which is
3316 * callback enables the signaler thread which is 3424 * triggered by our nop handler (indirectly, the
3317 * woken by the nop_submit_request() advancing the seqno 3425 * callback enables the signaler thread which is
3318 * and when the seqno passes the fence, the signaler 3426 * woken by the nop_submit_request() advancing the seqno
3319 * then signals the fence waking us up). 3427 * and when the seqno passes the fence, the signaler
3320 */ 3428 * then signals the fence waking us up).
3321 if (dma_fence_default_wait(&rq->fence, true, 3429 */
3322 MAX_SCHEDULE_TIMEOUT) < 0) 3430 if (dma_fence_default_wait(&rq->fence, true,
3323 return false; 3431 MAX_SCHEDULE_TIMEOUT) < 0)
3324 } 3432 return false;
3325 } 3433 }
3434 i915_retire_requests(i915);
3435 GEM_BUG_ON(i915->gt.active_requests);
3326 3436
3327 /* Undo nop_submit_request. We prevent all new i915 requests from 3437 /*
3438 * Undo nop_submit_request. We prevent all new i915 requests from
3328 * being queued (by disallowing execbuf whilst wedged) so having 3439 * being queued (by disallowing execbuf whilst wedged) so having
3329 * waited for all active requests above, we know the system is idle 3440 * waited for all active requests above, we know the system is idle
3330 * and do not have to worry about a thread being inside 3441 * and do not have to worry about a thread being inside
@@ -3335,6 +3446,8 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
3335 intel_engines_reset_default_submission(i915); 3446 intel_engines_reset_default_submission(i915);
3336 i915_gem_contexts_lost(i915); 3447 i915_gem_contexts_lost(i915);
3337 3448
3449 GEM_TRACE("end\n");
3450
3338 smp_mb__before_atomic(); /* complete takeover before enabling execbuf */ 3451 smp_mb__before_atomic(); /* complete takeover before enabling execbuf */
3339 clear_bit(I915_WEDGED, &i915->gpu_error.flags); 3452 clear_bit(I915_WEDGED, &i915->gpu_error.flags);
3340 3453
@@ -3473,36 +3586,9 @@ i915_gem_idle_work_handler(struct work_struct *work)
3473 if (new_requests_since_last_retire(dev_priv)) 3586 if (new_requests_since_last_retire(dev_priv))
3474 goto out_unlock; 3587 goto out_unlock;
3475 3588
3476 /* 3589 epoch = __i915_gem_park(dev_priv);
3477 * Be paranoid and flush a concurrent interrupt to make sure
3478 * we don't reactivate any irq tasklets after parking.
3479 *
3480 * FIXME: Note that even though we have waited for execlists to be idle,
3481 * there may still be an in-flight interrupt even though the CSB
3482 * is now empty. synchronize_irq() makes sure that a residual interrupt
3483 * is completed before we continue, but it doesn't prevent the HW from
3484 * raising a spurious interrupt later. To complete the shield we should
3485 * coordinate disabling the CS irq with flushing the interrupts.
3486 */
3487 synchronize_irq(dev_priv->drm.irq);
3488
3489 intel_engines_park(dev_priv);
3490 i915_gem_timelines_park(dev_priv);
3491 3590
3492 i915_pmu_gt_parked(dev_priv);
3493
3494 GEM_BUG_ON(!dev_priv->gt.awake);
3495 dev_priv->gt.awake = false;
3496 epoch = dev_priv->gt.epoch;
3497 GEM_BUG_ON(epoch == I915_EPOCH_INVALID);
3498 rearm_hangcheck = false; 3591 rearm_hangcheck = false;
3499
3500 if (INTEL_GEN(dev_priv) >= 6)
3501 gen6_rps_idle(dev_priv);
3502
3503 intel_display_power_put(dev_priv, POWER_DOMAIN_GT_IRQ);
3504
3505 intel_runtime_pm_put(dev_priv);
3506out_unlock: 3592out_unlock:
3507 mutex_unlock(&dev_priv->drm.struct_mutex); 3593 mutex_unlock(&dev_priv->drm.struct_mutex);
3508 3594
@@ -3648,17 +3734,9 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
3648 return ret; 3734 return ret;
3649} 3735}
3650 3736
3651static int wait_for_timeline(struct i915_gem_timeline *tl, unsigned int flags) 3737static int wait_for_timeline(struct i915_timeline *tl, unsigned int flags)
3652{ 3738{
3653 int ret, i; 3739 return i915_gem_active_wait(&tl->last_request, flags);
3654
3655 for (i = 0; i < ARRAY_SIZE(tl->engine); i++) {
3656 ret = i915_gem_active_wait(&tl->engine[i].last_request, flags);
3657 if (ret)
3658 return ret;
3659 }
3660
3661 return 0;
3662} 3740}
3663 3741
3664static int wait_for_engines(struct drm_i915_private *i915) 3742static int wait_for_engines(struct drm_i915_private *i915)
@@ -3666,16 +3744,7 @@ static int wait_for_engines(struct drm_i915_private *i915)
3666 if (wait_for(intel_engines_are_idle(i915), I915_IDLE_ENGINES_TIMEOUT)) { 3744 if (wait_for(intel_engines_are_idle(i915), I915_IDLE_ENGINES_TIMEOUT)) {
3667 dev_err(i915->drm.dev, 3745 dev_err(i915->drm.dev,
3668 "Failed to idle engines, declaring wedged!\n"); 3746 "Failed to idle engines, declaring wedged!\n");
3669 if (drm_debug & DRM_UT_DRIVER) { 3747 GEM_TRACE_DUMP();
3670 struct drm_printer p = drm_debug_printer(__func__);
3671 struct intel_engine_cs *engine;
3672 enum intel_engine_id id;
3673
3674 for_each_engine(engine, i915, id)
3675 intel_engine_dump(engine, &p,
3676 "%s\n", engine->name);
3677 }
3678
3679 i915_gem_set_wedged(i915); 3748 i915_gem_set_wedged(i915);
3680 return -EIO; 3749 return -EIO;
3681 } 3750 }
@@ -3685,30 +3754,37 @@ static int wait_for_engines(struct drm_i915_private *i915)
3685 3754
3686int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags) 3755int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)
3687{ 3756{
3688 int ret;
3689
3690 /* If the device is asleep, we have no requests outstanding */ 3757 /* If the device is asleep, we have no requests outstanding */
3691 if (!READ_ONCE(i915->gt.awake)) 3758 if (!READ_ONCE(i915->gt.awake))
3692 return 0; 3759 return 0;
3693 3760
3694 if (flags & I915_WAIT_LOCKED) { 3761 if (flags & I915_WAIT_LOCKED) {
3695 struct i915_gem_timeline *tl; 3762 struct i915_timeline *tl;
3763 int err;
3696 3764
3697 lockdep_assert_held(&i915->drm.struct_mutex); 3765 lockdep_assert_held(&i915->drm.struct_mutex);
3698 3766
3699 list_for_each_entry(tl, &i915->gt.timelines, link) { 3767 list_for_each_entry(tl, &i915->gt.timelines, link) {
3700 ret = wait_for_timeline(tl, flags); 3768 err = wait_for_timeline(tl, flags);
3701 if (ret) 3769 if (err)
3702 return ret; 3770 return err;
3703 } 3771 }
3704 i915_retire_requests(i915); 3772 i915_retire_requests(i915);
3705 3773
3706 ret = wait_for_engines(i915); 3774 return wait_for_engines(i915);
3707 } else { 3775 } else {
3708 ret = wait_for_timeline(&i915->gt.global_timeline, flags); 3776 struct intel_engine_cs *engine;
3709 } 3777 enum intel_engine_id id;
3778 int err;
3710 3779
3711 return ret; 3780 for_each_engine(engine, i915, id) {
3781 err = wait_for_timeline(&engine->timeline, flags);
3782 if (err)
3783 return err;
3784 }
3785
3786 return 0;
3787 }
3712} 3788}
3713 3789
3714static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object *obj) 3790static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object *obj)
@@ -4088,9 +4164,10 @@ out:
4088} 4164}
4089 4165
4090/* 4166/*
4091 * Prepare buffer for display plane (scanout, cursors, etc). 4167 * Prepare buffer for display plane (scanout, cursors, etc). Can be called from
4092 * Can be called from an uninterruptible phase (modesetting) and allows 4168 * an uninterruptible phase (modesetting) and allows any flushes to be pipelined
4093 * any flushes to be pipelined (for pageflips). 4169 * (for pageflips). We only flush the caches while preparing the buffer for
4170 * display, the callers are responsible for frontbuffer flush.
4094 */ 4171 */
4095struct i915_vma * 4172struct i915_vma *
4096i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, 4173i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
@@ -4146,9 +4223,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
4146 4223
4147 vma->display_alignment = max_t(u64, vma->display_alignment, alignment); 4224 vma->display_alignment = max_t(u64, vma->display_alignment, alignment);
4148 4225
4149 /* Treat this as an end-of-frame, like intel_user_framebuffer_dirty() */
4150 __i915_gem_object_flush_for_display(obj); 4226 __i915_gem_object_flush_for_display(obj);
4151 intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
4152 4227
4153 /* It should now be out of any other write domains, and we can update 4228 /* It should now be out of any other write domains, and we can update
4154 * the domain values for our changes. 4229 * the domain values for our changes.
@@ -4723,7 +4798,7 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
4723 &obj->vma_list, obj_link) { 4798 &obj->vma_list, obj_link) {
4724 GEM_BUG_ON(i915_vma_is_active(vma)); 4799 GEM_BUG_ON(i915_vma_is_active(vma));
4725 vma->flags &= ~I915_VMA_PIN_MASK; 4800 vma->flags &= ~I915_VMA_PIN_MASK;
4726 i915_vma_close(vma); 4801 i915_vma_destroy(vma);
4727 } 4802 }
4728 GEM_BUG_ON(!list_empty(&obj->vma_list)); 4803 GEM_BUG_ON(!list_empty(&obj->vma_list));
4729 GEM_BUG_ON(!RB_EMPTY_ROOT(&obj->vma_tree)); 4804 GEM_BUG_ON(!RB_EMPTY_ROOT(&obj->vma_tree));
@@ -4878,7 +4953,7 @@ static void assert_kernel_context_is_current(struct drm_i915_private *i915)
4878 enum intel_engine_id id; 4953 enum intel_engine_id id;
4879 4954
4880 for_each_engine(engine, i915, id) { 4955 for_each_engine(engine, i915, id) {
4881 GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline->last_request)); 4956 GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline.last_request));
4882 GEM_BUG_ON(engine->last_retired_context != kernel_context); 4957 GEM_BUG_ON(engine->last_retired_context != kernel_context);
4883 } 4958 }
4884} 4959}
@@ -4973,6 +5048,7 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
4973 * machines is a good idea, we don't - just in case it leaves the 5048 * machines is a good idea, we don't - just in case it leaves the
4974 * machine in an unusable condition. 5049 * machine in an unusable condition.
4975 */ 5050 */
5051 intel_uc_sanitize(dev_priv);
4976 i915_gem_sanitize(dev_priv); 5052 i915_gem_sanitize(dev_priv);
4977 5053
4978 intel_runtime_pm_put(dev_priv); 5054 intel_runtime_pm_put(dev_priv);
@@ -5118,6 +5194,8 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
5118 } 5194 }
5119 } 5195 }
5120 5196
5197 intel_gt_workarounds_apply(dev_priv);
5198
5121 i915_gem_init_swizzling(dev_priv); 5199 i915_gem_init_swizzling(dev_priv);
5122 5200
5123 /* 5201 /*
@@ -5140,6 +5218,12 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
5140 goto out; 5218 goto out;
5141 } 5219 }
5142 5220
5221 ret = intel_wopcm_init_hw(&dev_priv->wopcm);
5222 if (ret) {
5223 DRM_ERROR("Enabling WOPCM failed (%d)\n", ret);
5224 goto out;
5225 }
5226
5143 /* We can't enable contexts until all firmware is loaded */ 5227 /* We can't enable contexts until all firmware is loaded */
5144 ret = intel_uc_init_hw(dev_priv); 5228 ret = intel_uc_init_hw(dev_priv);
5145 if (ret) { 5229 if (ret) {
@@ -5207,7 +5291,7 @@ static int __intel_engines_record_defaults(struct drm_i915_private *i915)
5207 for_each_engine(engine, i915, id) { 5291 for_each_engine(engine, i915, id) {
5208 struct i915_vma *state; 5292 struct i915_vma *state;
5209 5293
5210 state = ctx->engine[id].state; 5294 state = to_intel_context(ctx, engine)->state;
5211 if (!state) 5295 if (!state)
5212 continue; 5296 continue;
5213 5297
@@ -5297,6 +5381,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
5297 if (ret) 5381 if (ret)
5298 return ret; 5382 return ret;
5299 5383
5384 ret = intel_wopcm_init(&dev_priv->wopcm);
5385 if (ret)
5386 return ret;
5387
5300 ret = intel_uc_init_misc(dev_priv); 5388 ret = intel_uc_init_misc(dev_priv);
5301 if (ret) 5389 if (ret)
5302 return ret; 5390 return ret;
@@ -5478,8 +5566,7 @@ static void i915_gem_init__mm(struct drm_i915_private *i915)
5478 INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); 5566 INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
5479} 5567}
5480 5568
5481int 5569int i915_gem_init_early(struct drm_i915_private *dev_priv)
5482i915_gem_load_init(struct drm_i915_private *dev_priv)
5483{ 5570{
5484 int err = -ENOMEM; 5571 int err = -ENOMEM;
5485 5572
@@ -5512,12 +5599,9 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
5512 if (!dev_priv->priorities) 5599 if (!dev_priv->priorities)
5513 goto err_dependencies; 5600 goto err_dependencies;
5514 5601
5515 mutex_lock(&dev_priv->drm.struct_mutex);
5516 INIT_LIST_HEAD(&dev_priv->gt.timelines); 5602 INIT_LIST_HEAD(&dev_priv->gt.timelines);
5517 err = i915_gem_timeline_init__global(dev_priv); 5603 INIT_LIST_HEAD(&dev_priv->gt.active_rings);
5518 mutex_unlock(&dev_priv->drm.struct_mutex); 5604 INIT_LIST_HEAD(&dev_priv->gt.closed_vma);
5519 if (err)
5520 goto err_priorities;
5521 5605
5522 i915_gem_init__mm(dev_priv); 5606 i915_gem_init__mm(dev_priv);
5523 5607
@@ -5538,8 +5622,6 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
5538 5622
5539 return 0; 5623 return 0;
5540 5624
5541err_priorities:
5542 kmem_cache_destroy(dev_priv->priorities);
5543err_dependencies: 5625err_dependencies:
5544 kmem_cache_destroy(dev_priv->dependencies); 5626 kmem_cache_destroy(dev_priv->dependencies);
5545err_requests: 5627err_requests:
@@ -5554,17 +5636,13 @@ err_out:
5554 return err; 5636 return err;
5555} 5637}
5556 5638
5557void i915_gem_load_cleanup(struct drm_i915_private *dev_priv) 5639void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
5558{ 5640{
5559 i915_gem_drain_freed_objects(dev_priv); 5641 i915_gem_drain_freed_objects(dev_priv);
5560 GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list)); 5642 GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list));
5561 GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count)); 5643 GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count));
5562 WARN_ON(dev_priv->mm.object_count); 5644 WARN_ON(dev_priv->mm.object_count);
5563
5564 mutex_lock(&dev_priv->drm.struct_mutex);
5565 i915_gem_timeline_fini(&dev_priv->gt.global_timeline);
5566 WARN_ON(!list_empty(&dev_priv->gt.timelines)); 5645 WARN_ON(!list_empty(&dev_priv->gt.timelines));
5567 mutex_unlock(&dev_priv->drm.struct_mutex);
5568 5646
5569 kmem_cache_destroy(dev_priv->priorities); 5647 kmem_cache_destroy(dev_priv->priorities);
5570 kmem_cache_destroy(dev_priv->dependencies); 5648 kmem_cache_destroy(dev_priv->dependencies);
diff --git a/drivers/gpu/drm/i915/i915_gem.h b/drivers/gpu/drm/i915/i915_gem.h
index f54c4ff74ded..525920404ede 100644
--- a/drivers/gpu/drm/i915/i915_gem.h
+++ b/drivers/gpu/drm/i915/i915_gem.h
@@ -27,7 +27,12 @@
27 27
28#include <linux/bug.h> 28#include <linux/bug.h>
29 29
30struct drm_i915_private;
31
30#ifdef CONFIG_DRM_I915_DEBUG_GEM 32#ifdef CONFIG_DRM_I915_DEBUG_GEM
33
34#define GEM_SHOW_DEBUG() (drm_debug & DRM_UT_DRIVER)
35
31#define GEM_BUG_ON(condition) do { if (unlikely((condition))) { \ 36#define GEM_BUG_ON(condition) do { if (unlikely((condition))) { \
32 pr_err("%s:%d GEM_BUG_ON(%s)\n", \ 37 pr_err("%s:%d GEM_BUG_ON(%s)\n", \
33 __func__, __LINE__, __stringify(condition)); \ 38 __func__, __LINE__, __stringify(condition)); \
@@ -43,6 +48,9 @@
43#define GEM_DEBUG_BUG_ON(expr) GEM_BUG_ON(expr) 48#define GEM_DEBUG_BUG_ON(expr) GEM_BUG_ON(expr)
44 49
45#else 50#else
51
52#define GEM_SHOW_DEBUG() (0)
53
46#define GEM_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr) 54#define GEM_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
47#define GEM_WARN_ON(expr) (BUILD_BUG_ON_INVALID(expr), 0) 55#define GEM_WARN_ON(expr) (BUILD_BUG_ON_INVALID(expr), 0)
48 56
@@ -53,10 +61,15 @@
53 61
54#if IS_ENABLED(CONFIG_DRM_I915_TRACE_GEM) 62#if IS_ENABLED(CONFIG_DRM_I915_TRACE_GEM)
55#define GEM_TRACE(...) trace_printk(__VA_ARGS__) 63#define GEM_TRACE(...) trace_printk(__VA_ARGS__)
64#define GEM_TRACE_DUMP() ftrace_dump(DUMP_ALL)
56#else 65#else
57#define GEM_TRACE(...) do { } while (0) 66#define GEM_TRACE(...) do { } while (0)
67#define GEM_TRACE_DUMP() do { } while (0)
58#endif 68#endif
59 69
60#define I915_NUM_ENGINES 8 70#define I915_NUM_ENGINES 8
61 71
72void i915_gem_park(struct drm_i915_private *i915);
73void i915_gem_unpark(struct drm_i915_private *i915);
74
62#endif /* __I915_GEM_H__ */ 75#endif /* __I915_GEM_H__ */
diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
index d3cbe8432f48..f3890b664e3f 100644
--- a/drivers/gpu/drm/i915/i915_gem_batch_pool.c
+++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
@@ -1,29 +1,11 @@
1/* 1/*
2 * Copyright © 2014 Intel Corporation 2 * SPDX-License-Identifier: MIT
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 * 3 *
4 * Copyright © 2014-2018 Intel Corporation
23 */ 5 */
24 6
25#include "i915_drv.h"
26#include "i915_gem_batch_pool.h" 7#include "i915_gem_batch_pool.h"
8#include "i915_drv.h"
27 9
28/** 10/**
29 * DOC: batch pool 11 * DOC: batch pool
@@ -41,11 +23,11 @@
41 23
42/** 24/**
43 * i915_gem_batch_pool_init() - initialize a batch buffer pool 25 * i915_gem_batch_pool_init() - initialize a batch buffer pool
44 * @engine: the associated request submission engine
45 * @pool: the batch buffer pool 26 * @pool: the batch buffer pool
27 * @engine: the associated request submission engine
46 */ 28 */
47void i915_gem_batch_pool_init(struct intel_engine_cs *engine, 29void i915_gem_batch_pool_init(struct i915_gem_batch_pool *pool,
48 struct i915_gem_batch_pool *pool) 30 struct intel_engine_cs *engine)
49{ 31{
50 int n; 32 int n;
51 33
diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.h b/drivers/gpu/drm/i915/i915_gem_batch_pool.h
index 10d5ac4c00d3..56947daaaf65 100644
--- a/drivers/gpu/drm/i915/i915_gem_batch_pool.h
+++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.h
@@ -1,31 +1,13 @@
1/* 1/*
2 * Copyright © 2014 Intel Corporation 2 * SPDX-License-Identifier: MIT
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 * 3 *
4 * Copyright © 2014-2018 Intel Corporation
23 */ 5 */
24 6
25#ifndef I915_GEM_BATCH_POOL_H 7#ifndef I915_GEM_BATCH_POOL_H
26#define I915_GEM_BATCH_POOL_H 8#define I915_GEM_BATCH_POOL_H
27 9
28#include "i915_drv.h" 10#include <linux/types.h>
29 11
30struct intel_engine_cs; 12struct intel_engine_cs;
31 13
@@ -34,9 +16,8 @@ struct i915_gem_batch_pool {
34 struct list_head cache_list[4]; 16 struct list_head cache_list[4];
35}; 17};
36 18
37/* i915_gem_batch_pool.c */ 19void i915_gem_batch_pool_init(struct i915_gem_batch_pool *pool,
38void i915_gem_batch_pool_init(struct intel_engine_cs *engine, 20 struct intel_engine_cs *engine);
39 struct i915_gem_batch_pool *pool);
40void i915_gem_batch_pool_fini(struct i915_gem_batch_pool *pool); 21void i915_gem_batch_pool_fini(struct i915_gem_batch_pool *pool);
41struct drm_i915_gem_object* 22struct drm_i915_gem_object*
42i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, size_t size); 23i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, size_t size);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index f2cbea7cf940..33f8a4b3c981 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -90,6 +90,7 @@
90#include <drm/i915_drm.h> 90#include <drm/i915_drm.h>
91#include "i915_drv.h" 91#include "i915_drv.h"
92#include "i915_trace.h" 92#include "i915_trace.h"
93#include "intel_workarounds.h"
93 94
94#define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1 95#define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1
95 96
@@ -116,15 +117,15 @@ static void lut_close(struct i915_gem_context *ctx)
116 117
117static void i915_gem_context_free(struct i915_gem_context *ctx) 118static void i915_gem_context_free(struct i915_gem_context *ctx)
118{ 119{
119 int i; 120 unsigned int n;
120 121
121 lockdep_assert_held(&ctx->i915->drm.struct_mutex); 122 lockdep_assert_held(&ctx->i915->drm.struct_mutex);
122 GEM_BUG_ON(!i915_gem_context_is_closed(ctx)); 123 GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
123 124
124 i915_ppgtt_put(ctx->ppgtt); 125 i915_ppgtt_put(ctx->ppgtt);
125 126
126 for (i = 0; i < I915_NUM_ENGINES; i++) { 127 for (n = 0; n < ARRAY_SIZE(ctx->__engine); n++) {
127 struct intel_context *ce = &ctx->engine[i]; 128 struct intel_context *ce = &ctx->__engine[n];
128 129
129 if (!ce->state) 130 if (!ce->state)
130 continue; 131 continue;
@@ -280,7 +281,7 @@ __create_hw_context(struct drm_i915_private *dev_priv,
280 kref_init(&ctx->ref); 281 kref_init(&ctx->ref);
281 list_add_tail(&ctx->link, &dev_priv->contexts.list); 282 list_add_tail(&ctx->link, &dev_priv->contexts.list);
282 ctx->i915 = dev_priv; 283 ctx->i915 = dev_priv;
283 ctx->priority = I915_PRIORITY_NORMAL; 284 ctx->sched.priority = I915_PRIORITY_NORMAL;
284 285
285 INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL); 286 INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
286 INIT_LIST_HEAD(&ctx->handles_list); 287 INIT_LIST_HEAD(&ctx->handles_list);
@@ -318,12 +319,13 @@ __create_hw_context(struct drm_i915_private *dev_priv,
318 ctx->desc_template = 319 ctx->desc_template =
319 default_desc_template(dev_priv, dev_priv->mm.aliasing_ppgtt); 320 default_desc_template(dev_priv, dev_priv->mm.aliasing_ppgtt);
320 321
321 /* GuC requires the ring to be placed above GUC_WOPCM_TOP. If GuC is not 322 /*
323 * GuC requires the ring to be placed in Non-WOPCM memory. If GuC is not
322 * present or not in use we still need a small bias as ring wraparound 324 * present or not in use we still need a small bias as ring wraparound
323 * at offset 0 sometimes hangs. No idea why. 325 * at offset 0 sometimes hangs. No idea why.
324 */ 326 */
325 if (USES_GUC(dev_priv)) 327 if (USES_GUC(dev_priv))
326 ctx->ggtt_offset_bias = GUC_WOPCM_TOP; 328 ctx->ggtt_offset_bias = dev_priv->guc.ggtt_pin_bias;
327 else 329 else
328 ctx->ggtt_offset_bias = I915_GTT_PAGE_SIZE; 330 ctx->ggtt_offset_bias = I915_GTT_PAGE_SIZE;
329 331
@@ -429,7 +431,7 @@ i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio)
429 return ctx; 431 return ctx;
430 432
431 i915_gem_context_clear_bannable(ctx); 433 i915_gem_context_clear_bannable(ctx);
432 ctx->priority = prio; 434 ctx->sched.priority = prio;
433 ctx->ring_size = PAGE_SIZE; 435 ctx->ring_size = PAGE_SIZE;
434 436
435 GEM_BUG_ON(!i915_gem_context_is_kernel(ctx)); 437 GEM_BUG_ON(!i915_gem_context_is_kernel(ctx));
@@ -458,11 +460,16 @@ static bool needs_preempt_context(struct drm_i915_private *i915)
458int i915_gem_contexts_init(struct drm_i915_private *dev_priv) 460int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
459{ 461{
460 struct i915_gem_context *ctx; 462 struct i915_gem_context *ctx;
463 int ret;
461 464
462 /* Reassure ourselves we are only called once */ 465 /* Reassure ourselves we are only called once */
463 GEM_BUG_ON(dev_priv->kernel_context); 466 GEM_BUG_ON(dev_priv->kernel_context);
464 GEM_BUG_ON(dev_priv->preempt_context); 467 GEM_BUG_ON(dev_priv->preempt_context);
465 468
469 ret = intel_ctx_workarounds_init(dev_priv);
470 if (ret)
471 return ret;
472
466 INIT_LIST_HEAD(&dev_priv->contexts.list); 473 INIT_LIST_HEAD(&dev_priv->contexts.list);
467 INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker); 474 INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker);
468 init_llist_head(&dev_priv->contexts.free_list); 475 init_llist_head(&dev_priv->contexts.free_list);
@@ -514,7 +521,7 @@ void i915_gem_contexts_lost(struct drm_i915_private *dev_priv)
514 if (!engine->last_retired_context) 521 if (!engine->last_retired_context)
515 continue; 522 continue;
516 523
517 engine->context_unpin(engine, engine->last_retired_context); 524 intel_context_unpin(engine->last_retired_context, engine);
518 engine->last_retired_context = NULL; 525 engine->last_retired_context = NULL;
519 } 526 }
520} 527}
@@ -570,19 +577,29 @@ void i915_gem_context_close(struct drm_file *file)
570 idr_destroy(&file_priv->context_idr); 577 idr_destroy(&file_priv->context_idr);
571} 578}
572 579
573static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine) 580static struct i915_request *
581last_request_on_engine(struct i915_timeline *timeline,
582 struct intel_engine_cs *engine)
574{ 583{
575 struct i915_gem_timeline *timeline; 584 struct i915_request *rq;
576 585
577 list_for_each_entry(timeline, &engine->i915->gt.timelines, link) { 586 if (timeline == &engine->timeline)
578 struct intel_timeline *tl; 587 return NULL;
579 588
580 if (timeline == &engine->i915->gt.global_timeline) 589 rq = i915_gem_active_raw(&timeline->last_request,
581 continue; 590 &engine->i915->drm.struct_mutex);
591 if (rq && rq->engine == engine)
592 return rq;
593
594 return NULL;
595}
582 596
583 tl = &timeline->engine[engine->id]; 597static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
584 if (i915_gem_active_peek(&tl->last_request, 598{
585 &engine->i915->drm.struct_mutex)) 599 struct i915_timeline *timeline;
600
601 list_for_each_entry(timeline, &engine->i915->gt.timelines, link) {
602 if (last_request_on_engine(timeline, engine))
586 return false; 603 return false;
587 } 604 }
588 605
@@ -592,7 +609,7 @@ static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
592int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv) 609int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
593{ 610{
594 struct intel_engine_cs *engine; 611 struct intel_engine_cs *engine;
595 struct i915_gem_timeline *timeline; 612 struct i915_timeline *timeline;
596 enum intel_engine_id id; 613 enum intel_engine_id id;
597 614
598 lockdep_assert_held(&dev_priv->drm.struct_mutex); 615 lockdep_assert_held(&dev_priv->drm.struct_mutex);
@@ -612,11 +629,8 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
612 /* Queue this switch after all other activity */ 629 /* Queue this switch after all other activity */
613 list_for_each_entry(timeline, &dev_priv->gt.timelines, link) { 630 list_for_each_entry(timeline, &dev_priv->gt.timelines, link) {
614 struct i915_request *prev; 631 struct i915_request *prev;
615 struct intel_timeline *tl;
616 632
617 tl = &timeline->engine[engine->id]; 633 prev = last_request_on_engine(timeline, engine);
618 prev = i915_gem_active_raw(&tl->last_request,
619 &dev_priv->drm.struct_mutex);
620 if (prev) 634 if (prev)
621 i915_sw_fence_await_sw_fence_gfp(&rq->submit, 635 i915_sw_fence_await_sw_fence_gfp(&rq->submit,
622 &prev->submit, 636 &prev->submit,
@@ -746,7 +760,7 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
746 args->value = i915_gem_context_is_bannable(ctx); 760 args->value = i915_gem_context_is_bannable(ctx);
747 break; 761 break;
748 case I915_CONTEXT_PARAM_PRIORITY: 762 case I915_CONTEXT_PARAM_PRIORITY:
749 args->value = ctx->priority; 763 args->value = ctx->sched.priority;
750 break; 764 break;
751 default: 765 default:
752 ret = -EINVAL; 766 ret = -EINVAL;
@@ -819,7 +833,7 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
819 !capable(CAP_SYS_NICE)) 833 !capable(CAP_SYS_NICE))
820 ret = -EPERM; 834 ret = -EPERM;
821 else 835 else
822 ctx->priority = priority; 836 ctx->sched.priority = priority;
823 } 837 }
824 break; 838 break;
825 839
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 7854262ddfd9..ace3b129c189 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -137,18 +137,7 @@ struct i915_gem_context {
137 */ 137 */
138 u32 user_handle; 138 u32 user_handle;
139 139
140 /** 140 struct i915_sched_attr sched;
141 * @priority: execution and service priority
142 *
143 * All clients are equal, but some are more equal than others!
144 *
145 * Requests from a context with a greater (more positive) value of
146 * @priority will be executed before those with a lower @priority
147 * value, forming a simple QoS.
148 *
149 * The &drm_i915_private.kernel_context is assigned the lowest priority.
150 */
151 int priority;
152 141
153 /** ggtt_offset_bias: placement restriction for context objects */ 142 /** ggtt_offset_bias: placement restriction for context objects */
154 u32 ggtt_offset_bias; 143 u32 ggtt_offset_bias;
@@ -160,7 +149,7 @@ struct i915_gem_context {
160 u32 *lrc_reg_state; 149 u32 *lrc_reg_state;
161 u64 lrc_desc; 150 u64 lrc_desc;
162 int pin_count; 151 int pin_count;
163 } engine[I915_NUM_ENGINES]; 152 } __engine[I915_NUM_ENGINES];
164 153
165 /** ring_size: size for allocating the per-engine ring buffer */ 154 /** ring_size: size for allocating the per-engine ring buffer */
166 u32 ring_size; 155 u32 ring_size;
@@ -267,6 +256,34 @@ static inline bool i915_gem_context_is_kernel(struct i915_gem_context *ctx)
267 return !ctx->file_priv; 256 return !ctx->file_priv;
268} 257}
269 258
259static inline struct intel_context *
260to_intel_context(struct i915_gem_context *ctx,
261 const struct intel_engine_cs *engine)
262{
263 return &ctx->__engine[engine->id];
264}
265
266static inline struct intel_ring *
267intel_context_pin(struct i915_gem_context *ctx, struct intel_engine_cs *engine)
268{
269 return engine->context_pin(engine, ctx);
270}
271
272static inline void __intel_context_pin(struct i915_gem_context *ctx,
273 const struct intel_engine_cs *engine)
274{
275 struct intel_context *ce = to_intel_context(ctx, engine);
276
277 GEM_BUG_ON(!ce->pin_count);
278 ce->pin_count++;
279}
280
281static inline void intel_context_unpin(struct i915_gem_context *ctx,
282 struct intel_engine_cs *engine)
283{
284 engine->context_unpin(engine, ctx);
285}
286
270/* i915_gem_context.c */ 287/* i915_gem_context.c */
271int __must_check i915_gem_contexts_init(struct drm_i915_private *dev_priv); 288int __must_check i915_gem_contexts_init(struct drm_i915_private *dev_priv);
272void i915_gem_contexts_lost(struct drm_i915_private *dev_priv); 289void i915_gem_contexts_lost(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 0414228cd2b5..f627a8c47c58 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -81,6 +81,35 @@ enum {
81 * but this remains just a hint as the kernel may choose a new location for 81 * but this remains just a hint as the kernel may choose a new location for
82 * any object in the future. 82 * any object in the future.
83 * 83 *
84 * At the level of talking to the hardware, submitting a batchbuffer for the
85 * GPU to execute is to add content to a buffer from which the HW
86 * command streamer is reading.
87 *
88 * 1. Add a command to load the HW context. For Logical Ring Contexts, i.e.
89 * Execlists, this command is not placed on the same buffer as the
90 * remaining items.
91 *
92 * 2. Add a command to invalidate caches to the buffer.
93 *
94 * 3. Add a batchbuffer start command to the buffer; the start command is
95 * essentially a token together with the GPU address of the batchbuffer
96 * to be executed.
97 *
98 * 4. Add a pipeline flush to the buffer.
99 *
100 * 5. Add a memory write command to the buffer to record when the GPU
101 * is done executing the batchbuffer. The memory write writes the
102 * global sequence number of the request, ``i915_request::global_seqno``;
103 * the i915 driver uses the current value in the register to determine
104 * if the GPU has completed the batchbuffer.
105 *
106 * 6. Add a user interrupt command to the buffer. This command instructs
107 * the GPU to issue an interrupt when the command, pipeline flush and
108 * memory write are completed.
109 *
110 * 7. Inform the hardware of the additional commands added to the buffer
111 * (by updating the tail pointer).
112 *
84 * Processing an execbuf ioctl is conceptually split up into a few phases. 113 * Processing an execbuf ioctl is conceptually split up into a few phases.
85 * 114 *
86 * 1. Validation - Ensure all the pointers, handles and flags are valid. 115 * 1. Validation - Ensure all the pointers, handles and flags are valid.
@@ -733,7 +762,8 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
733 } 762 }
734 763
735 /* transfer ref to ctx */ 764 /* transfer ref to ctx */
736 vma->open_count++; 765 if (!vma->open_count++)
766 i915_vma_reopen(vma);
737 list_add(&lut->obj_link, &obj->lut_list); 767 list_add(&lut->obj_link, &obj->lut_list);
738 list_add(&lut->ctx_link, &eb->ctx->handles_list); 768 list_add(&lut->ctx_link, &eb->ctx->handles_list);
739 lut->ctx = eb->ctx; 769 lut->ctx = eb->ctx;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 21d72f695adb..996ab2ad6c45 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -110,7 +110,8 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma);
110 110
111static void gen6_ggtt_invalidate(struct drm_i915_private *dev_priv) 111static void gen6_ggtt_invalidate(struct drm_i915_private *dev_priv)
112{ 112{
113 /* Note that as an uncached mmio write, this should flush the 113 /*
114 * Note that as an uncached mmio write, this will flush the
114 * WCB of the writes into the GGTT before it triggers the invalidate. 115 * WCB of the writes into the GGTT before it triggers the invalidate.
115 */ 116 */
116 I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); 117 I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
@@ -1161,6 +1162,27 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
1161 vaddr[idx.pde] |= GEN8_PDE_IPS_64K; 1162 vaddr[idx.pde] |= GEN8_PDE_IPS_64K;
1162 kunmap_atomic(vaddr); 1163 kunmap_atomic(vaddr);
1163 page_size = I915_GTT_PAGE_SIZE_64K; 1164 page_size = I915_GTT_PAGE_SIZE_64K;
1165
1166 /*
1167 * We write all 4K page entries, even when using 64K
1168 * pages. In order to verify that the HW isn't cheating
1169 * by using the 4K PTE instead of the 64K PTE, we want
1170 * to remove all the surplus entries. If the HW skipped
1171 * the 64K PTE, it will read/write into the scratch page
1172 * instead - which we detect as missing results during
1173 * selftests.
1174 */
1175 if (I915_SELFTEST_ONLY(vma->vm->scrub_64K)) {
1176 u16 i;
1177
1178 encode = pte_encode | vma->vm->scratch_page.daddr;
1179 vaddr = kmap_atomic_px(pd->page_table[idx.pde]);
1180
1181 for (i = 1; i < index; i += 16)
1182 memset64(vaddr + i, encode, 15);
1183
1184 kunmap_atomic(vaddr);
1185 }
1164 } 1186 }
1165 1187
1166 vma->page_sizes.gtt |= page_size; 1188 vma->page_sizes.gtt |= page_size;
@@ -2111,8 +2133,6 @@ static void i915_address_space_init(struct i915_address_space *vm,
2111 struct drm_i915_private *dev_priv, 2133 struct drm_i915_private *dev_priv,
2112 const char *name) 2134 const char *name)
2113{ 2135{
2114 i915_gem_timeline_init(dev_priv, &vm->timeline, name);
2115
2116 drm_mm_init(&vm->mm, 0, vm->total); 2136 drm_mm_init(&vm->mm, 0, vm->total);
2117 vm->mm.head_node.color = I915_COLOR_UNEVICTABLE; 2137 vm->mm.head_node.color = I915_COLOR_UNEVICTABLE;
2118 2138
@@ -2129,7 +2149,6 @@ static void i915_address_space_fini(struct i915_address_space *vm)
2129 if (pagevec_count(&vm->free_pages)) 2149 if (pagevec_count(&vm->free_pages))
2130 vm_free_pages_release(vm, true); 2150 vm_free_pages_release(vm, true);
2131 2151
2132 i915_gem_timeline_fini(&vm->timeline);
2133 drm_mm_takedown(&vm->mm); 2152 drm_mm_takedown(&vm->mm);
2134 list_del(&vm->global_link); 2153 list_del(&vm->global_link);
2135} 2154}
@@ -2140,15 +2159,15 @@ static void gtt_write_workarounds(struct drm_i915_private *dev_priv)
2140 * called on driver load and after a GPU reset, so you can place 2159 * called on driver load and after a GPU reset, so you can place
2141 * workarounds here even if they get overwritten by GPU reset. 2160 * workarounds here even if they get overwritten by GPU reset.
2142 */ 2161 */
2143 /* WaIncreaseDefaultTLBEntries:chv,bdw,skl,bxt,kbl,glk,cfl,cnl */ 2162 /* WaIncreaseDefaultTLBEntries:chv,bdw,skl,bxt,kbl,glk,cfl,cnl,icl */
2144 if (IS_BROADWELL(dev_priv)) 2163 if (IS_BROADWELL(dev_priv))
2145 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW); 2164 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW);
2146 else if (IS_CHERRYVIEW(dev_priv)) 2165 else if (IS_CHERRYVIEW(dev_priv))
2147 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_CHV); 2166 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_CHV);
2148 else if (IS_GEN9_BC(dev_priv) || IS_GEN10(dev_priv))
2149 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL);
2150 else if (IS_GEN9_LP(dev_priv)) 2167 else if (IS_GEN9_LP(dev_priv))
2151 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT); 2168 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT);
2169 else if (INTEL_GEN(dev_priv) >= 9)
2170 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL);
2152 2171
2153 /* 2172 /*
2154 * To support 64K PTEs we need to first enable the use of the 2173 * To support 64K PTEs we need to first enable the use of the
@@ -2222,6 +2241,12 @@ i915_ppgtt_create(struct drm_i915_private *dev_priv,
2222 2241
2223void i915_ppgtt_close(struct i915_address_space *vm) 2242void i915_ppgtt_close(struct i915_address_space *vm)
2224{ 2243{
2244 GEM_BUG_ON(vm->closed);
2245 vm->closed = true;
2246}
2247
2248static void ppgtt_destroy_vma(struct i915_address_space *vm)
2249{
2225 struct list_head *phases[] = { 2250 struct list_head *phases[] = {
2226 &vm->active_list, 2251 &vm->active_list,
2227 &vm->inactive_list, 2252 &vm->inactive_list,
@@ -2229,15 +2254,12 @@ void i915_ppgtt_close(struct i915_address_space *vm)
2229 NULL, 2254 NULL,
2230 }, **phase; 2255 }, **phase;
2231 2256
2232 GEM_BUG_ON(vm->closed);
2233 vm->closed = true; 2257 vm->closed = true;
2234
2235 for (phase = phases; *phase; phase++) { 2258 for (phase = phases; *phase; phase++) {
2236 struct i915_vma *vma, *vn; 2259 struct i915_vma *vma, *vn;
2237 2260
2238 list_for_each_entry_safe(vma, vn, *phase, vm_link) 2261 list_for_each_entry_safe(vma, vn, *phase, vm_link)
2239 if (!i915_vma_is_closed(vma)) 2262 i915_vma_destroy(vma);
2240 i915_vma_close(vma);
2241 } 2263 }
2242} 2264}
2243 2265
@@ -2248,7 +2270,8 @@ void i915_ppgtt_release(struct kref *kref)
2248 2270
2249 trace_i915_ppgtt_release(&ppgtt->base); 2271 trace_i915_ppgtt_release(&ppgtt->base);
2250 2272
2251 /* vmas should already be unbound and destroyed */ 2273 ppgtt_destroy_vma(&ppgtt->base);
2274
2252 GEM_BUG_ON(!list_empty(&ppgtt->base.active_list)); 2275 GEM_BUG_ON(!list_empty(&ppgtt->base.active_list));
2253 GEM_BUG_ON(!list_empty(&ppgtt->base.inactive_list)); 2276 GEM_BUG_ON(!list_empty(&ppgtt->base.inactive_list));
2254 GEM_BUG_ON(!list_empty(&ppgtt->base.unbound_list)); 2277 GEM_BUG_ON(!list_empty(&ppgtt->base.unbound_list));
@@ -2417,11 +2440,9 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
2417 for_each_sgt_dma(addr, sgt_iter, vma->pages) 2440 for_each_sgt_dma(addr, sgt_iter, vma->pages)
2418 gen8_set_pte(gtt_entries++, pte_encode | addr); 2441 gen8_set_pte(gtt_entries++, pte_encode | addr);
2419 2442
2420 wmb(); 2443 /*
2421 2444 * We want to flush the TLBs only after we're certain all the PTE
2422 /* This next bit makes the above posting read even more important. We 2445 * updates have finished.
2423 * want to flush the TLBs only after we're certain all the PTE updates
2424 * have finished.
2425 */ 2446 */
2426 ggtt->invalidate(vm->i915); 2447 ggtt->invalidate(vm->i915);
2427} 2448}
@@ -2459,11 +2480,10 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
2459 dma_addr_t addr; 2480 dma_addr_t addr;
2460 for_each_sgt_dma(addr, iter, vma->pages) 2481 for_each_sgt_dma(addr, iter, vma->pages)
2461 iowrite32(vm->pte_encode(addr, level, flags), &entries[i++]); 2482 iowrite32(vm->pte_encode(addr, level, flags), &entries[i++]);
2462 wmb();
2463 2483
2464 /* This next bit makes the above posting read even more important. We 2484 /*
2465 * want to flush the TLBs only after we're certain all the PTE updates 2485 * We want to flush the TLBs only after we're certain all the PTE
2466 * have finished. 2486 * updates have finished.
2467 */ 2487 */
2468 ggtt->invalidate(vm->i915); 2488 ggtt->invalidate(vm->i915);
2469} 2489}
@@ -3325,14 +3345,10 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
3325 DRM_ERROR("Can't set DMA mask/consistent mask (%d)\n", err); 3345 DRM_ERROR("Can't set DMA mask/consistent mask (%d)\n", err);
3326 3346
3327 pci_read_config_word(pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); 3347 pci_read_config_word(pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
3328 3348 if (IS_CHERRYVIEW(dev_priv))
3329 if (INTEL_GEN(dev_priv) >= 9) {
3330 size = gen8_get_total_gtt_size(snb_gmch_ctl);
3331 } else if (IS_CHERRYVIEW(dev_priv)) {
3332 size = chv_get_total_gtt_size(snb_gmch_ctl); 3349 size = chv_get_total_gtt_size(snb_gmch_ctl);
3333 } else { 3350 else
3334 size = gen8_get_total_gtt_size(snb_gmch_ctl); 3351 size = gen8_get_total_gtt_size(snb_gmch_ctl);
3335 }
3336 3352
3337 ggtt->base.total = (size / sizeof(gen8_pte_t)) << PAGE_SHIFT; 3353 ggtt->base.total = (size / sizeof(gen8_pte_t)) << PAGE_SHIFT;
3338 ggtt->base.cleanup = gen6_gmch_remove; 3354 ggtt->base.cleanup = gen6_gmch_remove;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 6efc017e8bb3..aec4f73574f4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -38,10 +38,9 @@
38#include <linux/mm.h> 38#include <linux/mm.h>
39#include <linux/pagevec.h> 39#include <linux/pagevec.h>
40 40
41#include "i915_gem_timeline.h"
42
43#include "i915_request.h" 41#include "i915_request.h"
44#include "i915_selftest.h" 42#include "i915_selftest.h"
43#include "i915_timeline.h"
45 44
46#define I915_GTT_PAGE_SIZE_4K BIT(12) 45#define I915_GTT_PAGE_SIZE_4K BIT(12)
47#define I915_GTT_PAGE_SIZE_64K BIT(16) 46#define I915_GTT_PAGE_SIZE_64K BIT(16)
@@ -257,7 +256,6 @@ struct i915_pml4 {
257 256
258struct i915_address_space { 257struct i915_address_space {
259 struct drm_mm mm; 258 struct drm_mm mm;
260 struct i915_gem_timeline timeline;
261 struct drm_i915_private *i915; 259 struct drm_i915_private *i915;
262 struct device *dma; 260 struct device *dma;
263 /* Every address space belongs to a struct file - except for the global 261 /* Every address space belongs to a struct file - except for the global
@@ -344,6 +342,7 @@ struct i915_address_space {
344 void (*clear_pages)(struct i915_vma *vma); 342 void (*clear_pages)(struct i915_vma *vma);
345 343
346 I915_SELFTEST_DECLARE(struct fault_attr fault_attr); 344 I915_SELFTEST_DECLARE(struct fault_attr fault_attr);
345 I915_SELFTEST_DECLARE(bool scrub_64K);
347}; 346};
348 347
349#define i915_is_ggtt(V) (!(V)->file) 348#define i915_is_ggtt(V) (!(V)->file)
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 62aa67960bf4..ad949cc30928 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -51,6 +51,10 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
51 if (!drm_mm_initialized(&dev_priv->mm.stolen)) 51 if (!drm_mm_initialized(&dev_priv->mm.stolen))
52 return -ENODEV; 52 return -ENODEV;
53 53
54 /* WaSkipStolenMemoryFirstPage:bdw+ */
55 if (INTEL_GEN(dev_priv) >= 8 && start < 4096)
56 start = 4096;
57
54 mutex_lock(&dev_priv->mm.stolen_lock); 58 mutex_lock(&dev_priv->mm.stolen_lock);
55 ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node, 59 ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node,
56 size, alignment, 0, 60 size, alignment, 0,
@@ -121,8 +125,8 @@ static int i915_adjust_stolen(struct drm_i915_private *dev_priv,
121 125
122 if (stolen[0].start != stolen[1].start || 126 if (stolen[0].start != stolen[1].start ||
123 stolen[0].end != stolen[1].end) { 127 stolen[0].end != stolen[1].end) {
124 DRM_DEBUG_KMS("GTT within stolen memory at %pR\n", &ggtt_res); 128 DRM_DEBUG_DRIVER("GTT within stolen memory at %pR\n", &ggtt_res);
125 DRM_DEBUG_KMS("Stolen memory adjusted to %pR\n", dsm); 129 DRM_DEBUG_DRIVER("Stolen memory adjusted to %pR\n", dsm);
126 } 130 }
127 } 131 }
128 132
@@ -174,18 +178,19 @@ void i915_gem_cleanup_stolen(struct drm_device *dev)
174} 178}
175 179
176static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv, 180static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv,
177 resource_size_t *base, resource_size_t *size) 181 resource_size_t *base,
182 resource_size_t *size)
178{ 183{
179 uint32_t reg_val = I915_READ(IS_GM45(dev_priv) ? 184 u32 reg_val = I915_READ(IS_GM45(dev_priv) ?
180 CTG_STOLEN_RESERVED : 185 CTG_STOLEN_RESERVED :
181 ELK_STOLEN_RESERVED); 186 ELK_STOLEN_RESERVED);
182 resource_size_t stolen_top = dev_priv->dsm.end + 1; 187 resource_size_t stolen_top = dev_priv->dsm.end + 1;
183 188
184 if ((reg_val & G4X_STOLEN_RESERVED_ENABLE) == 0) { 189 DRM_DEBUG_DRIVER("%s_STOLEN_RESERVED = %08x\n",
185 *base = 0; 190 IS_GM45(dev_priv) ? "CTG" : "ELK", reg_val);
186 *size = 0; 191
192 if ((reg_val & G4X_STOLEN_RESERVED_ENABLE) == 0)
187 return; 193 return;
188 }
189 194
190 /* 195 /*
191 * Whether ILK really reuses the ELK register for this is unclear. 196 * Whether ILK really reuses the ELK register for this is unclear.
@@ -193,30 +198,25 @@ static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv,
193 */ 198 */
194 WARN(IS_GEN5(dev_priv), "ILK stolen reserved found? 0x%08x\n", reg_val); 199 WARN(IS_GEN5(dev_priv), "ILK stolen reserved found? 0x%08x\n", reg_val);
195 200
196 *base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16; 201 if (!(reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK))
202 return;
197 203
204 *base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16;
198 WARN_ON((reg_val & G4X_STOLEN_RESERVED_ADDR1_MASK) < *base); 205 WARN_ON((reg_val & G4X_STOLEN_RESERVED_ADDR1_MASK) < *base);
199 206
200 /* On these platforms, the register doesn't have a size field, so the 207 *size = stolen_top - *base;
201 * size is the distance between the base and the top of the stolen
202 * memory. We also have the genuine case where base is zero and there's
203 * nothing reserved. */
204 if (*base == 0)
205 *size = 0;
206 else
207 *size = stolen_top - *base;
208} 208}
209 209
210static void gen6_get_stolen_reserved(struct drm_i915_private *dev_priv, 210static void gen6_get_stolen_reserved(struct drm_i915_private *dev_priv,
211 resource_size_t *base, resource_size_t *size) 211 resource_size_t *base,
212 resource_size_t *size)
212{ 213{
213 uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); 214 u32 reg_val = I915_READ(GEN6_STOLEN_RESERVED);
215
216 DRM_DEBUG_DRIVER("GEN6_STOLEN_RESERVED = %08x\n", reg_val);
214 217
215 if ((reg_val & GEN6_STOLEN_RESERVED_ENABLE) == 0) { 218 if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
216 *base = 0;
217 *size = 0;
218 return; 219 return;
219 }
220 220
221 *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; 221 *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
222 222
@@ -239,17 +239,44 @@ static void gen6_get_stolen_reserved(struct drm_i915_private *dev_priv,
239 } 239 }
240} 240}
241 241
242static void gen7_get_stolen_reserved(struct drm_i915_private *dev_priv, 242static void vlv_get_stolen_reserved(struct drm_i915_private *dev_priv,
243 resource_size_t *base, resource_size_t *size) 243 resource_size_t *base,
244 resource_size_t *size)
244{ 245{
245 uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); 246 u32 reg_val = I915_READ(GEN6_STOLEN_RESERVED);
247 resource_size_t stolen_top = dev_priv->dsm.end + 1;
248
249 DRM_DEBUG_DRIVER("GEN6_STOLEN_RESERVED = %08x\n", reg_val);
246 250
247 if ((reg_val & GEN6_STOLEN_RESERVED_ENABLE) == 0) { 251 if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
248 *base = 0;
249 *size = 0;
250 return; 252 return;
253
254 switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) {
255 default:
256 MISSING_CASE(reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK);
257 case GEN7_STOLEN_RESERVED_1M:
258 *size = 1024 * 1024;
259 break;
251 } 260 }
252 261
262 /*
263 * On vlv, the ADDR_MASK portion is left as 0 and HW deduces the
264 * reserved location as (top - size).
265 */
266 *base = stolen_top - *size;
267}
268
269static void gen7_get_stolen_reserved(struct drm_i915_private *dev_priv,
270 resource_size_t *base,
271 resource_size_t *size)
272{
273 u32 reg_val = I915_READ(GEN6_STOLEN_RESERVED);
274
275 DRM_DEBUG_DRIVER("GEN6_STOLEN_RESERVED = %08x\n", reg_val);
276
277 if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
278 return;
279
253 *base = reg_val & GEN7_STOLEN_RESERVED_ADDR_MASK; 280 *base = reg_val & GEN7_STOLEN_RESERVED_ADDR_MASK;
254 281
255 switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) { 282 switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) {
@@ -266,15 +293,15 @@ static void gen7_get_stolen_reserved(struct drm_i915_private *dev_priv,
266} 293}
267 294
268static void chv_get_stolen_reserved(struct drm_i915_private *dev_priv, 295static void chv_get_stolen_reserved(struct drm_i915_private *dev_priv,
269 resource_size_t *base, resource_size_t *size) 296 resource_size_t *base,
297 resource_size_t *size)
270{ 298{
271 uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); 299 u32 reg_val = I915_READ(GEN6_STOLEN_RESERVED);
272 300
273 if ((reg_val & GEN6_STOLEN_RESERVED_ENABLE) == 0) { 301 DRM_DEBUG_DRIVER("GEN6_STOLEN_RESERVED = %08x\n", reg_val);
274 *base = 0; 302
275 *size = 0; 303 if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
276 return; 304 return;
277 }
278 305
279 *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; 306 *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
280 307
@@ -298,36 +325,28 @@ static void chv_get_stolen_reserved(struct drm_i915_private *dev_priv,
298} 325}
299 326
300static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv, 327static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv,
301 resource_size_t *base, resource_size_t *size) 328 resource_size_t *base,
329 resource_size_t *size)
302{ 330{
303 uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); 331 u32 reg_val = I915_READ(GEN6_STOLEN_RESERVED);
304 resource_size_t stolen_top; 332 resource_size_t stolen_top = dev_priv->dsm.end + 1;
305 333
306 if ((reg_val & GEN6_STOLEN_RESERVED_ENABLE) == 0) { 334 DRM_DEBUG_DRIVER("GEN6_STOLEN_RESERVED = %08x\n", reg_val);
307 *base = 0; 335
308 *size = 0; 336 if (!(reg_val & GEN6_STOLEN_RESERVED_ENABLE))
309 return; 337 return;
310 }
311 338
312 stolen_top = dev_priv->dsm.end + 1; 339 if (!(reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK))
340 return;
313 341
314 *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; 342 *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
315 343 *size = stolen_top - *base;
316 /* On these platforms, the register doesn't have a size field, so the
317 * size is the distance between the base and the top of the stolen
318 * memory. We also have the genuine case where base is zero and there's
319 * nothing reserved. */
320 if (*base == 0)
321 *size = 0;
322 else
323 *size = stolen_top - *base;
324} 344}
325 345
326int i915_gem_init_stolen(struct drm_i915_private *dev_priv) 346int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
327{ 347{
328 resource_size_t reserved_base, stolen_top; 348 resource_size_t reserved_base, stolen_top;
329 resource_size_t reserved_total, reserved_size; 349 resource_size_t reserved_total, reserved_size;
330 resource_size_t stolen_usable_start;
331 350
332 mutex_init(&dev_priv->mm.stolen_lock); 351 mutex_init(&dev_priv->mm.stolen_lock);
333 352
@@ -353,7 +372,7 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
353 GEM_BUG_ON(dev_priv->dsm.end <= dev_priv->dsm.start); 372 GEM_BUG_ON(dev_priv->dsm.end <= dev_priv->dsm.start);
354 373
355 stolen_top = dev_priv->dsm.end + 1; 374 stolen_top = dev_priv->dsm.end + 1;
356 reserved_base = 0; 375 reserved_base = stolen_top;
357 reserved_size = 0; 376 reserved_size = 0;
358 377
359 switch (INTEL_GEN(dev_priv)) { 378 switch (INTEL_GEN(dev_priv)) {
@@ -373,8 +392,12 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
373 &reserved_base, &reserved_size); 392 &reserved_base, &reserved_size);
374 break; 393 break;
375 case 7: 394 case 7:
376 gen7_get_stolen_reserved(dev_priv, 395 if (IS_VALLEYVIEW(dev_priv))
377 &reserved_base, &reserved_size); 396 vlv_get_stolen_reserved(dev_priv,
397 &reserved_base, &reserved_size);
398 else
399 gen7_get_stolen_reserved(dev_priv,
400 &reserved_base, &reserved_size);
378 break; 401 break;
379 default: 402 default:
380 if (IS_LP(dev_priv)) 403 if (IS_LP(dev_priv))
@@ -386,11 +409,16 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
386 break; 409 break;
387 } 410 }
388 411
389 /* It is possible for the reserved base to be zero, but the register 412 /*
390 * field for size doesn't have a zero option. */ 413 * Our expectation is that the reserved space is at the top of the
391 if (reserved_base == 0) { 414 * stolen region and *never* at the bottom. If we see !reserved_base,
392 reserved_size = 0; 415 * it likely means we failed to read the registers correctly.
416 */
417 if (!reserved_base) {
418 DRM_ERROR("inconsistent reservation %pa + %pa; ignoring\n",
419 &reserved_base, &reserved_size);
393 reserved_base = stolen_top; 420 reserved_base = stolen_top;
421 reserved_size = 0;
394 } 422 }
395 423
396 dev_priv->dsm_reserved = 424 dev_priv->dsm_reserved =
@@ -406,21 +434,15 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
406 * memory, so just consider the start. */ 434 * memory, so just consider the start. */
407 reserved_total = stolen_top - reserved_base; 435 reserved_total = stolen_top - reserved_base;
408 436
409 DRM_DEBUG_KMS("Memory reserved for graphics device: %lluK, usable: %lluK\n", 437 DRM_DEBUG_DRIVER("Memory reserved for graphics device: %lluK, usable: %lluK\n",
410 (u64)resource_size(&dev_priv->dsm) >> 10, 438 (u64)resource_size(&dev_priv->dsm) >> 10,
411 ((u64)resource_size(&dev_priv->dsm) - reserved_total) >> 10); 439 ((u64)resource_size(&dev_priv->dsm) - reserved_total) >> 10);
412
413 stolen_usable_start = 0;
414 /* WaSkipStolenMemoryFirstPage:bdw+ */
415 if (INTEL_GEN(dev_priv) >= 8)
416 stolen_usable_start = 4096;
417 440
418 dev_priv->stolen_usable_size = 441 dev_priv->stolen_usable_size =
419 resource_size(&dev_priv->dsm) - reserved_total - stolen_usable_start; 442 resource_size(&dev_priv->dsm) - reserved_total;
420 443
421 /* Basic memrange allocator for stolen space. */ 444 /* Basic memrange allocator for stolen space. */
422 drm_mm_init(&dev_priv->mm.stolen, stolen_usable_start, 445 drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->stolen_usable_size);
423 dev_priv->stolen_usable_size);
424 446
425 return 0; 447 return 0;
426} 448}
@@ -580,8 +602,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv
580 602
581 lockdep_assert_held(&dev_priv->drm.struct_mutex); 603 lockdep_assert_held(&dev_priv->drm.struct_mutex);
582 604
583 DRM_DEBUG_KMS("creating preallocated stolen object: stolen_offset=%pa, gtt_offset=%pa, size=%pa\n", 605 DRM_DEBUG_DRIVER("creating preallocated stolen object: stolen_offset=%pa, gtt_offset=%pa, size=%pa\n",
584 &stolen_offset, &gtt_offset, &size); 606 &stolen_offset, &gtt_offset, &size);
585 607
586 /* KISS and expect everything to be page-aligned */ 608 /* KISS and expect everything to be page-aligned */
587 if (WARN_ON(size == 0) || 609 if (WARN_ON(size == 0) ||
@@ -599,14 +621,14 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv
599 ret = drm_mm_reserve_node(&dev_priv->mm.stolen, stolen); 621 ret = drm_mm_reserve_node(&dev_priv->mm.stolen, stolen);
600 mutex_unlock(&dev_priv->mm.stolen_lock); 622 mutex_unlock(&dev_priv->mm.stolen_lock);
601 if (ret) { 623 if (ret) {
602 DRM_DEBUG_KMS("failed to allocate stolen space\n"); 624 DRM_DEBUG_DRIVER("failed to allocate stolen space\n");
603 kfree(stolen); 625 kfree(stolen);
604 return NULL; 626 return NULL;
605 } 627 }
606 628
607 obj = _i915_gem_object_create_stolen(dev_priv, stolen); 629 obj = _i915_gem_object_create_stolen(dev_priv, stolen);
608 if (obj == NULL) { 630 if (obj == NULL) {
609 DRM_DEBUG_KMS("failed to allocate stolen object\n"); 631 DRM_DEBUG_DRIVER("failed to allocate stolen object\n");
610 i915_gem_stolen_remove_node(dev_priv, stolen); 632 i915_gem_stolen_remove_node(dev_priv, stolen);
611 kfree(stolen); 633 kfree(stolen);
612 return NULL; 634 return NULL;
@@ -635,7 +657,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv
635 size, gtt_offset, obj->cache_level, 657 size, gtt_offset, obj->cache_level,
636 0); 658 0);
637 if (ret) { 659 if (ret) {
638 DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); 660 DRM_DEBUG_DRIVER("failed to allocate stolen GTT space\n");
639 goto err_pages; 661 goto err_pages;
640 } 662 }
641 663
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
deleted file mode 100644
index e9fd87604067..000000000000
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ /dev/null
@@ -1,154 +0,0 @@
1/*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25#include "i915_drv.h"
26#include "i915_syncmap.h"
27
28static void __intel_timeline_init(struct intel_timeline *tl,
29 struct i915_gem_timeline *parent,
30 u64 context,
31 struct lock_class_key *lockclass,
32 const char *lockname)
33{
34 tl->fence_context = context;
35 tl->common = parent;
36 spin_lock_init(&tl->lock);
37 lockdep_set_class_and_name(&tl->lock, lockclass, lockname);
38 init_request_active(&tl->last_request, NULL);
39 INIT_LIST_HEAD(&tl->requests);
40 i915_syncmap_init(&tl->sync);
41}
42
43static void __intel_timeline_fini(struct intel_timeline *tl)
44{
45 GEM_BUG_ON(!list_empty(&tl->requests));
46
47 i915_syncmap_free(&tl->sync);
48}
49
50static int __i915_gem_timeline_init(struct drm_i915_private *i915,
51 struct i915_gem_timeline *timeline,
52 const char *name,
53 struct lock_class_key *lockclass,
54 const char *lockname)
55{
56 unsigned int i;
57 u64 fences;
58
59 lockdep_assert_held(&i915->drm.struct_mutex);
60
61 /*
62 * Ideally we want a set of engines on a single leaf as we expect
63 * to mostly be tracking synchronisation between engines. It is not
64 * a huge issue if this is not the case, but we may want to mitigate
65 * any page crossing penalties if they become an issue.
66 */
67 BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES);
68
69 timeline->i915 = i915;
70 timeline->name = kstrdup(name ?: "[kernel]", GFP_KERNEL);
71 if (!timeline->name)
72 return -ENOMEM;
73
74 list_add(&timeline->link, &i915->gt.timelines);
75
76 /* Called during early_init before we know how many engines there are */
77 fences = dma_fence_context_alloc(ARRAY_SIZE(timeline->engine));
78 for (i = 0; i < ARRAY_SIZE(timeline->engine); i++)
79 __intel_timeline_init(&timeline->engine[i],
80 timeline, fences++,
81 lockclass, lockname);
82
83 return 0;
84}
85
86int i915_gem_timeline_init(struct drm_i915_private *i915,
87 struct i915_gem_timeline *timeline,
88 const char *name)
89{
90 static struct lock_class_key class;
91
92 return __i915_gem_timeline_init(i915, timeline, name,
93 &class, "&timeline->lock");
94}
95
96int i915_gem_timeline_init__global(struct drm_i915_private *i915)
97{
98 static struct lock_class_key class;
99
100 return __i915_gem_timeline_init(i915,
101 &i915->gt.global_timeline,
102 "[execution]",
103 &class, "&global_timeline->lock");
104}
105
106/**
107 * i915_gem_timelines_park - called when the driver idles
108 * @i915: the drm_i915_private device
109 *
110 * When the driver is completely idle, we know that all of our sync points
111 * have been signaled and our tracking is then entirely redundant. Any request
112 * to wait upon an older sync point will be completed instantly as we know
113 * the fence is signaled and therefore we will not even look them up in the
114 * sync point map.
115 */
116void i915_gem_timelines_park(struct drm_i915_private *i915)
117{
118 struct i915_gem_timeline *timeline;
119 int i;
120
121 lockdep_assert_held(&i915->drm.struct_mutex);
122
123 list_for_each_entry(timeline, &i915->gt.timelines, link) {
124 for (i = 0; i < ARRAY_SIZE(timeline->engine); i++) {
125 struct intel_timeline *tl = &timeline->engine[i];
126
127 /*
128 * All known fences are completed so we can scrap
129 * the current sync point tracking and start afresh,
130 * any attempt to wait upon a previous sync point
131 * will be skipped as the fence was signaled.
132 */
133 i915_syncmap_free(&tl->sync);
134 }
135 }
136}
137
138void i915_gem_timeline_fini(struct i915_gem_timeline *timeline)
139{
140 int i;
141
142 lockdep_assert_held(&timeline->i915->drm.struct_mutex);
143
144 for (i = 0; i < ARRAY_SIZE(timeline->engine); i++)
145 __intel_timeline_fini(&timeline->engine[i]);
146
147 list_del(&timeline->link);
148 kfree(timeline->name);
149}
150
151#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
152#include "selftests/mock_timeline.c"
153#include "selftests/i915_gem_timeline.c"
154#endif
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index f89ac7a8f95f..df234dc23274 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -32,6 +32,7 @@
32#include <linux/zlib.h> 32#include <linux/zlib.h>
33#include <drm/drm_print.h> 33#include <drm/drm_print.h>
34 34
35#include "i915_gpu_error.h"
35#include "i915_drv.h" 36#include "i915_drv.h"
36 37
37static inline const struct intel_engine_cs * 38static inline const struct intel_engine_cs *
@@ -403,16 +404,17 @@ static const char *bannable(const struct drm_i915_error_context *ctx)
403 404
404static void error_print_request(struct drm_i915_error_state_buf *m, 405static void error_print_request(struct drm_i915_error_state_buf *m,
405 const char *prefix, 406 const char *prefix,
406 const struct drm_i915_error_request *erq) 407 const struct drm_i915_error_request *erq,
408 const unsigned long epoch)
407{ 409{
408 if (!erq->seqno) 410 if (!erq->seqno)
409 return; 411 return;
410 412
411 err_printf(m, "%s pid %d, ban score %d, seqno %8x:%08x, prio %d, emitted %dms ago, head %08x, tail %08x\n", 413 err_printf(m, "%s pid %d, ban score %d, seqno %8x:%08x, prio %d, emitted %dms, start %08x, head %08x, tail %08x\n",
412 prefix, erq->pid, erq->ban_score, 414 prefix, erq->pid, erq->ban_score,
413 erq->context, erq->seqno, erq->priority, 415 erq->context, erq->seqno, erq->sched_attr.priority,
414 jiffies_to_msecs(jiffies - erq->jiffies), 416 jiffies_to_msecs(erq->jiffies - epoch),
415 erq->head, erq->tail); 417 erq->start, erq->head, erq->tail);
416} 418}
417 419
418static void error_print_context(struct drm_i915_error_state_buf *m, 420static void error_print_context(struct drm_i915_error_state_buf *m,
@@ -421,12 +423,13 @@ static void error_print_context(struct drm_i915_error_state_buf *m,
421{ 423{
422 err_printf(m, "%s%s[%d] user_handle %d hw_id %d, prio %d, ban score %d%s guilty %d active %d\n", 424 err_printf(m, "%s%s[%d] user_handle %d hw_id %d, prio %d, ban score %d%s guilty %d active %d\n",
423 header, ctx->comm, ctx->pid, ctx->handle, ctx->hw_id, 425 header, ctx->comm, ctx->pid, ctx->handle, ctx->hw_id,
424 ctx->priority, ctx->ban_score, bannable(ctx), 426 ctx->sched_attr.priority, ctx->ban_score, bannable(ctx),
425 ctx->guilty, ctx->active); 427 ctx->guilty, ctx->active);
426} 428}
427 429
428static void error_print_engine(struct drm_i915_error_state_buf *m, 430static void error_print_engine(struct drm_i915_error_state_buf *m,
429 const struct drm_i915_error_engine *ee) 431 const struct drm_i915_error_engine *ee,
432 const unsigned long epoch)
430{ 433{
431 int n; 434 int n;
432 435
@@ -496,14 +499,15 @@ static void error_print_engine(struct drm_i915_error_state_buf *m,
496 err_printf(m, " hangcheck stall: %s\n", yesno(ee->hangcheck_stalled)); 499 err_printf(m, " hangcheck stall: %s\n", yesno(ee->hangcheck_stalled));
497 err_printf(m, " hangcheck action: %s\n", 500 err_printf(m, " hangcheck action: %s\n",
498 hangcheck_action_to_str(ee->hangcheck_action)); 501 hangcheck_action_to_str(ee->hangcheck_action));
499 err_printf(m, " hangcheck action timestamp: %lu, %u ms ago\n", 502 err_printf(m, " hangcheck action timestamp: %dms (%lu%s)\n",
503 jiffies_to_msecs(ee->hangcheck_timestamp - epoch),
500 ee->hangcheck_timestamp, 504 ee->hangcheck_timestamp,
501 jiffies_to_msecs(jiffies - ee->hangcheck_timestamp)); 505 ee->hangcheck_timestamp == epoch ? "; epoch" : "");
502 err_printf(m, " engine reset count: %u\n", ee->reset_count); 506 err_printf(m, " engine reset count: %u\n", ee->reset_count);
503 507
504 for (n = 0; n < ee->num_ports; n++) { 508 for (n = 0; n < ee->num_ports; n++) {
505 err_printf(m, " ELSP[%d]:", n); 509 err_printf(m, " ELSP[%d]:", n);
506 error_print_request(m, " ", &ee->execlist[n]); 510 error_print_request(m, " ", &ee->execlist[n], epoch);
507 } 511 }
508 512
509 error_print_context(m, " Active context: ", &ee->context); 513 error_print_context(m, " Active context: ", &ee->context);
@@ -649,6 +653,11 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
649 ts = ktime_to_timespec64(error->uptime); 653 ts = ktime_to_timespec64(error->uptime);
650 err_printf(m, "Uptime: %lld s %ld us\n", 654 err_printf(m, "Uptime: %lld s %ld us\n",
651 (s64)ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC); 655 (s64)ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC);
656 err_printf(m, "Epoch: %lu jiffies (%u HZ)\n", error->epoch, HZ);
657 err_printf(m, "Capture: %lu jiffies; %d ms ago, %d ms after epoch\n",
658 error->capture,
659 jiffies_to_msecs(jiffies - error->capture),
660 jiffies_to_msecs(error->capture - error->epoch));
652 661
653 for (i = 0; i < ARRAY_SIZE(error->engine); i++) { 662 for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
654 if (error->engine[i].hangcheck_stalled && 663 if (error->engine[i].hangcheck_stalled &&
@@ -709,7 +718,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
709 718
710 for (i = 0; i < ARRAY_SIZE(error->engine); i++) { 719 for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
711 if (error->engine[i].engine_id != -1) 720 if (error->engine[i].engine_id != -1)
712 error_print_engine(m, &error->engine[i]); 721 error_print_engine(m, &error->engine[i], error->epoch);
713 } 722 }
714 723
715 for (i = 0; i < ARRAY_SIZE(error->active_vm); i++) { 724 for (i = 0; i < ARRAY_SIZE(error->active_vm); i++) {
@@ -768,7 +777,9 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
768 dev_priv->engine[i]->name, 777 dev_priv->engine[i]->name,
769 ee->num_requests); 778 ee->num_requests);
770 for (j = 0; j < ee->num_requests; j++) 779 for (j = 0; j < ee->num_requests; j++)
771 error_print_request(m, " ", &ee->requests[j]); 780 error_print_request(m, " ",
781 &ee->requests[j],
782 error->epoch);
772 } 783 }
773 784
774 if (IS_ERR(ee->waiters)) { 785 if (IS_ERR(ee->waiters)) {
@@ -1277,10 +1288,11 @@ static void record_request(struct i915_request *request,
1277 struct drm_i915_error_request *erq) 1288 struct drm_i915_error_request *erq)
1278{ 1289{
1279 erq->context = request->ctx->hw_id; 1290 erq->context = request->ctx->hw_id;
1280 erq->priority = request->priotree.priority; 1291 erq->sched_attr = request->sched.attr;
1281 erq->ban_score = atomic_read(&request->ctx->ban_score); 1292 erq->ban_score = atomic_read(&request->ctx->ban_score);
1282 erq->seqno = request->global_seqno; 1293 erq->seqno = request->global_seqno;
1283 erq->jiffies = request->emitted_jiffies; 1294 erq->jiffies = request->emitted_jiffies;
1295 erq->start = i915_ggtt_offset(request->ring->vma);
1284 erq->head = request->head; 1296 erq->head = request->head;
1285 erq->tail = request->tail; 1297 erq->tail = request->tail;
1286 1298
@@ -1298,7 +1310,7 @@ static void engine_record_requests(struct intel_engine_cs *engine,
1298 1310
1299 count = 0; 1311 count = 0;
1300 request = first; 1312 request = first;
1301 list_for_each_entry_from(request, &engine->timeline->requests, link) 1313 list_for_each_entry_from(request, &engine->timeline.requests, link)
1302 count++; 1314 count++;
1303 if (!count) 1315 if (!count)
1304 return; 1316 return;
@@ -1311,7 +1323,7 @@ static void engine_record_requests(struct intel_engine_cs *engine,
1311 1323
1312 count = 0; 1324 count = 0;
1313 request = first; 1325 request = first;
1314 list_for_each_entry_from(request, &engine->timeline->requests, link) { 1326 list_for_each_entry_from(request, &engine->timeline.requests, link) {
1315 if (count >= ee->num_requests) { 1327 if (count >= ee->num_requests) {
1316 /* 1328 /*
1317 * If the ring request list was changed in 1329 * If the ring request list was changed in
@@ -1371,7 +1383,7 @@ static void record_context(struct drm_i915_error_context *e,
1371 1383
1372 e->handle = ctx->user_handle; 1384 e->handle = ctx->user_handle;
1373 e->hw_id = ctx->hw_id; 1385 e->hw_id = ctx->hw_id;
1374 e->priority = ctx->priority; 1386 e->sched_attr = ctx->sched;
1375 e->ban_score = atomic_read(&ctx->ban_score); 1387 e->ban_score = atomic_read(&ctx->ban_score);
1376 e->bannable = i915_gem_context_is_bannable(ctx); 1388 e->bannable = i915_gem_context_is_bannable(ctx);
1377 e->guilty = atomic_read(&ctx->guilty_count); 1389 e->guilty = atomic_read(&ctx->guilty_count);
@@ -1471,7 +1483,8 @@ static void gem_record_rings(struct i915_gpu_state *error)
1471 1483
1472 ee->ctx = 1484 ee->ctx =
1473 i915_error_object_create(i915, 1485 i915_error_object_create(i915,
1474 request->ctx->engine[i].state); 1486 to_intel_context(request->ctx,
1487 engine)->state);
1475 1488
1476 error->simulated |= 1489 error->simulated |=
1477 i915_gem_context_no_error_capture(request->ctx); 1490 i915_gem_context_no_error_capture(request->ctx);
@@ -1734,6 +1747,22 @@ static void capture_params(struct i915_gpu_state *error)
1734#undef DUP 1747#undef DUP
1735} 1748}
1736 1749
1750static unsigned long capture_find_epoch(const struct i915_gpu_state *error)
1751{
1752 unsigned long epoch = error->capture;
1753 int i;
1754
1755 for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
1756 const struct drm_i915_error_engine *ee = &error->engine[i];
1757
1758 if (ee->hangcheck_stalled &&
1759 time_before(ee->hangcheck_timestamp, epoch))
1760 epoch = ee->hangcheck_timestamp;
1761 }
1762
1763 return epoch;
1764}
1765
1737static int capture(void *data) 1766static int capture(void *data)
1738{ 1767{
1739 struct i915_gpu_state *error = data; 1768 struct i915_gpu_state *error = data;
@@ -1742,6 +1771,7 @@ static int capture(void *data)
1742 error->boottime = ktime_get_boottime(); 1771 error->boottime = ktime_get_boottime();
1743 error->uptime = ktime_sub(ktime_get(), 1772 error->uptime = ktime_sub(ktime_get(),
1744 error->i915->gt.last_init_time); 1773 error->i915->gt.last_init_time);
1774 error->capture = jiffies;
1745 1775
1746 capture_params(error); 1776 capture_params(error);
1747 capture_gen_state(error); 1777 capture_gen_state(error);
@@ -1755,6 +1785,8 @@ static int capture(void *data)
1755 error->overlay = intel_overlay_capture_error_state(error->i915); 1785 error->overlay = intel_overlay_capture_error_state(error->i915);
1756 error->display = intel_display_capture_error_state(error->i915); 1786 error->display = intel_display_capture_error_state(error->i915);
1757 1787
1788 error->epoch = capture_find_epoch(error);
1789
1758 return 0; 1790 return 0;
1759} 1791}
1760 1792
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
new file mode 100644
index 000000000000..dac0f8c4c1cf
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -0,0 +1,366 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright � 2008-2018 Intel Corporation
5 */
6
7#ifndef _I915_GPU_ERROR_H_
8#define _I915_GPU_ERROR_H_
9
10#include <linux/kref.h>
11#include <linux/ktime.h>
12#include <linux/sched.h>
13
14#include <drm/drm_mm.h>
15
16#include "intel_device_info.h"
17#include "intel_ringbuffer.h"
18#include "intel_uc_fw.h"
19
20#include "i915_gem.h"
21#include "i915_gem_gtt.h"
22#include "i915_params.h"
23#include "i915_scheduler.h"
24
25struct drm_i915_private;
26struct intel_overlay_error_state;
27struct intel_display_error_state;
28
29struct i915_gpu_state {
30 struct kref ref;
31 ktime_t time;
32 ktime_t boottime;
33 ktime_t uptime;
34 unsigned long capture;
35 unsigned long epoch;
36
37 struct drm_i915_private *i915;
38
39 char error_msg[128];
40 bool simulated;
41 bool awake;
42 bool wakelock;
43 bool suspended;
44 int iommu;
45 u32 reset_count;
46 u32 suspend_count;
47 struct intel_device_info device_info;
48 struct intel_driver_caps driver_caps;
49 struct i915_params params;
50
51 struct i915_error_uc {
52 struct intel_uc_fw guc_fw;
53 struct intel_uc_fw huc_fw;
54 struct drm_i915_error_object *guc_log;
55 } uc;
56
57 /* Generic register state */
58 u32 eir;
59 u32 pgtbl_er;
60 u32 ier;
61 u32 gtier[4], ngtier;
62 u32 ccid;
63 u32 derrmr;
64 u32 forcewake;
65 u32 error; /* gen6+ */
66 u32 err_int; /* gen7 */
67 u32 fault_data0; /* gen8, gen9 */
68 u32 fault_data1; /* gen8, gen9 */
69 u32 done_reg;
70 u32 gac_eco;
71 u32 gam_ecochk;
72 u32 gab_ctl;
73 u32 gfx_mode;
74
75 u32 nfence;
76 u64 fence[I915_MAX_NUM_FENCES];
77 struct intel_overlay_error_state *overlay;
78 struct intel_display_error_state *display;
79
80 struct drm_i915_error_engine {
81 int engine_id;
82 /* Software tracked state */
83 bool idle;
84 bool waiting;
85 int num_waiters;
86 unsigned long hangcheck_timestamp;
87 bool hangcheck_stalled;
88 enum intel_engine_hangcheck_action hangcheck_action;
89 struct i915_address_space *vm;
90 int num_requests;
91 u32 reset_count;
92
93 /* position of active request inside the ring */
94 u32 rq_head, rq_post, rq_tail;
95
96 /* our own tracking of ring head and tail */
97 u32 cpu_ring_head;
98 u32 cpu_ring_tail;
99
100 u32 last_seqno;
101
102 /* Register state */
103 u32 start;
104 u32 tail;
105 u32 head;
106 u32 ctl;
107 u32 mode;
108 u32 hws;
109 u32 ipeir;
110 u32 ipehr;
111 u32 bbstate;
112 u32 instpm;
113 u32 instps;
114 u32 seqno;
115 u64 bbaddr;
116 u64 acthd;
117 u32 fault_reg;
118 u64 faddr;
119 u32 rc_psmi; /* sleep state */
120 u32 semaphore_mboxes[I915_NUM_ENGINES - 1];
121 struct intel_instdone instdone;
122
123 struct drm_i915_error_context {
124 char comm[TASK_COMM_LEN];
125 pid_t pid;
126 u32 handle;
127 u32 hw_id;
128 int ban_score;
129 int active;
130 int guilty;
131 bool bannable;
132 struct i915_sched_attr sched_attr;
133 } context;
134
135 struct drm_i915_error_object {
136 u64 gtt_offset;
137 u64 gtt_size;
138 int page_count;
139 int unused;
140 u32 *pages[0];
141 } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
142
143 struct drm_i915_error_object **user_bo;
144 long user_bo_count;
145
146 struct drm_i915_error_object *wa_ctx;
147 struct drm_i915_error_object *default_state;
148
149 struct drm_i915_error_request {
150 long jiffies;
151 pid_t pid;
152 u32 context;
153 int ban_score;
154 u32 seqno;
155 u32 start;
156 u32 head;
157 u32 tail;
158 struct i915_sched_attr sched_attr;
159 } *requests, execlist[EXECLIST_MAX_PORTS];
160 unsigned int num_ports;
161
162 struct drm_i915_error_waiter {
163 char comm[TASK_COMM_LEN];
164 pid_t pid;
165 u32 seqno;
166 } *waiters;
167
168 struct {
169 u32 gfx_mode;
170 union {
171 u64 pdp[4];
172 u32 pp_dir_base;
173 };
174 } vm_info;
175 } engine[I915_NUM_ENGINES];
176
177 struct drm_i915_error_buffer {
178 u32 size;
179 u32 name;
180 u32 rseqno[I915_NUM_ENGINES], wseqno;
181 u64 gtt_offset;
182 u32 read_domains;
183 u32 write_domain;
184 s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
185 u32 tiling:2;
186 u32 dirty:1;
187 u32 purgeable:1;
188 u32 userptr:1;
189 s32 engine:4;
190 u32 cache_level:3;
191 } *active_bo[I915_NUM_ENGINES], *pinned_bo;
192 u32 active_bo_count[I915_NUM_ENGINES], pinned_bo_count;
193 struct i915_address_space *active_vm[I915_NUM_ENGINES];
194};
195
196struct i915_gpu_error {
197 /* For hangcheck timer */
198#define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */
199#define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)
200
201 struct delayed_work hangcheck_work;
202
203 /* For reset and error_state handling. */
204 spinlock_t lock;
205 /* Protected by the above dev->gpu_error.lock. */
206 struct i915_gpu_state *first_error;
207
208 atomic_t pending_fb_pin;
209
210 unsigned long missed_irq_rings;
211
212 /**
213 * State variable controlling the reset flow and count
214 *
215 * This is a counter which gets incremented when reset is triggered,
216 *
217 * Before the reset commences, the I915_RESET_BACKOFF bit is set
218 * meaning that any waiters holding onto the struct_mutex should
219 * relinquish the lock immediately in order for the reset to start.
220 *
221 * If reset is not completed successfully, the I915_WEDGE bit is
222 * set meaning that hardware is terminally sour and there is no
223 * recovery. All waiters on the reset_queue will be woken when
224 * that happens.
225 *
226 * This counter is used by the wait_seqno code to notice that reset
227 * event happened and it needs to restart the entire ioctl (since most
228 * likely the seqno it waited for won't ever signal anytime soon).
229 *
230 * This is important for lock-free wait paths, where no contended lock
231 * naturally enforces the correct ordering between the bail-out of the
232 * waiter and the gpu reset work code.
233 */
234 unsigned long reset_count;
235
236 /**
237 * flags: Control various stages of the GPU reset
238 *
239 * #I915_RESET_BACKOFF - When we start a reset, we want to stop any
240 * other users acquiring the struct_mutex. To do this we set the
241 * #I915_RESET_BACKOFF bit in the error flags when we detect a reset
242 * and then check for that bit before acquiring the struct_mutex (in
243 * i915_mutex_lock_interruptible()?). I915_RESET_BACKOFF serves a
244 * secondary role in preventing two concurrent global reset attempts.
245 *
246 * #I915_RESET_HANDOFF - To perform the actual GPU reset, we need the
247 * struct_mutex. We try to acquire the struct_mutex in the reset worker,
248 * but it may be held by some long running waiter (that we cannot
249 * interrupt without causing trouble). Once we are ready to do the GPU
250 * reset, we set the I915_RESET_HANDOFF bit and wakeup any waiters. If
251 * they already hold the struct_mutex and want to participate they can
252 * inspect the bit and do the reset directly, otherwise the worker
253 * waits for the struct_mutex.
254 *
255 * #I915_RESET_ENGINE[num_engines] - Since the driver doesn't need to
256 * acquire the struct_mutex to reset an engine, we need an explicit
257 * flag to prevent two concurrent reset attempts in the same engine.
258 * As the number of engines continues to grow, allocate the flags from
259 * the most significant bits.
260 *
261 * #I915_WEDGED - If reset fails and we can no longer use the GPU,
262 * we set the #I915_WEDGED bit. Prior to command submission, e.g.
263 * i915_request_alloc(), this bit is checked and the sequence
264 * aborted (with -EIO reported to userspace) if set.
265 */
266 unsigned long flags;
267#define I915_RESET_BACKOFF 0
268#define I915_RESET_HANDOFF 1
269#define I915_RESET_MODESET 2
270#define I915_WEDGED (BITS_PER_LONG - 1)
271#define I915_RESET_ENGINE (I915_WEDGED - I915_NUM_ENGINES)
272
273 /** Number of times an engine has been reset */
274 u32 reset_engine_count[I915_NUM_ENGINES];
275
276 /** Set of stalled engines with guilty requests, in the current reset */
277 u32 stalled_mask;
278
279 /** Reason for the current *global* reset */
280 const char *reason;
281
282 /**
283 * Waitqueue to signal when a hang is detected. Used to for waiters
284 * to release the struct_mutex for the reset to procede.
285 */
286 wait_queue_head_t wait_queue;
287
288 /**
289 * Waitqueue to signal when the reset has completed. Used by clients
290 * that wait for dev_priv->mm.wedged to settle.
291 */
292 wait_queue_head_t reset_queue;
293
294 /* For missed irq/seqno simulation. */
295 unsigned long test_irq_rings;
296};
297
298struct drm_i915_error_state_buf {
299 struct drm_i915_private *i915;
300 unsigned int bytes;
301 unsigned int size;
302 int err;
303 u8 *buf;
304 loff_t start;
305 loff_t pos;
306};
307
308#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
309
310__printf(2, 3)
311void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...);
312int i915_error_state_to_str(struct drm_i915_error_state_buf *estr,
313 const struct i915_gpu_state *gpu);
314int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb,
315 struct drm_i915_private *i915,
316 size_t count, loff_t pos);
317
318static inline void
319i915_error_state_buf_release(struct drm_i915_error_state_buf *eb)
320{
321 kfree(eb->buf);
322}
323
324struct i915_gpu_state *i915_capture_gpu_state(struct drm_i915_private *i915);
325void i915_capture_error_state(struct drm_i915_private *dev_priv,
326 u32 engine_mask,
327 const char *error_msg);
328
329static inline struct i915_gpu_state *
330i915_gpu_state_get(struct i915_gpu_state *gpu)
331{
332 kref_get(&gpu->ref);
333 return gpu;
334}
335
336void __i915_gpu_state_free(struct kref *kref);
337static inline void i915_gpu_state_put(struct i915_gpu_state *gpu)
338{
339 if (gpu)
340 kref_put(&gpu->ref, __i915_gpu_state_free);
341}
342
343struct i915_gpu_state *i915_first_error_state(struct drm_i915_private *i915);
344void i915_reset_error_state(struct drm_i915_private *i915);
345
346#else
347
348static inline void i915_capture_error_state(struct drm_i915_private *dev_priv,
349 u32 engine_mask,
350 const char *error_msg)
351{
352}
353
354static inline struct i915_gpu_state *
355i915_first_error_state(struct drm_i915_private *i915)
356{
357 return NULL;
358}
359
360static inline void i915_reset_error_state(struct drm_i915_private *i915)
361{
362}
363
364#endif /* IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) */
365
366#endif /* _I915_GPU_ERROR_H_ */
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 633c18785c1e..f9bc3aaa90d0 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -243,6 +243,41 @@ void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv,
243 spin_unlock_irq(&dev_priv->irq_lock); 243 spin_unlock_irq(&dev_priv->irq_lock);
244} 244}
245 245
246static u32
247gen11_gt_engine_identity(struct drm_i915_private * const i915,
248 const unsigned int bank, const unsigned int bit);
249
250bool gen11_reset_one_iir(struct drm_i915_private * const i915,
251 const unsigned int bank,
252 const unsigned int bit)
253{
254 void __iomem * const regs = i915->regs;
255 u32 dw;
256
257 lockdep_assert_held(&i915->irq_lock);
258
259 dw = raw_reg_read(regs, GEN11_GT_INTR_DW(bank));
260 if (dw & BIT(bit)) {
261 /*
262 * According to the BSpec, DW_IIR bits cannot be cleared without
263 * first servicing the Selector & Shared IIR registers.
264 */
265 gen11_gt_engine_identity(i915, bank, bit);
266
267 /*
268 * We locked GT INT DW by reading it. If we want to (try
269 * to) recover from this succesfully, we need to clear
270 * our bit, otherwise we are locking the register for
271 * everybody.
272 */
273 raw_reg_write(regs, GEN11_GT_INTR_DW(bank), BIT(bit));
274
275 return true;
276 }
277
278 return false;
279}
280
246/** 281/**
247 * ilk_update_display_irq - update DEIMR 282 * ilk_update_display_irq - update DEIMR
248 * @dev_priv: driver private 283 * @dev_priv: driver private
@@ -308,17 +343,29 @@ void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
308 343
309static i915_reg_t gen6_pm_iir(struct drm_i915_private *dev_priv) 344static i915_reg_t gen6_pm_iir(struct drm_i915_private *dev_priv)
310{ 345{
346 WARN_ON_ONCE(INTEL_GEN(dev_priv) >= 11);
347
311 return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; 348 return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR;
312} 349}
313 350
314static i915_reg_t gen6_pm_imr(struct drm_i915_private *dev_priv) 351static i915_reg_t gen6_pm_imr(struct drm_i915_private *dev_priv)
315{ 352{
316 return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR; 353 if (INTEL_GEN(dev_priv) >= 11)
354 return GEN11_GPM_WGBOXPERF_INTR_MASK;
355 else if (INTEL_GEN(dev_priv) >= 8)
356 return GEN8_GT_IMR(2);
357 else
358 return GEN6_PMIMR;
317} 359}
318 360
319static i915_reg_t gen6_pm_ier(struct drm_i915_private *dev_priv) 361static i915_reg_t gen6_pm_ier(struct drm_i915_private *dev_priv)
320{ 362{
321 return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER; 363 if (INTEL_GEN(dev_priv) >= 11)
364 return GEN11_GPM_WGBOXPERF_INTR_ENABLE;
365 else if (INTEL_GEN(dev_priv) >= 8)
366 return GEN8_GT_IER(2);
367 else
368 return GEN6_PMIER;
322} 369}
323 370
324/** 371/**
@@ -400,6 +447,18 @@ static void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, u32 disable_m
400 /* though a barrier is missing here, but don't really need a one */ 447 /* though a barrier is missing here, but don't really need a one */
401} 448}
402 449
450void gen11_reset_rps_interrupts(struct drm_i915_private *dev_priv)
451{
452 spin_lock_irq(&dev_priv->irq_lock);
453
454 while (gen11_reset_one_iir(dev_priv, 0, GEN11_GTPM))
455 ;
456
457 dev_priv->gt_pm.rps.pm_iir = 0;
458
459 spin_unlock_irq(&dev_priv->irq_lock);
460}
461
403void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) 462void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv)
404{ 463{
405 spin_lock_irq(&dev_priv->irq_lock); 464 spin_lock_irq(&dev_priv->irq_lock);
@@ -415,12 +474,14 @@ void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv)
415 if (READ_ONCE(rps->interrupts_enabled)) 474 if (READ_ONCE(rps->interrupts_enabled))
416 return; 475 return;
417 476
418 if (WARN_ON_ONCE(IS_GEN11(dev_priv)))
419 return;
420
421 spin_lock_irq(&dev_priv->irq_lock); 477 spin_lock_irq(&dev_priv->irq_lock);
422 WARN_ON_ONCE(rps->pm_iir); 478 WARN_ON_ONCE(rps->pm_iir);
423 WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); 479
480 if (INTEL_GEN(dev_priv) >= 11)
481 WARN_ON_ONCE(gen11_reset_one_iir(dev_priv, 0, GEN11_GTPM));
482 else
483 WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events);
484
424 rps->interrupts_enabled = true; 485 rps->interrupts_enabled = true;
425 gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); 486 gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
426 487
@@ -434,9 +495,6 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv)
434 if (!READ_ONCE(rps->interrupts_enabled)) 495 if (!READ_ONCE(rps->interrupts_enabled))
435 return; 496 return;
436 497
437 if (WARN_ON_ONCE(IS_GEN11(dev_priv)))
438 return;
439
440 spin_lock_irq(&dev_priv->irq_lock); 498 spin_lock_irq(&dev_priv->irq_lock);
441 rps->interrupts_enabled = false; 499 rps->interrupts_enabled = false;
442 500
@@ -453,7 +511,10 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv)
453 * state of the worker can be discarded. 511 * state of the worker can be discarded.
454 */ 512 */
455 cancel_work_sync(&rps->work); 513 cancel_work_sync(&rps->work);
456 gen6_reset_rps_interrupts(dev_priv); 514 if (INTEL_GEN(dev_priv) >= 11)
515 gen11_reset_rps_interrupts(dev_priv);
516 else
517 gen6_reset_rps_interrupts(dev_priv);
457} 518}
458 519
459void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv) 520void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv)
@@ -1399,19 +1460,18 @@ static void snb_gt_irq_handler(struct drm_i915_private *dev_priv,
1399} 1460}
1400 1461
1401static void 1462static void
1402gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) 1463gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir)
1403{ 1464{
1404 struct intel_engine_execlists * const execlists = &engine->execlists; 1465 struct intel_engine_execlists * const execlists = &engine->execlists;
1405 bool tasklet = false; 1466 bool tasklet = false;
1406 1467
1407 if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift)) { 1468 if (iir & GT_CONTEXT_SWITCH_INTERRUPT) {
1408 if (READ_ONCE(engine->execlists.active)) { 1469 if (READ_ONCE(engine->execlists.active))
1409 __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); 1470 tasklet = !test_and_set_bit(ENGINE_IRQ_EXECLIST,
1410 tasklet = true; 1471 &engine->irq_posted);
1411 }
1412 } 1472 }
1413 1473
1414 if (iir & (GT_RENDER_USER_INTERRUPT << test_shift)) { 1474 if (iir & GT_RENDER_USER_INTERRUPT) {
1415 notify_ring(engine); 1475 notify_ring(engine);
1416 tasklet |= USES_GUC_SUBMISSION(engine->i915); 1476 tasklet |= USES_GUC_SUBMISSION(engine->i915);
1417 } 1477 }
@@ -1466,21 +1526,21 @@ static void gen8_gt_irq_handler(struct drm_i915_private *i915,
1466{ 1526{
1467 if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) { 1527 if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
1468 gen8_cs_irq_handler(i915->engine[RCS], 1528 gen8_cs_irq_handler(i915->engine[RCS],
1469 gt_iir[0], GEN8_RCS_IRQ_SHIFT); 1529 gt_iir[0] >> GEN8_RCS_IRQ_SHIFT);
1470 gen8_cs_irq_handler(i915->engine[BCS], 1530 gen8_cs_irq_handler(i915->engine[BCS],
1471 gt_iir[0], GEN8_BCS_IRQ_SHIFT); 1531 gt_iir[0] >> GEN8_BCS_IRQ_SHIFT);
1472 } 1532 }
1473 1533
1474 if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) { 1534 if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) {
1475 gen8_cs_irq_handler(i915->engine[VCS], 1535 gen8_cs_irq_handler(i915->engine[VCS],
1476 gt_iir[1], GEN8_VCS1_IRQ_SHIFT); 1536 gt_iir[1] >> GEN8_VCS1_IRQ_SHIFT);
1477 gen8_cs_irq_handler(i915->engine[VCS2], 1537 gen8_cs_irq_handler(i915->engine[VCS2],
1478 gt_iir[1], GEN8_VCS2_IRQ_SHIFT); 1538 gt_iir[1] >> GEN8_VCS2_IRQ_SHIFT);
1479 } 1539 }
1480 1540
1481 if (master_ctl & GEN8_GT_VECS_IRQ) { 1541 if (master_ctl & GEN8_GT_VECS_IRQ) {
1482 gen8_cs_irq_handler(i915->engine[VECS], 1542 gen8_cs_irq_handler(i915->engine[VECS],
1483 gt_iir[3], GEN8_VECS_IRQ_SHIFT); 1543 gt_iir[3] >> GEN8_VECS_IRQ_SHIFT);
1484 } 1544 }
1485 1545
1486 if (master_ctl & (GEN8_GT_PM_IRQ | GEN8_GT_GUC_IRQ)) { 1546 if (master_ctl & (GEN8_GT_PM_IRQ | GEN8_GT_GUC_IRQ)) {
@@ -1627,7 +1687,7 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
1627 int head, tail; 1687 int head, tail;
1628 1688
1629 spin_lock(&pipe_crc->lock); 1689 spin_lock(&pipe_crc->lock);
1630 if (pipe_crc->source) { 1690 if (pipe_crc->source && !crtc->base.crc.opened) {
1631 if (!pipe_crc->entries) { 1691 if (!pipe_crc->entries) {
1632 spin_unlock(&pipe_crc->lock); 1692 spin_unlock(&pipe_crc->lock);
1633 DRM_DEBUG_KMS("spurious interrupt\n"); 1693 DRM_DEBUG_KMS("spurious interrupt\n");
@@ -1667,7 +1727,7 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
1667 * On GEN8+ sometimes the second CRC is bonkers as well, so 1727 * On GEN8+ sometimes the second CRC is bonkers as well, so
1668 * don't trust that one either. 1728 * don't trust that one either.
1669 */ 1729 */
1670 if (pipe_crc->skipped == 0 || 1730 if (pipe_crc->skipped <= 0 ||
1671 (INTEL_GEN(dev_priv) >= 8 && pipe_crc->skipped == 1)) { 1731 (INTEL_GEN(dev_priv) >= 8 && pipe_crc->skipped == 1)) {
1672 pipe_crc->skipped++; 1732 pipe_crc->skipped++;
1673 spin_unlock(&pipe_crc->lock); 1733 spin_unlock(&pipe_crc->lock);
@@ -1766,37 +1826,8 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
1766 1826
1767static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir) 1827static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir)
1768{ 1828{
1769 if (gt_iir & GEN9_GUC_TO_HOST_INT_EVENT) { 1829 if (gt_iir & GEN9_GUC_TO_HOST_INT_EVENT)
1770 /* Sample the log buffer flush related bits & clear them out now 1830 intel_guc_to_host_event_handler(&dev_priv->guc);
1771 * itself from the message identity register to minimize the
1772 * probability of losing a flush interrupt, when there are back
1773 * to back flush interrupts.
1774 * There can be a new flush interrupt, for different log buffer
1775 * type (like for ISR), whilst Host is handling one (for DPC).
1776 * Since same bit is used in message register for ISR & DPC, it
1777 * could happen that GuC sets the bit for 2nd interrupt but Host
1778 * clears out the bit on handling the 1st interrupt.
1779 */
1780 u32 msg, flush;
1781
1782 msg = I915_READ(SOFT_SCRATCH(15));
1783 flush = msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED |
1784 INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER);
1785 if (flush) {
1786 /* Clear the message bits that are handled */
1787 I915_WRITE(SOFT_SCRATCH(15), msg & ~flush);
1788
1789 /* Handle flush interrupt in bottom half */
1790 queue_work(dev_priv->guc.log.runtime.flush_wq,
1791 &dev_priv->guc.log.runtime.flush_work);
1792
1793 dev_priv->guc.log.flush_interrupt_count++;
1794 } else {
1795 /* Not clearing of unhandled event bits won't result in
1796 * re-triggering of the interrupt.
1797 */
1798 }
1799 }
1800} 1831}
1801 1832
1802static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) 1833static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv)
@@ -2433,6 +2464,13 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
2433 if (de_iir & DE_ERR_INT_IVB) 2464 if (de_iir & DE_ERR_INT_IVB)
2434 ivb_err_int_handler(dev_priv); 2465 ivb_err_int_handler(dev_priv);
2435 2466
2467 if (de_iir & DE_EDP_PSR_INT_HSW) {
2468 u32 psr_iir = I915_READ(EDP_PSR_IIR);
2469
2470 intel_psr_irq_handler(dev_priv, psr_iir);
2471 I915_WRITE(EDP_PSR_IIR, psr_iir);
2472 }
2473
2436 if (de_iir & DE_AUX_CHANNEL_A_IVB) 2474 if (de_iir & DE_AUX_CHANNEL_A_IVB)
2437 dp_aux_irq_handler(dev_priv); 2475 dp_aux_irq_handler(dev_priv);
2438 2476
@@ -2562,11 +2600,25 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
2562 if (master_ctl & GEN8_DE_MISC_IRQ) { 2600 if (master_ctl & GEN8_DE_MISC_IRQ) {
2563 iir = I915_READ(GEN8_DE_MISC_IIR); 2601 iir = I915_READ(GEN8_DE_MISC_IIR);
2564 if (iir) { 2602 if (iir) {
2603 bool found = false;
2604
2565 I915_WRITE(GEN8_DE_MISC_IIR, iir); 2605 I915_WRITE(GEN8_DE_MISC_IIR, iir);
2566 ret = IRQ_HANDLED; 2606 ret = IRQ_HANDLED;
2567 if (iir & GEN8_DE_MISC_GSE) 2607
2608 if (iir & GEN8_DE_MISC_GSE) {
2568 intel_opregion_asle_intr(dev_priv); 2609 intel_opregion_asle_intr(dev_priv);
2569 else 2610 found = true;
2611 }
2612
2613 if (iir & GEN8_DE_EDP_PSR) {
2614 u32 psr_iir = I915_READ(EDP_PSR_IIR);
2615
2616 intel_psr_irq_handler(dev_priv, psr_iir);
2617 I915_WRITE(EDP_PSR_IIR, psr_iir);
2618 found = true;
2619 }
2620
2621 if (!found)
2570 DRM_ERROR("Unexpected DE Misc interrupt\n"); 2622 DRM_ERROR("Unexpected DE Misc interrupt\n");
2571 } 2623 }
2572 else 2624 else
@@ -2762,58 +2814,16 @@ static void __fini_wedge(struct wedge_me *w)
2762 (W)->i915; \ 2814 (W)->i915; \
2763 __fini_wedge((W))) 2815 __fini_wedge((W)))
2764 2816
2765static __always_inline void
2766gen11_cs_irq_handler(struct intel_engine_cs * const engine, const u32 iir)
2767{
2768 gen8_cs_irq_handler(engine, iir, 0);
2769}
2770
2771static void
2772gen11_gt_engine_irq_handler(struct drm_i915_private * const i915,
2773 const unsigned int bank,
2774 const unsigned int engine_n,
2775 const u16 iir)
2776{
2777 struct intel_engine_cs ** const engine = i915->engine;
2778
2779 switch (bank) {
2780 case 0:
2781 switch (engine_n) {
2782
2783 case GEN11_RCS0:
2784 return gen11_cs_irq_handler(engine[RCS], iir);
2785
2786 case GEN11_BCS:
2787 return gen11_cs_irq_handler(engine[BCS], iir);
2788 }
2789 case 1:
2790 switch (engine_n) {
2791
2792 case GEN11_VCS(0):
2793 return gen11_cs_irq_handler(engine[_VCS(0)], iir);
2794 case GEN11_VCS(1):
2795 return gen11_cs_irq_handler(engine[_VCS(1)], iir);
2796 case GEN11_VCS(2):
2797 return gen11_cs_irq_handler(engine[_VCS(2)], iir);
2798 case GEN11_VCS(3):
2799 return gen11_cs_irq_handler(engine[_VCS(3)], iir);
2800
2801 case GEN11_VECS(0):
2802 return gen11_cs_irq_handler(engine[_VECS(0)], iir);
2803 case GEN11_VECS(1):
2804 return gen11_cs_irq_handler(engine[_VECS(1)], iir);
2805 }
2806 }
2807}
2808
2809static u32 2817static u32
2810gen11_gt_engine_intr(struct drm_i915_private * const i915, 2818gen11_gt_engine_identity(struct drm_i915_private * const i915,
2811 const unsigned int bank, const unsigned int bit) 2819 const unsigned int bank, const unsigned int bit)
2812{ 2820{
2813 void __iomem * const regs = i915->regs; 2821 void __iomem * const regs = i915->regs;
2814 u32 timeout_ts; 2822 u32 timeout_ts;
2815 u32 ident; 2823 u32 ident;
2816 2824
2825 lockdep_assert_held(&i915->irq_lock);
2826
2817 raw_reg_write(regs, GEN11_IIR_REG_SELECTOR(bank), BIT(bit)); 2827 raw_reg_write(regs, GEN11_IIR_REG_SELECTOR(bank), BIT(bit));
2818 2828
2819 /* 2829 /*
@@ -2835,42 +2845,101 @@ gen11_gt_engine_intr(struct drm_i915_private * const i915,
2835 raw_reg_write(regs, GEN11_INTR_IDENTITY_REG(bank), 2845 raw_reg_write(regs, GEN11_INTR_IDENTITY_REG(bank),
2836 GEN11_INTR_DATA_VALID); 2846 GEN11_INTR_DATA_VALID);
2837 2847
2838 return ident & GEN11_INTR_ENGINE_MASK; 2848 return ident;
2839} 2849}
2840 2850
2841static void 2851static void
2842gen11_gt_irq_handler(struct drm_i915_private * const i915, 2852gen11_other_irq_handler(struct drm_i915_private * const i915,
2843 const u32 master_ctl) 2853 const u8 instance, const u16 iir)
2854{
2855 if (instance == OTHER_GTPM_INSTANCE)
2856 return gen6_rps_irq_handler(i915, iir);
2857
2858 WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
2859 instance, iir);
2860}
2861
2862static void
2863gen11_engine_irq_handler(struct drm_i915_private * const i915,
2864 const u8 class, const u8 instance, const u16 iir)
2865{
2866 struct intel_engine_cs *engine;
2867
2868 if (instance <= MAX_ENGINE_INSTANCE)
2869 engine = i915->engine_class[class][instance];
2870 else
2871 engine = NULL;
2872
2873 if (likely(engine))
2874 return gen8_cs_irq_handler(engine, iir);
2875
2876 WARN_ONCE(1, "unhandled engine interrupt class=0x%x, instance=0x%x\n",
2877 class, instance);
2878}
2879
2880static void
2881gen11_gt_identity_handler(struct drm_i915_private * const i915,
2882 const u32 identity)
2883{
2884 const u8 class = GEN11_INTR_ENGINE_CLASS(identity);
2885 const u8 instance = GEN11_INTR_ENGINE_INSTANCE(identity);
2886 const u16 intr = GEN11_INTR_ENGINE_INTR(identity);
2887
2888 if (unlikely(!intr))
2889 return;
2890
2891 if (class <= COPY_ENGINE_CLASS)
2892 return gen11_engine_irq_handler(i915, class, instance, intr);
2893
2894 if (class == OTHER_CLASS)
2895 return gen11_other_irq_handler(i915, instance, intr);
2896
2897 WARN_ONCE(1, "unknown interrupt class=0x%x, instance=0x%x, intr=0x%x\n",
2898 class, instance, intr);
2899}
2900
2901static void
2902gen11_gt_bank_handler(struct drm_i915_private * const i915,
2903 const unsigned int bank)
2844{ 2904{
2845 void __iomem * const regs = i915->regs; 2905 void __iomem * const regs = i915->regs;
2846 unsigned int bank; 2906 unsigned long intr_dw;
2907 unsigned int bit;
2847 2908
2848 for (bank = 0; bank < 2; bank++) { 2909 lockdep_assert_held(&i915->irq_lock);
2849 unsigned long intr_dw;
2850 unsigned int bit;
2851 2910
2852 if (!(master_ctl & GEN11_GT_DW_IRQ(bank))) 2911 intr_dw = raw_reg_read(regs, GEN11_GT_INTR_DW(bank));
2853 continue;
2854 2912
2855 intr_dw = raw_reg_read(regs, GEN11_GT_INTR_DW(bank)); 2913 if (unlikely(!intr_dw)) {
2914 DRM_ERROR("GT_INTR_DW%u blank!\n", bank);
2915 return;
2916 }
2856 2917
2857 if (unlikely(!intr_dw)) { 2918 for_each_set_bit(bit, &intr_dw, 32) {
2858 DRM_ERROR("GT_INTR_DW%u blank!\n", bank); 2919 const u32 ident = gen11_gt_engine_identity(i915,
2859 continue; 2920 bank, bit);
2860 }
2861 2921
2862 for_each_set_bit(bit, &intr_dw, 32) { 2922 gen11_gt_identity_handler(i915, ident);
2863 const u16 iir = gen11_gt_engine_intr(i915, bank, bit); 2923 }
2864 2924
2865 if (unlikely(!iir)) 2925 /* Clear must be after shared has been served for engine */
2866 continue; 2926 raw_reg_write(regs, GEN11_GT_INTR_DW(bank), intr_dw);
2927}
2867 2928
2868 gen11_gt_engine_irq_handler(i915, bank, bit, iir); 2929static void
2869 } 2930gen11_gt_irq_handler(struct drm_i915_private * const i915,
2931 const u32 master_ctl)
2932{
2933 unsigned int bank;
2870 2934
2871 /* Clear must be after shared has been served for engine */ 2935 spin_lock(&i915->irq_lock);
2872 raw_reg_write(regs, GEN11_GT_INTR_DW(bank), intr_dw); 2936
2937 for (bank = 0; bank < 2; bank++) {
2938 if (master_ctl & GEN11_GT_DW_IRQ(bank))
2939 gen11_gt_bank_handler(i915, bank);
2873 } 2940 }
2941
2942 spin_unlock(&i915->irq_lock);
2874} 2943}
2875 2944
2876static irqreturn_t gen11_irq_handler(int irq, void *arg) 2945static irqreturn_t gen11_irq_handler(int irq, void *arg)
@@ -2912,15 +2981,11 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
2912 return IRQ_HANDLED; 2981 return IRQ_HANDLED;
2913} 2982}
2914 2983
2915/** 2984static void i915_reset_device(struct drm_i915_private *dev_priv,
2916 * i915_reset_device - do process context error handling work 2985 u32 engine_mask,
2917 * @dev_priv: i915 device private 2986 const char *reason)
2918 *
2919 * Fire an error uevent so userspace can see that a hang or error
2920 * was detected.
2921 */
2922static void i915_reset_device(struct drm_i915_private *dev_priv)
2923{ 2987{
2988 struct i915_gpu_error *error = &dev_priv->gpu_error;
2924 struct kobject *kobj = &dev_priv->drm.primary->kdev->kobj; 2989 struct kobject *kobj = &dev_priv->drm.primary->kdev->kobj;
2925 char *error_event[] = { I915_ERROR_UEVENT "=1", NULL }; 2990 char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
2926 char *reset_event[] = { I915_RESET_UEVENT "=1", NULL }; 2991 char *reset_event[] = { I915_RESET_UEVENT "=1", NULL };
@@ -2936,29 +3001,35 @@ static void i915_reset_device(struct drm_i915_private *dev_priv)
2936 i915_wedge_on_timeout(&w, dev_priv, 5*HZ) { 3001 i915_wedge_on_timeout(&w, dev_priv, 5*HZ) {
2937 intel_prepare_reset(dev_priv); 3002 intel_prepare_reset(dev_priv);
2938 3003
3004 error->reason = reason;
3005 error->stalled_mask = engine_mask;
3006
2939 /* Signal that locked waiters should reset the GPU */ 3007 /* Signal that locked waiters should reset the GPU */
2940 set_bit(I915_RESET_HANDOFF, &dev_priv->gpu_error.flags); 3008 smp_mb__before_atomic();
2941 wake_up_all(&dev_priv->gpu_error.wait_queue); 3009 set_bit(I915_RESET_HANDOFF, &error->flags);
3010 wake_up_all(&error->wait_queue);
2942 3011
2943 /* Wait for anyone holding the lock to wakeup, without 3012 /* Wait for anyone holding the lock to wakeup, without
2944 * blocking indefinitely on struct_mutex. 3013 * blocking indefinitely on struct_mutex.
2945 */ 3014 */
2946 do { 3015 do {
2947 if (mutex_trylock(&dev_priv->drm.struct_mutex)) { 3016 if (mutex_trylock(&dev_priv->drm.struct_mutex)) {
2948 i915_reset(dev_priv, 0); 3017 i915_reset(dev_priv, engine_mask, reason);
2949 mutex_unlock(&dev_priv->drm.struct_mutex); 3018 mutex_unlock(&dev_priv->drm.struct_mutex);
2950 } 3019 }
2951 } while (wait_on_bit_timeout(&dev_priv->gpu_error.flags, 3020 } while (wait_on_bit_timeout(&error->flags,
2952 I915_RESET_HANDOFF, 3021 I915_RESET_HANDOFF,
2953 TASK_UNINTERRUPTIBLE, 3022 TASK_UNINTERRUPTIBLE,
2954 1)); 3023 1));
2955 3024
3025 error->stalled_mask = 0;
3026 error->reason = NULL;
3027
2956 intel_finish_reset(dev_priv); 3028 intel_finish_reset(dev_priv);
2957 } 3029 }
2958 3030
2959 if (!test_bit(I915_WEDGED, &dev_priv->gpu_error.flags)) 3031 if (!test_bit(I915_WEDGED, &error->flags))
2960 kobject_uevent_env(kobj, 3032 kobject_uevent_env(kobj, KOBJ_CHANGE, reset_done_event);
2961 KOBJ_CHANGE, reset_done_event);
2962} 3033}
2963 3034
2964static void i915_clear_error_registers(struct drm_i915_private *dev_priv) 3035static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
@@ -2990,6 +3061,7 @@ static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
2990 * i915_handle_error - handle a gpu error 3061 * i915_handle_error - handle a gpu error
2991 * @dev_priv: i915 device private 3062 * @dev_priv: i915 device private
2992 * @engine_mask: mask representing engines that are hung 3063 * @engine_mask: mask representing engines that are hung
3064 * @flags: control flags
2993 * @fmt: Error message format string 3065 * @fmt: Error message format string
2994 * 3066 *
2995 * Do some basic checking of register state at error time and 3067 * Do some basic checking of register state at error time and
@@ -3000,16 +3072,23 @@ static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
3000 */ 3072 */
3001void i915_handle_error(struct drm_i915_private *dev_priv, 3073void i915_handle_error(struct drm_i915_private *dev_priv,
3002 u32 engine_mask, 3074 u32 engine_mask,
3075 unsigned long flags,
3003 const char *fmt, ...) 3076 const char *fmt, ...)
3004{ 3077{
3005 struct intel_engine_cs *engine; 3078 struct intel_engine_cs *engine;
3006 unsigned int tmp; 3079 unsigned int tmp;
3007 va_list args;
3008 char error_msg[80]; 3080 char error_msg[80];
3081 char *msg = NULL;
3009 3082
3010 va_start(args, fmt); 3083 if (fmt) {
3011 vscnprintf(error_msg, sizeof(error_msg), fmt, args); 3084 va_list args;
3012 va_end(args); 3085
3086 va_start(args, fmt);
3087 vscnprintf(error_msg, sizeof(error_msg), fmt, args);
3088 va_end(args);
3089
3090 msg = error_msg;
3091 }
3013 3092
3014 /* 3093 /*
3015 * In most cases it's guaranteed that we get here with an RPM 3094 * In most cases it's guaranteed that we get here with an RPM
@@ -3020,8 +3099,12 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
3020 */ 3099 */
3021 intel_runtime_pm_get(dev_priv); 3100 intel_runtime_pm_get(dev_priv);
3022 3101
3023 i915_capture_error_state(dev_priv, engine_mask, error_msg); 3102 engine_mask &= INTEL_INFO(dev_priv)->ring_mask;
3024 i915_clear_error_registers(dev_priv); 3103
3104 if (flags & I915_ERROR_CAPTURE) {
3105 i915_capture_error_state(dev_priv, engine_mask, msg);
3106 i915_clear_error_registers(dev_priv);
3107 }
3025 3108
3026 /* 3109 /*
3027 * Try engine reset when available. We fall back to full reset if 3110 * Try engine reset when available. We fall back to full reset if
@@ -3034,7 +3117,7 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
3034 &dev_priv->gpu_error.flags)) 3117 &dev_priv->gpu_error.flags))
3035 continue; 3118 continue;
3036 3119
3037 if (i915_reset_engine(engine, 0) == 0) 3120 if (i915_reset_engine(engine, msg) == 0)
3038 engine_mask &= ~intel_engine_flag(engine); 3121 engine_mask &= ~intel_engine_flag(engine);
3039 3122
3040 clear_bit(I915_RESET_ENGINE + engine->id, 3123 clear_bit(I915_RESET_ENGINE + engine->id,
@@ -3064,7 +3147,7 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
3064 TASK_UNINTERRUPTIBLE); 3147 TASK_UNINTERRUPTIBLE);
3065 } 3148 }
3066 3149
3067 i915_reset_device(dev_priv); 3150 i915_reset_device(dev_priv, engine_mask, msg);
3068 3151
3069 for_each_engine(engine, dev_priv, tmp) { 3152 for_each_engine(engine, dev_priv, tmp) {
3070 clear_bit(I915_RESET_ENGINE + engine->id, 3153 clear_bit(I915_RESET_ENGINE + engine->id,
@@ -3286,6 +3369,11 @@ static void ironlake_irq_reset(struct drm_device *dev)
3286 if (IS_GEN7(dev_priv)) 3369 if (IS_GEN7(dev_priv))
3287 I915_WRITE(GEN7_ERR_INT, 0xffffffff); 3370 I915_WRITE(GEN7_ERR_INT, 0xffffffff);
3288 3371
3372 if (IS_HASWELL(dev_priv)) {
3373 I915_WRITE(EDP_PSR_IMR, 0xffffffff);
3374 I915_WRITE(EDP_PSR_IIR, 0xffffffff);
3375 }
3376
3289 gen5_gt_irq_reset(dev_priv); 3377 gen5_gt_irq_reset(dev_priv);
3290 3378
3291 ibx_irq_reset(dev_priv); 3379 ibx_irq_reset(dev_priv);
@@ -3324,6 +3412,9 @@ static void gen8_irq_reset(struct drm_device *dev)
3324 3412
3325 gen8_gt_irq_reset(dev_priv); 3413 gen8_gt_irq_reset(dev_priv);
3326 3414
3415 I915_WRITE(EDP_PSR_IMR, 0xffffffff);
3416 I915_WRITE(EDP_PSR_IIR, 0xffffffff);
3417
3327 for_each_pipe(dev_priv, pipe) 3418 for_each_pipe(dev_priv, pipe)
3328 if (intel_display_power_is_enabled(dev_priv, 3419 if (intel_display_power_is_enabled(dev_priv,
3329 POWER_DOMAIN_PIPE(pipe))) 3420 POWER_DOMAIN_PIPE(pipe)))
@@ -3349,6 +3440,9 @@ static void gen11_gt_irq_reset(struct drm_i915_private *dev_priv)
3349 I915_WRITE(GEN11_VCS0_VCS1_INTR_MASK, ~0); 3440 I915_WRITE(GEN11_VCS0_VCS1_INTR_MASK, ~0);
3350 I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~0); 3441 I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~0);
3351 I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~0); 3442 I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~0);
3443
3444 I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
3445 I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_MASK, ~0);
3352} 3446}
3353 3447
3354static void gen11_irq_reset(struct drm_device *dev) 3448static void gen11_irq_reset(struct drm_device *dev)
@@ -3697,6 +3791,12 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
3697 DE_DP_A_HOTPLUG); 3791 DE_DP_A_HOTPLUG);
3698 } 3792 }
3699 3793
3794 if (IS_HASWELL(dev_priv)) {
3795 gen3_assert_iir_is_zero(dev_priv, EDP_PSR_IIR);
3796 intel_psr_irq_control(dev_priv, dev_priv->psr.debug);
3797 display_mask |= DE_EDP_PSR_INT_HSW;
3798 }
3799
3700 dev_priv->irq_mask = ~display_mask; 3800 dev_priv->irq_mask = ~display_mask;
3701 3801
3702 ibx_irq_pre_postinstall(dev); 3802 ibx_irq_pre_postinstall(dev);
@@ -3807,7 +3907,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
3807 uint32_t de_pipe_enables; 3907 uint32_t de_pipe_enables;
3808 u32 de_port_masked = GEN8_AUX_CHANNEL_A; 3908 u32 de_port_masked = GEN8_AUX_CHANNEL_A;
3809 u32 de_port_enables; 3909 u32 de_port_enables;
3810 u32 de_misc_masked = GEN8_DE_MISC_GSE; 3910 u32 de_misc_masked = GEN8_DE_MISC_GSE | GEN8_DE_EDP_PSR;
3811 enum pipe pipe; 3911 enum pipe pipe;
3812 3912
3813 if (INTEL_GEN(dev_priv) >= 9) { 3913 if (INTEL_GEN(dev_priv) >= 9) {
@@ -3832,6 +3932,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
3832 else if (IS_BROADWELL(dev_priv)) 3932 else if (IS_BROADWELL(dev_priv))
3833 de_port_enables |= GEN8_PORT_DP_A_HOTPLUG; 3933 de_port_enables |= GEN8_PORT_DP_A_HOTPLUG;
3834 3934
3935 gen3_assert_iir_is_zero(dev_priv, EDP_PSR_IIR);
3936 intel_psr_irq_control(dev_priv, dev_priv->psr.debug);
3937
3835 for_each_pipe(dev_priv, pipe) { 3938 for_each_pipe(dev_priv, pipe) {
3836 dev_priv->de_irq_mask[pipe] = ~de_pipe_masked; 3939 dev_priv->de_irq_mask[pipe] = ~de_pipe_masked;
3837 3940
@@ -3887,7 +3990,14 @@ static void gen11_gt_irq_postinstall(struct drm_i915_private *dev_priv)
3887 I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~(irqs | irqs << 16)); 3990 I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~(irqs | irqs << 16));
3888 I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~(irqs | irqs << 16)); 3991 I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~(irqs | irqs << 16));
3889 3992
3890 dev_priv->pm_imr = 0xffffffff; /* TODO */ 3993 /*
3994 * RPS interrupts will get enabled/disabled on demand when RPS itself
3995 * is enabled/disabled.
3996 */
3997 dev_priv->pm_ier = 0x0;
3998 dev_priv->pm_imr = ~dev_priv->pm_ier;
3999 I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
4000 I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_MASK, ~0);
3891} 4001}
3892 4002
3893static int gen11_irq_postinstall(struct drm_device *dev) 4003static int gen11_irq_postinstall(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/i915_oa_icl.c b/drivers/gpu/drm/i915/i915_oa_icl.c
new file mode 100644
index 000000000000..a5667926e3de
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_oa_icl.c
@@ -0,0 +1,118 @@
1/*
2 * Autogenerated file by GPU Top : https://github.com/rib/gputop
3 * DO NOT EDIT manually!
4 *
5 *
6 * Copyright (c) 2015 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * IN THE SOFTWARE.
26 *
27 */
28
29#include <linux/sysfs.h>
30
31#include "i915_drv.h"
32#include "i915_oa_icl.h"
33
34static const struct i915_oa_reg b_counter_config_test_oa[] = {
35 { _MMIO(0x2740), 0x00000000 },
36 { _MMIO(0x2710), 0x00000000 },
37 { _MMIO(0x2714), 0xf0800000 },
38 { _MMIO(0x2720), 0x00000000 },
39 { _MMIO(0x2724), 0xf0800000 },
40 { _MMIO(0x2770), 0x00000004 },
41 { _MMIO(0x2774), 0x0000ffff },
42 { _MMIO(0x2778), 0x00000003 },
43 { _MMIO(0x277c), 0x0000ffff },
44 { _MMIO(0x2780), 0x00000007 },
45 { _MMIO(0x2784), 0x0000ffff },
46 { _MMIO(0x2788), 0x00100002 },
47 { _MMIO(0x278c), 0x0000fff7 },
48 { _MMIO(0x2790), 0x00100002 },
49 { _MMIO(0x2794), 0x0000ffcf },
50 { _MMIO(0x2798), 0x00100082 },
51 { _MMIO(0x279c), 0x0000ffef },
52 { _MMIO(0x27a0), 0x001000c2 },
53 { _MMIO(0x27a4), 0x0000ffe7 },
54 { _MMIO(0x27a8), 0x00100001 },
55 { _MMIO(0x27ac), 0x0000ffe7 },
56};
57
58static const struct i915_oa_reg flex_eu_config_test_oa[] = {
59};
60
61static const struct i915_oa_reg mux_config_test_oa[] = {
62 { _MMIO(0xd04), 0x00000200 },
63 { _MMIO(0x9840), 0x00000000 },
64 { _MMIO(0x9884), 0x00000000 },
65 { _MMIO(0x9888), 0x10060000 },
66 { _MMIO(0x9888), 0x22060000 },
67 { _MMIO(0x9888), 0x16060000 },
68 { _MMIO(0x9888), 0x24060000 },
69 { _MMIO(0x9888), 0x18060000 },
70 { _MMIO(0x9888), 0x1a060000 },
71 { _MMIO(0x9888), 0x12060000 },
72 { _MMIO(0x9888), 0x14060000 },
73 { _MMIO(0x9888), 0x10060000 },
74 { _MMIO(0x9888), 0x22060000 },
75 { _MMIO(0x9884), 0x00000003 },
76 { _MMIO(0x9888), 0x16130000 },
77 { _MMIO(0x9888), 0x24000001 },
78 { _MMIO(0x9888), 0x0e130056 },
79 { _MMIO(0x9888), 0x10130000 },
80 { _MMIO(0x9888), 0x1a130000 },
81 { _MMIO(0x9888), 0x541f0001 },
82 { _MMIO(0x9888), 0x181f0000 },
83 { _MMIO(0x9888), 0x4c1f0000 },
84 { _MMIO(0x9888), 0x301f0000 },
85};
86
87static ssize_t
88show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
89{
90 return sprintf(buf, "1\n");
91}
92
93void
94i915_perf_load_test_config_icl(struct drm_i915_private *dev_priv)
95{
96 strlcpy(dev_priv->perf.oa.test_config.uuid,
97 "a291665e-244b-4b76-9b9a-01de9d3c8068",
98 sizeof(dev_priv->perf.oa.test_config.uuid));
99 dev_priv->perf.oa.test_config.id = 1;
100
101 dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
102 dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
103
104 dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
105 dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
106
107 dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
108 dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
109
110 dev_priv->perf.oa.test_config.sysfs_metric.name = "a291665e-244b-4b76-9b9a-01de9d3c8068";
111 dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
112
113 dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
114
115 dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
116 dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
117 dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
118}
diff --git a/drivers/gpu/drm/i915/i915_oa_icl.h b/drivers/gpu/drm/i915/i915_oa_icl.h
new file mode 100644
index 000000000000..ae1c24aafe4f
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_oa_icl.h
@@ -0,0 +1,34 @@
1/*
2 * Autogenerated file by GPU Top : https://github.com/rib/gputop
3 * DO NOT EDIT manually!
4 *
5 *
6 * Copyright (c) 2015 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * IN THE SOFTWARE.
26 *
27 */
28
29#ifndef __I915_OA_ICL_H__
30#define __I915_OA_ICL_H__
31
32extern void i915_perf_load_test_config_icl(struct drm_i915_private *dev_priv);
33
34#endif
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 08108ce5be21..66ea3552c63e 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -164,6 +164,9 @@ i915_param_named_unsafe(guc_firmware_path, charp, 0400,
164i915_param_named_unsafe(huc_firmware_path, charp, 0400, 164i915_param_named_unsafe(huc_firmware_path, charp, 0400,
165 "HuC firmware path to use instead of the default one"); 165 "HuC firmware path to use instead of the default one");
166 166
167i915_param_named_unsafe(dmc_firmware_path, charp, 0400,
168 "DMC firmware path to use instead of the default one");
169
167i915_param_named_unsafe(enable_dp_mst, bool, 0600, 170i915_param_named_unsafe(enable_dp_mst, bool, 0600,
168 "Enable multi-stream transport (MST) for new DisplayPort sinks. (default: true)"); 171 "Enable multi-stream transport (MST) for new DisplayPort sinks. (default: true)");
169 172
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index 430f5f9d0ff4..6684025b7af8 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -48,9 +48,10 @@ struct drm_printer;
48 param(int, enable_ips, 1) \ 48 param(int, enable_ips, 1) \
49 param(int, invert_brightness, 0) \ 49 param(int, invert_brightness, 0) \
50 param(int, enable_guc, 0) \ 50 param(int, enable_guc, 0) \
51 param(int, guc_log_level, 0) \ 51 param(int, guc_log_level, -1) \
52 param(char *, guc_firmware_path, NULL) \ 52 param(char *, guc_firmware_path, NULL) \
53 param(char *, huc_firmware_path, NULL) \ 53 param(char *, huc_firmware_path, NULL) \
54 param(char *, dmc_firmware_path, NULL) \
54 param(int, mmio_debug, 0) \ 55 param(int, mmio_debug, 0) \
55 param(int, edp_vswing, 0) \ 56 param(int, edp_vswing, 0) \
56 param(int, reset, 2) \ 57 param(int, reset, 2) \
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 062e91b39085..4364922e935d 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -602,6 +602,7 @@ static const struct intel_device_info intel_icelake_11_info = {
602 PLATFORM(INTEL_ICELAKE), 602 PLATFORM(INTEL_ICELAKE),
603 .is_alpha_support = 1, 603 .is_alpha_support = 1,
604 .has_resource_streamer = 0, 604 .has_resource_streamer = 0,
605 .ring_mask = RENDER_RING | BLT_RING | VEBOX_RING | BSD_RING | BSD3_RING,
605}; 606};
606 607
607#undef GEN 608#undef GEN
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index abaca6edeb71..019bd2d073ad 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -209,6 +209,7 @@
209#include "i915_oa_cflgt2.h" 209#include "i915_oa_cflgt2.h"
210#include "i915_oa_cflgt3.h" 210#include "i915_oa_cflgt3.h"
211#include "i915_oa_cnl.h" 211#include "i915_oa_cnl.h"
212#include "i915_oa_icl.h"
212 213
213/* HW requires this to be a power of two, between 128k and 16M, though driver 214/* HW requires this to be a power of two, between 128k and 16M, though driver
214 * is currently generally designed assuming the largest 16M size is used such 215 * is currently generally designed assuming the largest 16M size is used such
@@ -1042,7 +1043,7 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
1042 1043
1043 I915_WRITE(GEN7_OASTATUS2, 1044 I915_WRITE(GEN7_OASTATUS2,
1044 ((head & GEN7_OASTATUS2_HEAD_MASK) | 1045 ((head & GEN7_OASTATUS2_HEAD_MASK) |
1045 OA_MEM_SELECT_GGTT)); 1046 GEN7_OASTATUS2_MEM_SELECT_GGTT));
1046 dev_priv->perf.oa.oa_buffer.head = head; 1047 dev_priv->perf.oa.oa_buffer.head = head;
1047 1048
1048 spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags); 1049 spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags);
@@ -1233,7 +1234,7 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
1233 * 1234 *
1234 * NB: implied RCS engine... 1235 * NB: implied RCS engine...
1235 */ 1236 */
1236 ring = engine->context_pin(engine, stream->ctx); 1237 ring = intel_context_pin(stream->ctx, engine);
1237 mutex_unlock(&dev_priv->drm.struct_mutex); 1238 mutex_unlock(&dev_priv->drm.struct_mutex);
1238 if (IS_ERR(ring)) 1239 if (IS_ERR(ring))
1239 return PTR_ERR(ring); 1240 return PTR_ERR(ring);
@@ -1245,7 +1246,7 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
1245 * with gen8+ and execlists 1246 * with gen8+ and execlists
1246 */ 1247 */
1247 dev_priv->perf.oa.specific_ctx_id = 1248 dev_priv->perf.oa.specific_ctx_id =
1248 i915_ggtt_offset(stream->ctx->engine[engine->id].state); 1249 i915_ggtt_offset(to_intel_context(stream->ctx, engine)->state);
1249 } 1250 }
1250 1251
1251 return 0; 1252 return 0;
@@ -1270,7 +1271,7 @@ static void oa_put_render_ctx_id(struct i915_perf_stream *stream)
1270 mutex_lock(&dev_priv->drm.struct_mutex); 1271 mutex_lock(&dev_priv->drm.struct_mutex);
1271 1272
1272 dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID; 1273 dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID;
1273 engine->context_unpin(engine, stream->ctx); 1274 intel_context_unpin(stream->ctx, engine);
1274 1275
1275 mutex_unlock(&dev_priv->drm.struct_mutex); 1276 mutex_unlock(&dev_priv->drm.struct_mutex);
1276 } 1277 }
@@ -1332,7 +1333,8 @@ static void gen7_init_oa_buffer(struct drm_i915_private *dev_priv)
1332 /* Pre-DevBDW: OABUFFER must be set with counters off, 1333 /* Pre-DevBDW: OABUFFER must be set with counters off,
1333 * before OASTATUS1, but after OASTATUS2 1334 * before OASTATUS1, but after OASTATUS2
1334 */ 1335 */
1335 I915_WRITE(GEN7_OASTATUS2, gtt_offset | OA_MEM_SELECT_GGTT); /* head */ 1336 I915_WRITE(GEN7_OASTATUS2,
1337 gtt_offset | GEN7_OASTATUS2_MEM_SELECT_GGTT); /* head */
1336 dev_priv->perf.oa.oa_buffer.head = gtt_offset; 1338 dev_priv->perf.oa.oa_buffer.head = gtt_offset;
1337 1339
1338 I915_WRITE(GEN7_OABUFFER, gtt_offset); 1340 I915_WRITE(GEN7_OABUFFER, gtt_offset);
@@ -1392,7 +1394,7 @@ static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv)
1392 * bit." 1394 * bit."
1393 */ 1395 */
1394 I915_WRITE(GEN8_OABUFFER, gtt_offset | 1396 I915_WRITE(GEN8_OABUFFER, gtt_offset |
1395 OABUFFER_SIZE_16M | OA_MEM_SELECT_GGTT); 1397 OABUFFER_SIZE_16M | GEN8_OABUFFER_MEM_SELECT_GGTT);
1396 I915_WRITE(GEN8_OATAILPTR, gtt_offset & GEN8_OATAILPTR_MASK); 1398 I915_WRITE(GEN8_OATAILPTR, gtt_offset & GEN8_OATAILPTR_MASK);
1397 1399
1398 /* Mark that we need updated tail pointers to read from... */ 1400 /* Mark that we need updated tail pointers to read from... */
@@ -1693,7 +1695,7 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
1693 const struct i915_oa_config *oa_config) 1695 const struct i915_oa_config *oa_config)
1694{ 1696{
1695 struct intel_engine_cs *engine = dev_priv->engine[RCS]; 1697 struct intel_engine_cs *engine = dev_priv->engine[RCS];
1696 struct i915_gem_timeline *timeline; 1698 struct i915_timeline *timeline;
1697 struct i915_request *rq; 1699 struct i915_request *rq;
1698 int ret; 1700 int ret;
1699 1701
@@ -1714,15 +1716,11 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
1714 /* Queue this switch after all other activity */ 1716 /* Queue this switch after all other activity */
1715 list_for_each_entry(timeline, &dev_priv->gt.timelines, link) { 1717 list_for_each_entry(timeline, &dev_priv->gt.timelines, link) {
1716 struct i915_request *prev; 1718 struct i915_request *prev;
1717 struct intel_timeline *tl;
1718 1719
1719 tl = &timeline->engine[engine->id]; 1720 prev = i915_gem_active_raw(&timeline->last_request,
1720 prev = i915_gem_active_raw(&tl->last_request,
1721 &dev_priv->drm.struct_mutex); 1721 &dev_priv->drm.struct_mutex);
1722 if (prev) 1722 if (prev)
1723 i915_sw_fence_await_sw_fence_gfp(&rq->submit, 1723 i915_request_await_dma_fence(rq, &prev->fence);
1724 &prev->submit,
1725 GFP_KERNEL);
1726 } 1724 }
1727 1725
1728 i915_request_add(rq); 1726 i915_request_add(rq);
@@ -1757,6 +1755,7 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
1757static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, 1755static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
1758 const struct i915_oa_config *oa_config) 1756 const struct i915_oa_config *oa_config)
1759{ 1757{
1758 struct intel_engine_cs *engine = dev_priv->engine[RCS];
1760 struct i915_gem_context *ctx; 1759 struct i915_gem_context *ctx;
1761 int ret; 1760 int ret;
1762 unsigned int wait_flags = I915_WAIT_LOCKED; 1761 unsigned int wait_flags = I915_WAIT_LOCKED;
@@ -1787,7 +1786,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
1787 1786
1788 /* Update all contexts now that we've stalled the submission. */ 1787 /* Update all contexts now that we've stalled the submission. */
1789 list_for_each_entry(ctx, &dev_priv->contexts.list, link) { 1788 list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
1790 struct intel_context *ce = &ctx->engine[RCS]; 1789 struct intel_context *ce = to_intel_context(ctx, engine);
1791 u32 *regs; 1790 u32 *regs;
1792 1791
1793 /* OA settings will be set upon first use */ 1792 /* OA settings will be set upon first use */
@@ -1840,7 +1839,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv,
1840 * be read back from automatically triggered reports, as part of the 1839 * be read back from automatically triggered reports, as part of the
1841 * RPT_ID field. 1840 * RPT_ID field.
1842 */ 1841 */
1843 if (IS_GEN9(dev_priv) || IS_GEN10(dev_priv)) { 1842 if (IS_GEN(dev_priv, 9, 11)) {
1844 I915_WRITE(GEN8_OA_DEBUG, 1843 I915_WRITE(GEN8_OA_DEBUG,
1845 _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS | 1844 _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
1846 GEN9_OA_DEBUG_INCLUDE_CLK_RATIO)); 1845 GEN9_OA_DEBUG_INCLUDE_CLK_RATIO));
@@ -1870,7 +1869,6 @@ static void gen8_disable_metric_set(struct drm_i915_private *dev_priv)
1870 1869
1871 I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) & 1870 I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) &
1872 ~GT_NOA_ENABLE)); 1871 ~GT_NOA_ENABLE));
1873
1874} 1872}
1875 1873
1876static void gen10_disable_metric_set(struct drm_i915_private *dev_priv) 1874static void gen10_disable_metric_set(struct drm_i915_private *dev_priv)
@@ -1885,6 +1883,13 @@ static void gen10_disable_metric_set(struct drm_i915_private *dev_priv)
1885 1883
1886static void gen7_oa_enable(struct drm_i915_private *dev_priv) 1884static void gen7_oa_enable(struct drm_i915_private *dev_priv)
1887{ 1885{
1886 struct i915_gem_context *ctx =
1887 dev_priv->perf.oa.exclusive_stream->ctx;
1888 u32 ctx_id = dev_priv->perf.oa.specific_ctx_id;
1889 bool periodic = dev_priv->perf.oa.periodic;
1890 u32 period_exponent = dev_priv->perf.oa.period_exponent;
1891 u32 report_format = dev_priv->perf.oa.oa_buffer.format;
1892
1888 /* 1893 /*
1889 * Reset buf pointers so we don't forward reports from before now. 1894 * Reset buf pointers so we don't forward reports from before now.
1890 * 1895 *
@@ -1896,25 +1901,14 @@ static void gen7_oa_enable(struct drm_i915_private *dev_priv)
1896 */ 1901 */
1897 gen7_init_oa_buffer(dev_priv); 1902 gen7_init_oa_buffer(dev_priv);
1898 1903
1899 if (dev_priv->perf.oa.exclusive_stream->enabled) { 1904 I915_WRITE(GEN7_OACONTROL,
1900 struct i915_gem_context *ctx = 1905 (ctx_id & GEN7_OACONTROL_CTX_MASK) |
1901 dev_priv->perf.oa.exclusive_stream->ctx; 1906 (period_exponent <<
1902 u32 ctx_id = dev_priv->perf.oa.specific_ctx_id; 1907 GEN7_OACONTROL_TIMER_PERIOD_SHIFT) |
1903 1908 (periodic ? GEN7_OACONTROL_TIMER_ENABLE : 0) |
1904 bool periodic = dev_priv->perf.oa.periodic; 1909 (report_format << GEN7_OACONTROL_FORMAT_SHIFT) |
1905 u32 period_exponent = dev_priv->perf.oa.period_exponent; 1910 (ctx ? GEN7_OACONTROL_PER_CTX_ENABLE : 0) |
1906 u32 report_format = dev_priv->perf.oa.oa_buffer.format; 1911 GEN7_OACONTROL_ENABLE);
1907
1908 I915_WRITE(GEN7_OACONTROL,
1909 (ctx_id & GEN7_OACONTROL_CTX_MASK) |
1910 (period_exponent <<
1911 GEN7_OACONTROL_TIMER_PERIOD_SHIFT) |
1912 (periodic ? GEN7_OACONTROL_TIMER_ENABLE : 0) |
1913 (report_format << GEN7_OACONTROL_FORMAT_SHIFT) |
1914 (ctx ? GEN7_OACONTROL_PER_CTX_ENABLE : 0) |
1915 GEN7_OACONTROL_ENABLE);
1916 } else
1917 I915_WRITE(GEN7_OACONTROL, 0);
1918} 1912}
1919 1913
1920static void gen8_oa_enable(struct drm_i915_private *dev_priv) 1914static void gen8_oa_enable(struct drm_i915_private *dev_priv)
@@ -1966,11 +1960,19 @@ static void i915_oa_stream_enable(struct i915_perf_stream *stream)
1966static void gen7_oa_disable(struct drm_i915_private *dev_priv) 1960static void gen7_oa_disable(struct drm_i915_private *dev_priv)
1967{ 1961{
1968 I915_WRITE(GEN7_OACONTROL, 0); 1962 I915_WRITE(GEN7_OACONTROL, 0);
1963 if (intel_wait_for_register(dev_priv,
1964 GEN7_OACONTROL, GEN7_OACONTROL_ENABLE, 0,
1965 50))
1966 DRM_ERROR("wait for OA to be disabled timed out\n");
1969} 1967}
1970 1968
1971static void gen8_oa_disable(struct drm_i915_private *dev_priv) 1969static void gen8_oa_disable(struct drm_i915_private *dev_priv)
1972{ 1970{
1973 I915_WRITE(GEN8_OACONTROL, 0); 1971 I915_WRITE(GEN8_OACONTROL, 0);
1972 if (intel_wait_for_register(dev_priv,
1973 GEN8_OACONTROL, GEN8_OA_COUNTER_ENABLE, 0,
1974 50))
1975 DRM_ERROR("wait for OA to be disabled timed out\n");
1974} 1976}
1975 1977
1976/** 1978/**
@@ -2099,13 +2101,17 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
2099 2101
2100 if (stream->ctx) { 2102 if (stream->ctx) {
2101 ret = oa_get_render_ctx_id(stream); 2103 ret = oa_get_render_ctx_id(stream);
2102 if (ret) 2104 if (ret) {
2105 DRM_DEBUG("Invalid context id to filter with\n");
2103 return ret; 2106 return ret;
2107 }
2104 } 2108 }
2105 2109
2106 ret = get_oa_config(dev_priv, props->metrics_set, &stream->oa_config); 2110 ret = get_oa_config(dev_priv, props->metrics_set, &stream->oa_config);
2107 if (ret) 2111 if (ret) {
2112 DRM_DEBUG("Invalid OA config id=%i\n", props->metrics_set);
2108 goto err_config; 2113 goto err_config;
2114 }
2109 2115
2110 /* PRM - observability performance counters: 2116 /* PRM - observability performance counters:
2111 * 2117 *
@@ -2132,8 +2138,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
2132 2138
2133 ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv, 2139 ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv,
2134 stream->oa_config); 2140 stream->oa_config);
2135 if (ret) 2141 if (ret) {
2142 DRM_DEBUG("Unable to enable metric set\n");
2136 goto err_enable; 2143 goto err_enable;
2144 }
2137 2145
2138 stream->ops = &i915_oa_stream_ops; 2146 stream->ops = &i915_oa_stream_ops;
2139 2147
@@ -2745,7 +2753,8 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
2745 props->ctx_handle = value; 2753 props->ctx_handle = value;
2746 break; 2754 break;
2747 case DRM_I915_PERF_PROP_SAMPLE_OA: 2755 case DRM_I915_PERF_PROP_SAMPLE_OA:
2748 props->sample_flags |= SAMPLE_OA_REPORT; 2756 if (value)
2757 props->sample_flags |= SAMPLE_OA_REPORT;
2749 break; 2758 break;
2750 case DRM_I915_PERF_PROP_OA_METRICS_SET: 2759 case DRM_I915_PERF_PROP_OA_METRICS_SET:
2751 if (value == 0) { 2760 if (value == 0) {
@@ -2935,6 +2944,8 @@ void i915_perf_register(struct drm_i915_private *dev_priv)
2935 i915_perf_load_test_config_cflgt3(dev_priv); 2944 i915_perf_load_test_config_cflgt3(dev_priv);
2936 } else if (IS_CANNONLAKE(dev_priv)) { 2945 } else if (IS_CANNONLAKE(dev_priv)) {
2937 i915_perf_load_test_config_cnl(dev_priv); 2946 i915_perf_load_test_config_cnl(dev_priv);
2947 } else if (IS_ICELAKE(dev_priv)) {
2948 i915_perf_load_test_config_icl(dev_priv);
2938 } 2949 }
2939 2950
2940 if (dev_priv->perf.oa.test_config.id == 0) 2951 if (dev_priv->perf.oa.test_config.id == 0)
@@ -3292,6 +3303,8 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
3292 3303
3293 mutex_unlock(&dev_priv->perf.metrics_lock); 3304 mutex_unlock(&dev_priv->perf.metrics_lock);
3294 3305
3306 DRM_DEBUG("Added config %s id=%i\n", oa_config->uuid, oa_config->id);
3307
3295 return oa_config->id; 3308 return oa_config->id;
3296 3309
3297sysfs_err: 3310sysfs_err:
@@ -3348,6 +3361,9 @@ int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
3348 &oa_config->sysfs_metric); 3361 &oa_config->sysfs_metric);
3349 3362
3350 idr_remove(&dev_priv->perf.metrics_idr, *arg); 3363 idr_remove(&dev_priv->perf.metrics_idr, *arg);
3364
3365 DRM_DEBUG("Removed config %s id=%i\n", oa_config->uuid, oa_config->id);
3366
3351 put_oa_config(dev_priv, oa_config); 3367 put_oa_config(dev_priv, oa_config);
3352 3368
3353config_err: 3369config_err:
@@ -3467,7 +3483,7 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
3467 3483
3468 dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16); 3484 dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16);
3469 } 3485 }
3470 } else if (IS_GEN10(dev_priv)) { 3486 } else if (IS_GEN(dev_priv, 10, 11)) {
3471 dev_priv->perf.oa.ops.is_valid_b_counter_reg = 3487 dev_priv->perf.oa.ops.is_valid_b_counter_reg =
3472 gen7_is_valid_b_counter_addr; 3488 gen7_is_valid_b_counter_addr;
3473 dev_priv->perf.oa.ops.is_valid_mux_reg = 3489 dev_priv->perf.oa.ops.is_valid_mux_reg =
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index f0519e31543a..dc87797db500 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -1,33 +1,12 @@
1/* 1/*
2 * Copyright © 2017 Intel Corporation 2 * SPDX-License-Identifier: MIT
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 * 3 *
4 * Copyright © 2017-2018 Intel Corporation
23 */ 5 */
24 6
25#include <linux/perf_event.h>
26#include <linux/pm_runtime.h>
27
28#include "i915_drv.h"
29#include "i915_pmu.h" 7#include "i915_pmu.h"
30#include "intel_ringbuffer.h" 8#include "intel_ringbuffer.h"
9#include "i915_drv.h"
31 10
32/* Frequency for the sampling timer for events which need it. */ 11/* Frequency for the sampling timer for events which need it. */
33#define FREQUENCY 200 12#define FREQUENCY 200
diff --git a/drivers/gpu/drm/i915/i915_pmu.h b/drivers/gpu/drm/i915/i915_pmu.h
index aa1b1a987ea1..2ba735299f7c 100644
--- a/drivers/gpu/drm/i915/i915_pmu.h
+++ b/drivers/gpu/drm/i915/i915_pmu.h
@@ -1,29 +1,19 @@
1/* 1/*
2 * Copyright © 2017 Intel Corporation 2 * SPDX-License-Identifier: MIT
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 * 3 *
4 * Copyright © 2017-2018 Intel Corporation
23 */ 5 */
6
24#ifndef __I915_PMU_H__ 7#ifndef __I915_PMU_H__
25#define __I915_PMU_H__ 8#define __I915_PMU_H__
26 9
10#include <linux/hrtimer.h>
11#include <linux/perf_event.h>
12#include <linux/spinlock_types.h>
13#include <drm/i915_drm.h>
14
15struct drm_i915_private;
16
27enum { 17enum {
28 __I915_SAMPLE_FREQ_ACT = 0, 18 __I915_SAMPLE_FREQ_ACT = 0,
29 __I915_SAMPLE_FREQ_REQ, 19 __I915_SAMPLE_FREQ_REQ,
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8a69a9275e28..f11bb213ec07 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -153,9 +153,6 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
153#define _MMIO_PORT3(pipe, a, b, c) _MMIO(_PICK(pipe, a, b, c)) 153#define _MMIO_PORT3(pipe, a, b, c) _MMIO(_PICK(pipe, a, b, c))
154#define _PLL(pll, a, b) ((a) + (pll)*((b)-(a))) 154#define _PLL(pll, a, b) ((a) + (pll)*((b)-(a)))
155#define _MMIO_PLL(pll, a, b) _MMIO(_PLL(pll, a, b)) 155#define _MMIO_PLL(pll, a, b) _MMIO(_PLL(pll, a, b))
156#define _MMIO_PORT6(port, a, b, c, d, e, f) _MMIO(_PICK(port, a, b, c, d, e, f))
157#define _MMIO_PORT6_LN(port, ln, a0, a1, b, c, d, e, f) \
158 _MMIO(_PICK(port, a0, b, c, d, e, f) + (ln * (a1 - a0)))
159#define _PHY3(phy, ...) _PICK(phy, __VA_ARGS__) 156#define _PHY3(phy, ...) _PICK(phy, __VA_ARGS__)
160#define _MMIO_PHY3(phy, a, b, c) _MMIO(_PHY3(phy, a, b, c)) 157#define _MMIO_PHY3(phy, a, b, c) _MMIO(_PHY3(phy, a, b, c))
161 158
@@ -191,6 +188,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
191#define OTHER_CLASS 4 188#define OTHER_CLASS 4
192#define MAX_ENGINE_CLASS 4 189#define MAX_ENGINE_CLASS 4
193 190
191#define OTHER_GTPM_INSTANCE 1
194#define MAX_ENGINE_INSTANCE 3 192#define MAX_ENGINE_INSTANCE 3
195 193
196/* PCI config space */ 194/* PCI config space */
@@ -304,6 +302,17 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
304#define GEN6_GRDOM_VECS (1 << 4) 302#define GEN6_GRDOM_VECS (1 << 4)
305#define GEN9_GRDOM_GUC (1 << 5) 303#define GEN9_GRDOM_GUC (1 << 5)
306#define GEN8_GRDOM_MEDIA2 (1 << 7) 304#define GEN8_GRDOM_MEDIA2 (1 << 7)
305/* GEN11 changed all bit defs except for FULL & RENDER */
306#define GEN11_GRDOM_FULL GEN6_GRDOM_FULL
307#define GEN11_GRDOM_RENDER GEN6_GRDOM_RENDER
308#define GEN11_GRDOM_BLT (1 << 2)
309#define GEN11_GRDOM_GUC (1 << 3)
310#define GEN11_GRDOM_MEDIA (1 << 5)
311#define GEN11_GRDOM_MEDIA2 (1 << 6)
312#define GEN11_GRDOM_MEDIA3 (1 << 7)
313#define GEN11_GRDOM_MEDIA4 (1 << 8)
314#define GEN11_GRDOM_VECS (1 << 13)
315#define GEN11_GRDOM_VECS2 (1 << 14)
307 316
308#define RING_PP_DIR_BASE(engine) _MMIO((engine)->mmio_base+0x228) 317#define RING_PP_DIR_BASE(engine) _MMIO((engine)->mmio_base+0x228)
309#define RING_PP_DIR_BASE_READ(engine) _MMIO((engine)->mmio_base+0x518) 318#define RING_PP_DIR_BASE_READ(engine) _MMIO((engine)->mmio_base+0x518)
@@ -430,145 +439,6 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
430#define VGA_CR_INDEX_CGA 0x3d4 439#define VGA_CR_INDEX_CGA 0x3d4
431#define VGA_CR_DATA_CGA 0x3d5 440#define VGA_CR_DATA_CGA 0x3d5
432 441
433/*
434 * Instruction field definitions used by the command parser
435 */
436#define INSTR_CLIENT_SHIFT 29
437#define INSTR_MI_CLIENT 0x0
438#define INSTR_BC_CLIENT 0x2
439#define INSTR_RC_CLIENT 0x3
440#define INSTR_SUBCLIENT_SHIFT 27
441#define INSTR_SUBCLIENT_MASK 0x18000000
442#define INSTR_MEDIA_SUBCLIENT 0x2
443#define INSTR_26_TO_24_MASK 0x7000000
444#define INSTR_26_TO_24_SHIFT 24
445
446/*
447 * Memory interface instructions used by the kernel
448 */
449#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
450/* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */
451#define MI_GLOBAL_GTT (1<<22)
452
453#define MI_NOOP MI_INSTR(0, 0)
454#define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
455#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0)
456#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16)
457#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
458#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
459#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
460#define MI_FLUSH MI_INSTR(0x04, 0)
461#define MI_READ_FLUSH (1 << 0)
462#define MI_EXE_FLUSH (1 << 1)
463#define MI_NO_WRITE_FLUSH (1 << 2)
464#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
465#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
466#define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */
467#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
468#define MI_ARB_ON_OFF MI_INSTR(0x08, 0)
469#define MI_ARB_ENABLE (1<<0)
470#define MI_ARB_DISABLE (0<<0)
471#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
472#define MI_SUSPEND_FLUSH MI_INSTR(0x0b, 0)
473#define MI_SUSPEND_FLUSH_EN (1<<0)
474#define MI_SET_APPID MI_INSTR(0x0e, 0)
475#define MI_OVERLAY_FLIP MI_INSTR(0x11, 0)
476#define MI_OVERLAY_CONTINUE (0x0<<21)
477#define MI_OVERLAY_ON (0x1<<21)
478#define MI_OVERLAY_OFF (0x2<<21)
479#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
480#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
481#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1)
482#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
483/* IVB has funny definitions for which plane to flip. */
484#define MI_DISPLAY_FLIP_IVB_PLANE_A (0 << 19)
485#define MI_DISPLAY_FLIP_IVB_PLANE_B (1 << 19)
486#define MI_DISPLAY_FLIP_IVB_SPRITE_A (2 << 19)
487#define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
488#define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19)
489#define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
490/* SKL ones */
491#define MI_DISPLAY_FLIP_SKL_PLANE_1_A (0 << 8)
492#define MI_DISPLAY_FLIP_SKL_PLANE_1_B (1 << 8)
493#define MI_DISPLAY_FLIP_SKL_PLANE_1_C (2 << 8)
494#define MI_DISPLAY_FLIP_SKL_PLANE_2_A (4 << 8)
495#define MI_DISPLAY_FLIP_SKL_PLANE_2_B (5 << 8)
496#define MI_DISPLAY_FLIP_SKL_PLANE_2_C (6 << 8)
497#define MI_DISPLAY_FLIP_SKL_PLANE_3_A (7 << 8)
498#define MI_DISPLAY_FLIP_SKL_PLANE_3_B (8 << 8)
499#define MI_DISPLAY_FLIP_SKL_PLANE_3_C (9 << 8)
500#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6, gen7 */
501#define MI_SEMAPHORE_GLOBAL_GTT (1<<22)
502#define MI_SEMAPHORE_UPDATE (1<<21)
503#define MI_SEMAPHORE_COMPARE (1<<20)
504#define MI_SEMAPHORE_REGISTER (1<<18)
505#define MI_SEMAPHORE_SYNC_VR (0<<16) /* RCS wait for VCS (RVSYNC) */
506#define MI_SEMAPHORE_SYNC_VER (1<<16) /* RCS wait for VECS (RVESYNC) */
507#define MI_SEMAPHORE_SYNC_BR (2<<16) /* RCS wait for BCS (RBSYNC) */
508#define MI_SEMAPHORE_SYNC_BV (0<<16) /* VCS wait for BCS (VBSYNC) */
509#define MI_SEMAPHORE_SYNC_VEV (1<<16) /* VCS wait for VECS (VVESYNC) */
510#define MI_SEMAPHORE_SYNC_RV (2<<16) /* VCS wait for RCS (VRSYNC) */
511#define MI_SEMAPHORE_SYNC_RB (0<<16) /* BCS wait for RCS (BRSYNC) */
512#define MI_SEMAPHORE_SYNC_VEB (1<<16) /* BCS wait for VECS (BVESYNC) */
513#define MI_SEMAPHORE_SYNC_VB (2<<16) /* BCS wait for VCS (BVSYNC) */
514#define MI_SEMAPHORE_SYNC_BVE (0<<16) /* VECS wait for BCS (VEBSYNC) */
515#define MI_SEMAPHORE_SYNC_VVE (1<<16) /* VECS wait for VCS (VEVSYNC) */
516#define MI_SEMAPHORE_SYNC_RVE (2<<16) /* VECS wait for RCS (VERSYNC) */
517#define MI_SEMAPHORE_SYNC_INVALID (3<<16)
518#define MI_SEMAPHORE_SYNC_MASK (3<<16)
519#define MI_SET_CONTEXT MI_INSTR(0x18, 0)
520#define MI_MM_SPACE_GTT (1<<8)
521#define MI_MM_SPACE_PHYSICAL (0<<8)
522#define MI_SAVE_EXT_STATE_EN (1<<3)
523#define MI_RESTORE_EXT_STATE_EN (1<<2)
524#define MI_FORCE_RESTORE (1<<1)
525#define MI_RESTORE_INHIBIT (1<<0)
526#define HSW_MI_RS_SAVE_STATE_EN (1<<3)
527#define HSW_MI_RS_RESTORE_STATE_EN (1<<2)
528#define MI_SEMAPHORE_SIGNAL MI_INSTR(0x1b, 0) /* GEN8+ */
529#define MI_SEMAPHORE_TARGET(engine) ((engine)<<15)
530#define MI_SEMAPHORE_WAIT MI_INSTR(0x1c, 2) /* GEN8+ */
531#define MI_SEMAPHORE_POLL (1<<15)
532#define MI_SEMAPHORE_SAD_GTE_SDD (1<<12)
533#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
534#define MI_STORE_DWORD_IMM_GEN4 MI_INSTR(0x20, 2)
535#define MI_MEM_VIRTUAL (1 << 22) /* 945,g33,965 */
536#define MI_USE_GGTT (1 << 22) /* g4x+ */
537#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
538#define MI_STORE_DWORD_INDEX_SHIFT 2
539/* Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM:
540 * - Always issue a MI_NOOP _before_ the MI_LOAD_REGISTER_IMM - otherwise hw
541 * simply ignores the register load under certain conditions.
542 * - One can actually load arbitrary many arbitrary registers: Simply issue x
543 * address/value pairs. Don't overdue it, though, x <= 2^4 must hold!
544 */
545#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*(x)-1)
546#define MI_LRI_FORCE_POSTED (1<<12)
547#define MI_STORE_REGISTER_MEM MI_INSTR(0x24, 1)
548#define MI_STORE_REGISTER_MEM_GEN8 MI_INSTR(0x24, 2)
549#define MI_SRM_LRM_GLOBAL_GTT (1<<22)
550#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */
551#define MI_FLUSH_DW_STORE_INDEX (1<<21)
552#define MI_INVALIDATE_TLB (1<<18)
553#define MI_FLUSH_DW_OP_STOREDW (1<<14)
554#define MI_FLUSH_DW_OP_MASK (3<<14)
555#define MI_FLUSH_DW_NOTIFY (1<<8)
556#define MI_INVALIDATE_BSD (1<<7)
557#define MI_FLUSH_DW_USE_GTT (1<<2)
558#define MI_FLUSH_DW_USE_PPGTT (0<<2)
559#define MI_LOAD_REGISTER_MEM MI_INSTR(0x29, 1)
560#define MI_LOAD_REGISTER_MEM_GEN8 MI_INSTR(0x29, 2)
561#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
562#define MI_BATCH_NON_SECURE (1)
563/* for snb/ivb/vlv this also means "batch in ppgtt" when ppgtt is enabled. */
564#define MI_BATCH_NON_SECURE_I965 (1<<8)
565#define MI_BATCH_PPGTT_HSW (1<<8)
566#define MI_BATCH_NON_SECURE_HSW (1<<13)
567#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
568#define MI_BATCH_GTT (2<<6) /* aliased with (1<<7) on gen4 */
569#define MI_BATCH_BUFFER_START_GEN8 MI_INSTR(0x31, 1)
570#define MI_BATCH_RESOURCE_STREAMER (1<<10)
571
572#define MI_PREDICATE_SRC0 _MMIO(0x2400) 442#define MI_PREDICATE_SRC0 _MMIO(0x2400)
573#define MI_PREDICATE_SRC0_UDW _MMIO(0x2400 + 4) 443#define MI_PREDICATE_SRC0_UDW _MMIO(0x2400 + 4)
574#define MI_PREDICATE_SRC1 _MMIO(0x2408) 444#define MI_PREDICATE_SRC1 _MMIO(0x2408)
@@ -579,130 +449,6 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
579#define LOWER_SLICE_DISABLED (0<<0) 449#define LOWER_SLICE_DISABLED (0<<0)
580 450
581/* 451/*
582 * 3D instructions used by the kernel
583 */
584#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
585
586#define GEN9_MEDIA_POOL_STATE ((0x3 << 29) | (0x2 << 27) | (0x5 << 16) | 4)
587#define GEN9_MEDIA_POOL_ENABLE (1 << 31)
588#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
589#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
590#define SC_UPDATE_SCISSOR (0x1<<1)
591#define SC_ENABLE_MASK (0x1<<0)
592#define SC_ENABLE (0x1<<0)
593#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
594#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
595#define SCI_YMIN_MASK (0xffff<<16)
596#define SCI_XMIN_MASK (0xffff<<0)
597#define SCI_YMAX_MASK (0xffff<<16)
598#define SCI_XMAX_MASK (0xffff<<0)
599#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
600#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
601#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
602#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
603#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
604#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
605#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
606#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
607#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
608
609#define COLOR_BLT_CMD (2<<29 | 0x40<<22 | (5-2))
610#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
611#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
612#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5)
613#define BLT_WRITE_A (2<<20)
614#define BLT_WRITE_RGB (1<<20)
615#define BLT_WRITE_RGBA (BLT_WRITE_RGB | BLT_WRITE_A)
616#define BLT_DEPTH_8 (0<<24)
617#define BLT_DEPTH_16_565 (1<<24)
618#define BLT_DEPTH_16_1555 (2<<24)
619#define BLT_DEPTH_32 (3<<24)
620#define BLT_ROP_SRC_COPY (0xcc<<16)
621#define BLT_ROP_COLOR_COPY (0xf0<<16)
622#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */
623#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */
624#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
625#define ASYNC_FLIP (1<<22)
626#define DISPLAY_PLANE_A (0<<20)
627#define DISPLAY_PLANE_B (1<<20)
628#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|((len)-2))
629#define PIPE_CONTROL_FLUSH_L3 (1<<27)
630#define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */
631#define PIPE_CONTROL_MMIO_WRITE (1<<23)
632#define PIPE_CONTROL_STORE_DATA_INDEX (1<<21)
633#define PIPE_CONTROL_CS_STALL (1<<20)
634#define PIPE_CONTROL_TLB_INVALIDATE (1<<18)
635#define PIPE_CONTROL_MEDIA_STATE_CLEAR (1<<16)
636#define PIPE_CONTROL_QW_WRITE (1<<14)
637#define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14)
638#define PIPE_CONTROL_DEPTH_STALL (1<<13)
639#define PIPE_CONTROL_WRITE_FLUSH (1<<12)
640#define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */
641#define PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE (1<<11) /* MBZ on Ironlake */
642#define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */
643#define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9)
644#define PIPE_CONTROL_NOTIFY (1<<8)
645#define PIPE_CONTROL_FLUSH_ENABLE (1<<7) /* gen7+ */
646#define PIPE_CONTROL_DC_FLUSH_ENABLE (1<<5)
647#define PIPE_CONTROL_VF_CACHE_INVALIDATE (1<<4)
648#define PIPE_CONTROL_CONST_CACHE_INVALIDATE (1<<3)
649#define PIPE_CONTROL_STATE_CACHE_INVALIDATE (1<<2)
650#define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1)
651#define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0)
652#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
653
654/*
655 * Commands used only by the command parser
656 */
657#define MI_SET_PREDICATE MI_INSTR(0x01, 0)
658#define MI_ARB_CHECK MI_INSTR(0x05, 0)
659#define MI_RS_CONTROL MI_INSTR(0x06, 0)
660#define MI_URB_ATOMIC_ALLOC MI_INSTR(0x09, 0)
661#define MI_PREDICATE MI_INSTR(0x0C, 0)
662#define MI_RS_CONTEXT MI_INSTR(0x0F, 0)
663#define MI_TOPOLOGY_FILTER MI_INSTR(0x0D, 0)
664#define MI_LOAD_SCAN_LINES_EXCL MI_INSTR(0x13, 0)
665#define MI_URB_CLEAR MI_INSTR(0x19, 0)
666#define MI_UPDATE_GTT MI_INSTR(0x23, 0)
667#define MI_CLFLUSH MI_INSTR(0x27, 0)
668#define MI_REPORT_PERF_COUNT MI_INSTR(0x28, 0)
669#define MI_REPORT_PERF_COUNT_GGTT (1<<0)
670#define MI_LOAD_REGISTER_REG MI_INSTR(0x2A, 0)
671#define MI_RS_STORE_DATA_IMM MI_INSTR(0x2B, 0)
672#define MI_LOAD_URB_MEM MI_INSTR(0x2C, 0)
673#define MI_STORE_URB_MEM MI_INSTR(0x2D, 0)
674#define MI_CONDITIONAL_BATCH_BUFFER_END MI_INSTR(0x36, 0)
675
676#define PIPELINE_SELECT ((0x3<<29)|(0x1<<27)|(0x1<<24)|(0x4<<16))
677#define GFX_OP_3DSTATE_VF_STATISTICS ((0x3<<29)|(0x1<<27)|(0x0<<24)|(0xB<<16))
678#define MEDIA_VFE_STATE ((0x3<<29)|(0x2<<27)|(0x0<<24)|(0x0<<16))
679#define MEDIA_VFE_STATE_MMIO_ACCESS_MASK (0x18)
680#define GPGPU_OBJECT ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x4<<16))
681#define GPGPU_WALKER ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x5<<16))
682#define GFX_OP_3DSTATE_DX9_CONSTANTF_VS \
683 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x39<<16))
684#define GFX_OP_3DSTATE_DX9_CONSTANTF_PS \
685 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x3A<<16))
686#define GFX_OP_3DSTATE_SO_DECL_LIST \
687 ((0x3<<29)|(0x3<<27)|(0x1<<24)|(0x17<<16))
688
689#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_VS \
690 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x43<<16))
691#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_GS \
692 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x44<<16))
693#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_HS \
694 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x45<<16))
695#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_DS \
696 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x46<<16))
697#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS \
698 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x47<<16))
699
700#define MFX_WAIT ((0x3<<29)|(0x1<<27)|(0x0<<16))
701
702#define COLOR_BLT ((0x2<<29)|(0x40<<22))
703#define SRC_COPY_BLT ((0x2<<29)|(0x43<<22))
704
705/*
706 * Registers used only by the command parser 452 * Registers used only by the command parser
707 */ 453 */
708#define BCS_SWCTRL _MMIO(0x22200) 454#define BCS_SWCTRL _MMIO(0x22200)
@@ -802,6 +548,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
802 548
803#define GEN8_OABUFFER_UDW _MMIO(0x23b4) 549#define GEN8_OABUFFER_UDW _MMIO(0x23b4)
804#define GEN8_OABUFFER _MMIO(0x2b14) 550#define GEN8_OABUFFER _MMIO(0x2b14)
551#define GEN8_OABUFFER_MEM_SELECT_GGTT (1 << 0) /* 0: PPGTT, 1: GGTT */
805 552
806#define GEN7_OASTATUS1 _MMIO(0x2364) 553#define GEN7_OASTATUS1 _MMIO(0x2364)
807#define GEN7_OASTATUS1_TAIL_MASK 0xffffffc0 554#define GEN7_OASTATUS1_TAIL_MASK 0xffffffc0
@@ -810,7 +557,8 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
810#define GEN7_OASTATUS1_REPORT_LOST (1<<0) 557#define GEN7_OASTATUS1_REPORT_LOST (1<<0)
811 558
812#define GEN7_OASTATUS2 _MMIO(0x2368) 559#define GEN7_OASTATUS2 _MMIO(0x2368)
813#define GEN7_OASTATUS2_HEAD_MASK 0xffffffc0 560#define GEN7_OASTATUS2_HEAD_MASK 0xffffffc0
561#define GEN7_OASTATUS2_MEM_SELECT_GGTT (1 << 0) /* 0: PPGTT, 1: GGTT */
814 562
815#define GEN8_OASTATUS _MMIO(0x2b08) 563#define GEN8_OASTATUS _MMIO(0x2b08)
816#define GEN8_OASTATUS_OVERRUN_STATUS (1<<3) 564#define GEN8_OASTATUS_OVERRUN_STATUS (1<<3)
@@ -832,8 +580,6 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
832#define OABUFFER_SIZE_8M (6<<3) 580#define OABUFFER_SIZE_8M (6<<3)
833#define OABUFFER_SIZE_16M (7<<3) 581#define OABUFFER_SIZE_16M (7<<3)
834 582
835#define OA_MEM_SELECT_GGTT (1<<0)
836
837/* 583/*
838 * Flexible, Aggregate EU Counter Registers. 584 * Flexible, Aggregate EU Counter Registers.
839 * Note: these aren't contiguous 585 * Note: these aren't contiguous
@@ -1127,6 +873,12 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
1127#define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK (1 << GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT) 873#define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK (1 << GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT)
1128#define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ 0 874#define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ 0
1129#define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ 1 875#define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ 1
876#define GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT 3
877#define GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK (0x7 << GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT)
878#define GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ 0
879#define GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ 1
880#define GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ 2
881#define GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ 3
1130#define GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT 1 882#define GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT 1
1131#define GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK (0x3 << GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT) 883#define GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK (0x3 << GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT)
1132 884
@@ -1948,79 +1700,100 @@ enum i915_power_well_id {
1948#define _CNL_PORT_PCS_DW1_LN0_C 0x162C04 1700#define _CNL_PORT_PCS_DW1_LN0_C 0x162C04
1949#define _CNL_PORT_PCS_DW1_LN0_D 0x162E04 1701#define _CNL_PORT_PCS_DW1_LN0_D 0x162E04
1950#define _CNL_PORT_PCS_DW1_LN0_F 0x162804 1702#define _CNL_PORT_PCS_DW1_LN0_F 0x162804
1951#define CNL_PORT_PCS_DW1_GRP(port) _MMIO_PORT6(port, \ 1703#define CNL_PORT_PCS_DW1_GRP(port) _MMIO(_PICK(port, \
1952 _CNL_PORT_PCS_DW1_GRP_AE, \ 1704 _CNL_PORT_PCS_DW1_GRP_AE, \
1953 _CNL_PORT_PCS_DW1_GRP_B, \ 1705 _CNL_PORT_PCS_DW1_GRP_B, \
1954 _CNL_PORT_PCS_DW1_GRP_C, \ 1706 _CNL_PORT_PCS_DW1_GRP_C, \
1955 _CNL_PORT_PCS_DW1_GRP_D, \ 1707 _CNL_PORT_PCS_DW1_GRP_D, \
1956 _CNL_PORT_PCS_DW1_GRP_AE, \ 1708 _CNL_PORT_PCS_DW1_GRP_AE, \
1957 _CNL_PORT_PCS_DW1_GRP_F) 1709 _CNL_PORT_PCS_DW1_GRP_F))
1958#define CNL_PORT_PCS_DW1_LN0(port) _MMIO_PORT6(port, \ 1710
1711#define CNL_PORT_PCS_DW1_LN0(port) _MMIO(_PICK(port, \
1959 _CNL_PORT_PCS_DW1_LN0_AE, \ 1712 _CNL_PORT_PCS_DW1_LN0_AE, \
1960 _CNL_PORT_PCS_DW1_LN0_B, \ 1713 _CNL_PORT_PCS_DW1_LN0_B, \
1961 _CNL_PORT_PCS_DW1_LN0_C, \ 1714 _CNL_PORT_PCS_DW1_LN0_C, \
1962 _CNL_PORT_PCS_DW1_LN0_D, \ 1715 _CNL_PORT_PCS_DW1_LN0_D, \
1963 _CNL_PORT_PCS_DW1_LN0_AE, \ 1716 _CNL_PORT_PCS_DW1_LN0_AE, \
1964 _CNL_PORT_PCS_DW1_LN0_F) 1717 _CNL_PORT_PCS_DW1_LN0_F))
1718#define _ICL_PORT_PCS_DW1_GRP_A 0x162604
1719#define _ICL_PORT_PCS_DW1_GRP_B 0x6C604
1720#define _ICL_PORT_PCS_DW1_LN0_A 0x162804
1721#define _ICL_PORT_PCS_DW1_LN0_B 0x6C804
1722#define ICL_PORT_PCS_DW1_GRP(port) _MMIO_PORT(port,\
1723 _ICL_PORT_PCS_DW1_GRP_A, \
1724 _ICL_PORT_PCS_DW1_GRP_B)
1725#define ICL_PORT_PCS_DW1_LN0(port) _MMIO_PORT(port, \
1726 _ICL_PORT_PCS_DW1_LN0_A, \
1727 _ICL_PORT_PCS_DW1_LN0_B)
1965#define COMMON_KEEPER_EN (1 << 26) 1728#define COMMON_KEEPER_EN (1 << 26)
1966 1729
1967#define _CNL_PORT_TX_DW2_GRP_AE 0x162348 1730/* CNL Port TX registers */
1968#define _CNL_PORT_TX_DW2_GRP_B 0x1623C8 1731#define _CNL_PORT_TX_AE_GRP_OFFSET 0x162340
1969#define _CNL_PORT_TX_DW2_GRP_C 0x162B48 1732#define _CNL_PORT_TX_B_GRP_OFFSET 0x1623C0
1970#define _CNL_PORT_TX_DW2_GRP_D 0x162BC8 1733#define _CNL_PORT_TX_C_GRP_OFFSET 0x162B40
1971#define _CNL_PORT_TX_DW2_GRP_F 0x162A48 1734#define _CNL_PORT_TX_D_GRP_OFFSET 0x162BC0
1972#define _CNL_PORT_TX_DW2_LN0_AE 0x162448 1735#define _CNL_PORT_TX_F_GRP_OFFSET 0x162A40
1973#define _CNL_PORT_TX_DW2_LN0_B 0x162648 1736#define _CNL_PORT_TX_AE_LN0_OFFSET 0x162440
1974#define _CNL_PORT_TX_DW2_LN0_C 0x162C48 1737#define _CNL_PORT_TX_B_LN0_OFFSET 0x162640
1975#define _CNL_PORT_TX_DW2_LN0_D 0x162E48 1738#define _CNL_PORT_TX_C_LN0_OFFSET 0x162C40
1976#define _CNL_PORT_TX_DW2_LN0_F 0x162848 1739#define _CNL_PORT_TX_D_LN0_OFFSET 0x162E40
1977#define CNL_PORT_TX_DW2_GRP(port) _MMIO_PORT6(port, \ 1740#define _CNL_PORT_TX_F_LN0_OFFSET 0x162840
1978 _CNL_PORT_TX_DW2_GRP_AE, \ 1741#define _CNL_PORT_TX_DW_GRP(port, dw) (_PICK((port), \
1979 _CNL_PORT_TX_DW2_GRP_B, \ 1742 _CNL_PORT_TX_AE_GRP_OFFSET, \
1980 _CNL_PORT_TX_DW2_GRP_C, \ 1743 _CNL_PORT_TX_B_GRP_OFFSET, \
1981 _CNL_PORT_TX_DW2_GRP_D, \ 1744 _CNL_PORT_TX_B_GRP_OFFSET, \
1982 _CNL_PORT_TX_DW2_GRP_AE, \ 1745 _CNL_PORT_TX_D_GRP_OFFSET, \
1983 _CNL_PORT_TX_DW2_GRP_F) 1746 _CNL_PORT_TX_AE_GRP_OFFSET, \
1984#define CNL_PORT_TX_DW2_LN0(port) _MMIO_PORT6(port, \ 1747 _CNL_PORT_TX_F_GRP_OFFSET) + \
1985 _CNL_PORT_TX_DW2_LN0_AE, \ 1748 4*(dw))
1986 _CNL_PORT_TX_DW2_LN0_B, \ 1749#define _CNL_PORT_TX_DW_LN0(port, dw) (_PICK((port), \
1987 _CNL_PORT_TX_DW2_LN0_C, \ 1750 _CNL_PORT_TX_AE_LN0_OFFSET, \
1988 _CNL_PORT_TX_DW2_LN0_D, \ 1751 _CNL_PORT_TX_B_LN0_OFFSET, \
1989 _CNL_PORT_TX_DW2_LN0_AE, \ 1752 _CNL_PORT_TX_B_LN0_OFFSET, \
1990 _CNL_PORT_TX_DW2_LN0_F) 1753 _CNL_PORT_TX_D_LN0_OFFSET, \
1991#define SWING_SEL_UPPER(x) ((x >> 3) << 15) 1754 _CNL_PORT_TX_AE_LN0_OFFSET, \
1755 _CNL_PORT_TX_F_LN0_OFFSET) + \
1756 4*(dw))
1757
1758#define CNL_PORT_TX_DW2_GRP(port) _MMIO(_CNL_PORT_TX_DW_GRP((port), 2))
1759#define CNL_PORT_TX_DW2_LN0(port) _MMIO(_CNL_PORT_TX_DW_LN0((port), 2))
1760#define _ICL_PORT_TX_DW2_GRP_A 0x162688
1761#define _ICL_PORT_TX_DW2_GRP_B 0x6C688
1762#define _ICL_PORT_TX_DW2_LN0_A 0x162888
1763#define _ICL_PORT_TX_DW2_LN0_B 0x6C888
1764#define ICL_PORT_TX_DW2_GRP(port) _MMIO_PORT(port, \
1765 _ICL_PORT_TX_DW2_GRP_A, \
1766 _ICL_PORT_TX_DW2_GRP_B)
1767#define ICL_PORT_TX_DW2_LN0(port) _MMIO_PORT(port, \
1768 _ICL_PORT_TX_DW2_LN0_A, \
1769 _ICL_PORT_TX_DW2_LN0_B)
1770#define SWING_SEL_UPPER(x) (((x) >> 3) << 15)
1992#define SWING_SEL_UPPER_MASK (1 << 15) 1771#define SWING_SEL_UPPER_MASK (1 << 15)
1993#define SWING_SEL_LOWER(x) ((x & 0x7) << 11) 1772#define SWING_SEL_LOWER(x) (((x) & 0x7) << 11)
1994#define SWING_SEL_LOWER_MASK (0x7 << 11) 1773#define SWING_SEL_LOWER_MASK (0x7 << 11)
1995#define RCOMP_SCALAR(x) ((x) << 0) 1774#define RCOMP_SCALAR(x) ((x) << 0)
1996#define RCOMP_SCALAR_MASK (0xFF << 0) 1775#define RCOMP_SCALAR_MASK (0xFF << 0)
1997 1776
1998#define _CNL_PORT_TX_DW4_GRP_AE 0x162350
1999#define _CNL_PORT_TX_DW4_GRP_B 0x1623D0
2000#define _CNL_PORT_TX_DW4_GRP_C 0x162B50
2001#define _CNL_PORT_TX_DW4_GRP_D 0x162BD0
2002#define _CNL_PORT_TX_DW4_GRP_F 0x162A50
2003#define _CNL_PORT_TX_DW4_LN0_AE 0x162450 1777#define _CNL_PORT_TX_DW4_LN0_AE 0x162450
2004#define _CNL_PORT_TX_DW4_LN1_AE 0x1624D0 1778#define _CNL_PORT_TX_DW4_LN1_AE 0x1624D0
2005#define _CNL_PORT_TX_DW4_LN0_B 0x162650 1779#define CNL_PORT_TX_DW4_GRP(port) _MMIO(_CNL_PORT_TX_DW_GRP((port), 4))
2006#define _CNL_PORT_TX_DW4_LN0_C 0x162C50 1780#define CNL_PORT_TX_DW4_LN0(port) _MMIO(_CNL_PORT_TX_DW_LN0((port), 4))
2007#define _CNL_PORT_TX_DW4_LN0_D 0x162E50 1781#define CNL_PORT_TX_DW4_LN(port, ln) _MMIO(_CNL_PORT_TX_DW_LN0((port), 4) + \
2008#define _CNL_PORT_TX_DW4_LN0_F 0x162850 1782 (ln * (_CNL_PORT_TX_DW4_LN1_AE - \
2009#define CNL_PORT_TX_DW4_GRP(port) _MMIO_PORT6(port, \ 1783 _CNL_PORT_TX_DW4_LN0_AE)))
2010 _CNL_PORT_TX_DW4_GRP_AE, \ 1784#define _ICL_PORT_TX_DW4_GRP_A 0x162690
2011 _CNL_PORT_TX_DW4_GRP_B, \ 1785#define _ICL_PORT_TX_DW4_GRP_B 0x6C690
2012 _CNL_PORT_TX_DW4_GRP_C, \ 1786#define _ICL_PORT_TX_DW4_LN0_A 0x162890
2013 _CNL_PORT_TX_DW4_GRP_D, \ 1787#define _ICL_PORT_TX_DW4_LN1_A 0x162990
2014 _CNL_PORT_TX_DW4_GRP_AE, \ 1788#define _ICL_PORT_TX_DW4_LN0_B 0x6C890
2015 _CNL_PORT_TX_DW4_GRP_F) 1789#define ICL_PORT_TX_DW4_GRP(port) _MMIO_PORT(port, \
2016#define CNL_PORT_TX_DW4_LN(port, ln) _MMIO_PORT6_LN(port, ln, \ 1790 _ICL_PORT_TX_DW4_GRP_A, \
2017 _CNL_PORT_TX_DW4_LN0_AE, \ 1791 _ICL_PORT_TX_DW4_GRP_B)
2018 _CNL_PORT_TX_DW4_LN1_AE, \ 1792#define ICL_PORT_TX_DW4_LN(port, ln) _MMIO(_PORT(port, \
2019 _CNL_PORT_TX_DW4_LN0_B, \ 1793 _ICL_PORT_TX_DW4_LN0_A, \
2020 _CNL_PORT_TX_DW4_LN0_C, \ 1794 _ICL_PORT_TX_DW4_LN0_B) + \
2021 _CNL_PORT_TX_DW4_LN0_D, \ 1795 (ln * (_ICL_PORT_TX_DW4_LN1_A - \
2022 _CNL_PORT_TX_DW4_LN0_AE, \ 1796 _ICL_PORT_TX_DW4_LN0_A)))
2023 _CNL_PORT_TX_DW4_LN0_F)
2024#define LOADGEN_SELECT (1 << 31) 1797#define LOADGEN_SELECT (1 << 31)
2025#define POST_CURSOR_1(x) ((x) << 12) 1798#define POST_CURSOR_1(x) ((x) << 12)
2026#define POST_CURSOR_1_MASK (0x3F << 12) 1799#define POST_CURSOR_1_MASK (0x3F << 12)
@@ -2029,64 +1802,147 @@ enum i915_power_well_id {
2029#define CURSOR_COEFF(x) ((x) << 0) 1802#define CURSOR_COEFF(x) ((x) << 0)
2030#define CURSOR_COEFF_MASK (0x3F << 0) 1803#define CURSOR_COEFF_MASK (0x3F << 0)
2031 1804
2032#define _CNL_PORT_TX_DW5_GRP_AE 0x162354 1805#define CNL_PORT_TX_DW5_GRP(port) _MMIO(_CNL_PORT_TX_DW_GRP((port), 5))
2033#define _CNL_PORT_TX_DW5_GRP_B 0x1623D4 1806#define CNL_PORT_TX_DW5_LN0(port) _MMIO(_CNL_PORT_TX_DW_LN0((port), 5))
2034#define _CNL_PORT_TX_DW5_GRP_C 0x162B54 1807#define _ICL_PORT_TX_DW5_GRP_A 0x162694
2035#define _CNL_PORT_TX_DW5_GRP_D 0x162BD4 1808#define _ICL_PORT_TX_DW5_GRP_B 0x6C694
2036#define _CNL_PORT_TX_DW5_GRP_F 0x162A54 1809#define _ICL_PORT_TX_DW5_LN0_A 0x162894
2037#define _CNL_PORT_TX_DW5_LN0_AE 0x162454 1810#define _ICL_PORT_TX_DW5_LN0_B 0x6C894
2038#define _CNL_PORT_TX_DW5_LN0_B 0x162654 1811#define ICL_PORT_TX_DW5_GRP(port) _MMIO_PORT(port, \
2039#define _CNL_PORT_TX_DW5_LN0_C 0x162C54 1812 _ICL_PORT_TX_DW5_GRP_A, \
2040#define _CNL_PORT_TX_DW5_LN0_D 0x162E54 1813 _ICL_PORT_TX_DW5_GRP_B)
2041#define _CNL_PORT_TX_DW5_LN0_F 0x162854 1814#define ICL_PORT_TX_DW5_LN0(port) _MMIO_PORT(port, \
2042#define CNL_PORT_TX_DW5_GRP(port) _MMIO_PORT6(port, \ 1815 _ICL_PORT_TX_DW5_LN0_A, \
2043 _CNL_PORT_TX_DW5_GRP_AE, \ 1816 _ICL_PORT_TX_DW5_LN0_B)
2044 _CNL_PORT_TX_DW5_GRP_B, \
2045 _CNL_PORT_TX_DW5_GRP_C, \
2046 _CNL_PORT_TX_DW5_GRP_D, \
2047 _CNL_PORT_TX_DW5_GRP_AE, \
2048 _CNL_PORT_TX_DW5_GRP_F)
2049#define CNL_PORT_TX_DW5_LN0(port) _MMIO_PORT6(port, \
2050 _CNL_PORT_TX_DW5_LN0_AE, \
2051 _CNL_PORT_TX_DW5_LN0_B, \
2052 _CNL_PORT_TX_DW5_LN0_C, \
2053 _CNL_PORT_TX_DW5_LN0_D, \
2054 _CNL_PORT_TX_DW5_LN0_AE, \
2055 _CNL_PORT_TX_DW5_LN0_F)
2056#define TX_TRAINING_EN (1 << 31) 1817#define TX_TRAINING_EN (1 << 31)
1818#define TAP2_DISABLE (1 << 30)
2057#define TAP3_DISABLE (1 << 29) 1819#define TAP3_DISABLE (1 << 29)
2058#define SCALING_MODE_SEL(x) ((x) << 18) 1820#define SCALING_MODE_SEL(x) ((x) << 18)
2059#define SCALING_MODE_SEL_MASK (0x7 << 18) 1821#define SCALING_MODE_SEL_MASK (0x7 << 18)
2060#define RTERM_SELECT(x) ((x) << 3) 1822#define RTERM_SELECT(x) ((x) << 3)
2061#define RTERM_SELECT_MASK (0x7 << 3) 1823#define RTERM_SELECT_MASK (0x7 << 3)
2062 1824
2063#define _CNL_PORT_TX_DW7_GRP_AE 0x16235C 1825#define CNL_PORT_TX_DW7_GRP(port) _MMIO(_CNL_PORT_TX_DW_GRP((port), 7))
2064#define _CNL_PORT_TX_DW7_GRP_B 0x1623DC 1826#define CNL_PORT_TX_DW7_LN0(port) _MMIO(_CNL_PORT_TX_DW_LN0((port), 7))
2065#define _CNL_PORT_TX_DW7_GRP_C 0x162B5C
2066#define _CNL_PORT_TX_DW7_GRP_D 0x162BDC
2067#define _CNL_PORT_TX_DW7_GRP_F 0x162A5C
2068#define _CNL_PORT_TX_DW7_LN0_AE 0x16245C
2069#define _CNL_PORT_TX_DW7_LN0_B 0x16265C
2070#define _CNL_PORT_TX_DW7_LN0_C 0x162C5C
2071#define _CNL_PORT_TX_DW7_LN0_D 0x162E5C
2072#define _CNL_PORT_TX_DW7_LN0_F 0x16285C
2073#define CNL_PORT_TX_DW7_GRP(port) _MMIO_PORT6(port, \
2074 _CNL_PORT_TX_DW7_GRP_AE, \
2075 _CNL_PORT_TX_DW7_GRP_B, \
2076 _CNL_PORT_TX_DW7_GRP_C, \
2077 _CNL_PORT_TX_DW7_GRP_D, \
2078 _CNL_PORT_TX_DW7_GRP_AE, \
2079 _CNL_PORT_TX_DW7_GRP_F)
2080#define CNL_PORT_TX_DW7_LN0(port) _MMIO_PORT6(port, \
2081 _CNL_PORT_TX_DW7_LN0_AE, \
2082 _CNL_PORT_TX_DW7_LN0_B, \
2083 _CNL_PORT_TX_DW7_LN0_C, \
2084 _CNL_PORT_TX_DW7_LN0_D, \
2085 _CNL_PORT_TX_DW7_LN0_AE, \
2086 _CNL_PORT_TX_DW7_LN0_F)
2087#define N_SCALAR(x) ((x) << 24) 1827#define N_SCALAR(x) ((x) << 24)
2088#define N_SCALAR_MASK (0x7F << 24) 1828#define N_SCALAR_MASK (0x7F << 24)
2089 1829
1830#define _ICL_MG_PHY_PORT_LN(port, ln, ln0p1, ln0p2, ln1p1) \
1831 _MMIO(_PORT((port) - PORT_C, ln0p1, ln0p2) + (ln) * ((ln1p1) - (ln0p1)))
1832
1833#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT1 0x16812C
1834#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT1 0x16852C
1835#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT2 0x16912C
1836#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT2 0x16952C
1837#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT3 0x16A12C
1838#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT3 0x16A52C
1839#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT4 0x16B12C
1840#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT4 0x16B52C
1841#define ICL_PORT_MG_TX1_LINK_PARAMS(port, ln) \
1842 _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT1, \
1843 _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT2, \
1844 _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT1)
1845
1846#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT1 0x1680AC
1847#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT1 0x1684AC
1848#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT2 0x1690AC
1849#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT2 0x1694AC
1850#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT3 0x16A0AC
1851#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT3 0x16A4AC
1852#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT4 0x16B0AC
1853#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT4 0x16B4AC
1854#define ICL_PORT_MG_TX2_LINK_PARAMS(port, ln) \
1855 _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT1, \
1856 _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT2, \
1857 _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT1)
1858#define CRI_USE_FS32 (1 << 5)
1859
1860#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT1 0x16814C
1861#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT1 0x16854C
1862#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT2 0x16914C
1863#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT2 0x16954C
1864#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT3 0x16A14C
1865#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT3 0x16A54C
1866#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT4 0x16B14C
1867#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT4 0x16B54C
1868#define ICL_PORT_MG_TX1_PISO_READLOAD(port, ln) \
1869 _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT1, \
1870 _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT2, \
1871 _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT1)
1872
1873#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT1 0x1680CC
1874#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT1 0x1684CC
1875#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT2 0x1690CC
1876#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT2 0x1694CC
1877#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT3 0x16A0CC
1878#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT3 0x16A4CC
1879#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT4 0x16B0CC
1880#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT4 0x16B4CC
1881#define ICL_PORT_MG_TX2_PISO_READLOAD(port, ln) \
1882 _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT1, \
1883 _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT2, \
1884 _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT1)
1885#define CRI_CALCINIT (1 << 1)
1886
1887#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT1 0x168148
1888#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT1 0x168548
1889#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT2 0x169148
1890#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT2 0x169548
1891#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT3 0x16A148
1892#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT3 0x16A548
1893#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT4 0x16B148
1894#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT4 0x16B548
1895#define ICL_PORT_MG_TX1_SWINGCTRL(port, ln) \
1896 _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT1, \
1897 _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT2, \
1898 _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT1)
1899
1900#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT1 0x1680C8
1901#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT1 0x1684C8
1902#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT2 0x1690C8
1903#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT2 0x1694C8
1904#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT3 0x16A0C8
1905#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT3 0x16A4C8
1906#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT4 0x16B0C8
1907#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT4 0x16B4C8
1908#define ICL_PORT_MG_TX2_SWINGCTRL(port, ln) \
1909 _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT1, \
1910 _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT2, \
1911 _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT1)
1912#define CRI_TXDEEMPH_OVERRIDE_17_12(x) ((x) << 0)
1913#define CRI_TXDEEMPH_OVERRIDE_17_12_MASK (0x3F << 0)
1914
1915#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT1 0x168144
1916#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT1 0x168544
1917#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT2 0x169144
1918#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT2 0x169544
1919#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT3 0x16A144
1920#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT3 0x16A544
1921#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT4 0x16B144
1922#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT4 0x16B544
1923#define ICL_PORT_MG_TX1_DRVCTRL(port, ln) \
1924 _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_DRVCTRL_TX1LN0_PORT1, \
1925 _ICL_MG_TX_DRVCTRL_TX1LN0_PORT2, \
1926 _ICL_MG_TX_DRVCTRL_TX1LN1_PORT1)
1927
1928#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT1 0x1680C4
1929#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT1 0x1684C4
1930#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT2 0x1690C4
1931#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT2 0x1694C4
1932#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT3 0x16A0C4
1933#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT3 0x16A4C4
1934#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT4 0x16B0C4
1935#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT4 0x16B4C4
1936#define ICL_PORT_MG_TX2_DRVCTRL(port, ln) \
1937 _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_DRVCTRL_TX2LN0_PORT1, \
1938 _ICL_MG_TX_DRVCTRL_TX2LN0_PORT2, \
1939 _ICL_MG_TX_DRVCTRL_TX2LN1_PORT1)
1940#define CRI_TXDEEMPH_OVERRIDE_11_6(x) ((x) << 24)
1941#define CRI_TXDEEMPH_OVERRIDE_11_6_MASK (0x3F << 24)
1942#define CRI_TXDEEMPH_OVERRIDE_EN (1 << 22)
1943#define CRI_TXDEEMPH_OVERRIDE_5_0(x) ((x) << 16)
1944#define CRI_TXDEEMPH_OVERRIDE_5_0_MASK (0x3F << 16)
1945
2090/* The spec defines this only for BXT PHY0, but lets assume that this 1946/* The spec defines this only for BXT PHY0, but lets assume that this
2091 * would exist for PHY1 too if it had a second channel. 1947 * would exist for PHY1 too if it had a second channel.
2092 */ 1948 */
@@ -2473,6 +2329,10 @@ enum i915_power_well_id {
2473#define GEN8_MCR_SLICE_MASK GEN8_MCR_SLICE(3) 2329#define GEN8_MCR_SLICE_MASK GEN8_MCR_SLICE(3)
2474#define GEN8_MCR_SUBSLICE(subslice) (((subslice) & 3) << 24) 2330#define GEN8_MCR_SUBSLICE(subslice) (((subslice) & 3) << 24)
2475#define GEN8_MCR_SUBSLICE_MASK GEN8_MCR_SUBSLICE(3) 2331#define GEN8_MCR_SUBSLICE_MASK GEN8_MCR_SUBSLICE(3)
2332#define GEN11_MCR_SLICE(slice) (((slice) & 0xf) << 27)
2333#define GEN11_MCR_SLICE_MASK GEN11_MCR_SLICE(0xf)
2334#define GEN11_MCR_SUBSLICE(subslice) (((subslice) & 0x7) << 24)
2335#define GEN11_MCR_SUBSLICE_MASK GEN11_MCR_SUBSLICE(0x7)
2476#define RING_IPEIR(base) _MMIO((base)+0x64) 2336#define RING_IPEIR(base) _MMIO((base)+0x64)
2477#define RING_IPEHR(base) _MMIO((base)+0x68) 2337#define RING_IPEHR(base) _MMIO((base)+0x68)
2478/* 2338/*
@@ -2867,6 +2727,19 @@ enum i915_power_well_id {
2867#define GEN10_EU_DISABLE3 _MMIO(0x9140) 2727#define GEN10_EU_DISABLE3 _MMIO(0x9140)
2868#define GEN10_EU_DIS_SS_MASK 0xff 2728#define GEN10_EU_DIS_SS_MASK 0xff
2869 2729
2730#define GEN11_GT_VEBOX_VDBOX_DISABLE _MMIO(0x9140)
2731#define GEN11_GT_VDBOX_DISABLE_MASK 0xff
2732#define GEN11_GT_VEBOX_DISABLE_SHIFT 16
2733#define GEN11_GT_VEBOX_DISABLE_MASK (0xff << GEN11_GT_VEBOX_DISABLE_SHIFT)
2734
2735#define GEN11_EU_DISABLE _MMIO(0x9134)
2736#define GEN11_EU_DIS_MASK 0xFF
2737
2738#define GEN11_GT_SLICE_ENABLE _MMIO(0x9138)
2739#define GEN11_GT_S_ENA_MASK 0xFF
2740
2741#define GEN11_GT_SUBSLICE_DISABLE _MMIO(0x913C)
2742
2870#define GEN6_BSD_SLEEP_PSMI_CONTROL _MMIO(0x12050) 2743#define GEN6_BSD_SLEEP_PSMI_CONTROL _MMIO(0x12050)
2871#define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0) 2744#define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0)
2872#define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2) 2745#define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2)
@@ -3951,6 +3824,9 @@ enum {
3951#define _CLKGATE_DIS_PSL_A 0x46520 3824#define _CLKGATE_DIS_PSL_A 0x46520
3952#define _CLKGATE_DIS_PSL_B 0x46524 3825#define _CLKGATE_DIS_PSL_B 0x46524
3953#define _CLKGATE_DIS_PSL_C 0x46528 3826#define _CLKGATE_DIS_PSL_C 0x46528
3827#define DUPS1_GATING_DIS (1 << 15)
3828#define DUPS2_GATING_DIS (1 << 19)
3829#define DUPS3_GATING_DIS (1 << 23)
3954#define DPF_GATING_DIS (1 << 10) 3830#define DPF_GATING_DIS (1 << 10)
3955#define DPF_RAM_GATING_DIS (1 << 9) 3831#define DPF_RAM_GATING_DIS (1 << 9)
3956#define DPFR_GATING_DIS (1 << 8) 3832#define DPFR_GATING_DIS (1 << 8)
@@ -3964,6 +3840,7 @@ enum {
3964#define SLICE_UNIT_LEVEL_CLKGATE _MMIO(0x94d4) 3840#define SLICE_UNIT_LEVEL_CLKGATE _MMIO(0x94d4)
3965#define SARBUNIT_CLKGATE_DIS (1 << 5) 3841#define SARBUNIT_CLKGATE_DIS (1 << 5)
3966#define RCCUNIT_CLKGATE_DIS (1 << 7) 3842#define RCCUNIT_CLKGATE_DIS (1 << 7)
3843#define MSCUNIT_CLKGATE_DIS (1 << 10)
3967 3844
3968#define SUBSLICE_UNIT_LEVEL_CLKGATE _MMIO(0x9524) 3845#define SUBSLICE_UNIT_LEVEL_CLKGATE _MMIO(0x9524)
3969#define GWUNIT_CLKGATE_DIS (1 << 16) 3846#define GWUNIT_CLKGATE_DIS (1 << 16)
@@ -3971,6 +3848,9 @@ enum {
3971#define UNSLICE_UNIT_LEVEL_CLKGATE _MMIO(0x9434) 3848#define UNSLICE_UNIT_LEVEL_CLKGATE _MMIO(0x9434)
3972#define VFUNIT_CLKGATE_DIS (1 << 20) 3849#define VFUNIT_CLKGATE_DIS (1 << 20)
3973 3850
3851#define INF_UNIT_LEVEL_CLKGATE _MMIO(0x9560)
3852#define CGPSF_CLKGATE_DIS (1 << 3)
3853
3974/* 3854/*
3975 * Display engine regs 3855 * Display engine regs
3976 */ 3856 */
@@ -4150,7 +4030,20 @@ enum {
4150#define EDP_PSR_TP1_TIME_0us (3<<4) 4030#define EDP_PSR_TP1_TIME_0us (3<<4)
4151#define EDP_PSR_IDLE_FRAME_SHIFT 0 4031#define EDP_PSR_IDLE_FRAME_SHIFT 0
4152 4032
4033/* Bspec claims those aren't shifted but stay at 0x64800 */
4034#define EDP_PSR_IMR _MMIO(0x64834)
4035#define EDP_PSR_IIR _MMIO(0x64838)
4036#define EDP_PSR_ERROR(trans) (1 << (((trans) * 8 + 10) & 31))
4037#define EDP_PSR_POST_EXIT(trans) (1 << (((trans) * 8 + 9) & 31))
4038#define EDP_PSR_PRE_ENTRY(trans) (1 << (((trans) * 8 + 8) & 31))
4039
4153#define EDP_PSR_AUX_CTL _MMIO(dev_priv->psr_mmio_base + 0x10) 4040#define EDP_PSR_AUX_CTL _MMIO(dev_priv->psr_mmio_base + 0x10)
4041#define EDP_PSR_AUX_CTL_TIME_OUT_MASK (3 << 26)
4042#define EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK (0x1f << 20)
4043#define EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK (0xf << 16)
4044#define EDP_PSR_AUX_CTL_ERROR_INTERRUPT (1 << 11)
4045#define EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK (0x7ff)
4046
4154#define EDP_PSR_AUX_DATA(i) _MMIO(dev_priv->psr_mmio_base + 0x14 + (i) * 4) /* 5 registers */ 4047#define EDP_PSR_AUX_DATA(i) _MMIO(dev_priv->psr_mmio_base + 0x14 + (i) * 4) /* 5 registers */
4155 4048
4156#define EDP_PSR_STATUS _MMIO(dev_priv->psr_mmio_base + 0x40) 4049#define EDP_PSR_STATUS _MMIO(dev_priv->psr_mmio_base + 0x40)
@@ -4180,17 +4073,19 @@ enum {
4180#define EDP_PSR_PERF_CNT _MMIO(dev_priv->psr_mmio_base + 0x44) 4073#define EDP_PSR_PERF_CNT _MMIO(dev_priv->psr_mmio_base + 0x44)
4181#define EDP_PSR_PERF_CNT_MASK 0xffffff 4074#define EDP_PSR_PERF_CNT_MASK 0xffffff
4182 4075
4183#define EDP_PSR_DEBUG _MMIO(dev_priv->psr_mmio_base + 0x60) 4076#define EDP_PSR_DEBUG _MMIO(dev_priv->psr_mmio_base + 0x60) /* PSR_MASK on SKL+ */
4184#define EDP_PSR_DEBUG_MASK_MAX_SLEEP (1<<28) 4077#define EDP_PSR_DEBUG_MASK_MAX_SLEEP (1<<28)
4185#define EDP_PSR_DEBUG_MASK_LPSP (1<<27) 4078#define EDP_PSR_DEBUG_MASK_LPSP (1<<27)
4186#define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) 4079#define EDP_PSR_DEBUG_MASK_MEMUP (1<<26)
4187#define EDP_PSR_DEBUG_MASK_HPD (1<<25) 4080#define EDP_PSR_DEBUG_MASK_HPD (1<<25)
4188#define EDP_PSR_DEBUG_MASK_DISP_REG_WRITE (1<<16) 4081#define EDP_PSR_DEBUG_MASK_DISP_REG_WRITE (1<<16)
4189#define EDP_PSR_DEBUG_EXIT_ON_PIXEL_UNDERRUN (1<<15) 4082#define EDP_PSR_DEBUG_EXIT_ON_PIXEL_UNDERRUN (1<<15) /* SKL+ */
4190 4083
4191#define EDP_PSR2_CTL _MMIO(0x6f900) 4084#define EDP_PSR2_CTL _MMIO(0x6f900)
4192#define EDP_PSR2_ENABLE (1<<31) 4085#define EDP_PSR2_ENABLE (1<<31)
4193#define EDP_SU_TRACK_ENABLE (1<<30) 4086#define EDP_SU_TRACK_ENABLE (1<<30)
4087#define EDP_Y_COORDINATE_VALID (1<<26) /* GLK and CNL+ */
4088#define EDP_Y_COORDINATE_ENABLE (1<<25) /* GLK and CNL+ */
4194#define EDP_MAX_SU_DISABLE_TIME(t) ((t)<<20) 4089#define EDP_MAX_SU_DISABLE_TIME(t) ((t)<<20)
4195#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f<<20) 4090#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f<<20)
4196#define EDP_PSR2_TP2_TIME_500 (0<<8) 4091#define EDP_PSR2_TP2_TIME_500 (0<<8)
@@ -4200,8 +4095,32 @@ enum {
4200#define EDP_PSR2_TP2_TIME_MASK (3<<8) 4095#define EDP_PSR2_TP2_TIME_MASK (3<<8)
4201#define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4 4096#define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4
4202#define EDP_PSR2_FRAME_BEFORE_SU_MASK (0xf<<4) 4097#define EDP_PSR2_FRAME_BEFORE_SU_MASK (0xf<<4)
4203#define EDP_PSR2_IDLE_MASK 0xf
4204#define EDP_PSR2_FRAME_BEFORE_SU(a) ((a)<<4) 4098#define EDP_PSR2_FRAME_BEFORE_SU(a) ((a)<<4)
4099#define EDP_PSR2_IDLE_FRAME_MASK 0xf
4100#define EDP_PSR2_IDLE_FRAME_SHIFT 0
4101
4102#define _PSR_EVENT_TRANS_A 0x60848
4103#define _PSR_EVENT_TRANS_B 0x61848
4104#define _PSR_EVENT_TRANS_C 0x62848
4105#define _PSR_EVENT_TRANS_D 0x63848
4106#define _PSR_EVENT_TRANS_EDP 0x6F848
4107#define PSR_EVENT(trans) _MMIO_TRANS2(trans, _PSR_EVENT_TRANS_A)
4108#define PSR_EVENT_PSR2_WD_TIMER_EXPIRE (1 << 17)
4109#define PSR_EVENT_PSR2_DISABLED (1 << 16)
4110#define PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN (1 << 15)
4111#define PSR_EVENT_SU_CRC_FIFO_UNDERRUN (1 << 14)
4112#define PSR_EVENT_GRAPHICS_RESET (1 << 12)
4113#define PSR_EVENT_PCH_INTERRUPT (1 << 11)
4114#define PSR_EVENT_MEMORY_UP (1 << 10)
4115#define PSR_EVENT_FRONT_BUFFER_MODIFY (1 << 9)
4116#define PSR_EVENT_WD_TIMER_EXPIRE (1 << 8)
4117#define PSR_EVENT_PIPE_REGISTERS_UPDATE (1 << 6)
4118#define PSR_EVENT_REGISTER_UPDATE (1 << 5)
4119#define PSR_EVENT_HDCP_ENABLE (1 << 4)
4120#define PSR_EVENT_KVMR_SESSION_ENABLE (1 << 3)
4121#define PSR_EVENT_VBI_ENABLE (1 << 2)
4122#define PSR_EVENT_LPSP_MODE_EXIT (1 << 1)
4123#define PSR_EVENT_PSR_DISABLE (1 << 0)
4205 4124
4206#define EDP_PSR2_STATUS _MMIO(0x6f940) 4125#define EDP_PSR2_STATUS _MMIO(0x6f940)
4207#define EDP_PSR2_STATUS_STATE_MASK (0xf<<28) 4126#define EDP_PSR2_STATUS_STATE_MASK (0xf<<28)
@@ -5265,8 +5184,6 @@ enum {
5265#define DP_LINK_TRAIN_OFF (3 << 28) 5184#define DP_LINK_TRAIN_OFF (3 << 28)
5266#define DP_LINK_TRAIN_MASK (3 << 28) 5185#define DP_LINK_TRAIN_MASK (3 << 28)
5267#define DP_LINK_TRAIN_SHIFT 28 5186#define DP_LINK_TRAIN_SHIFT 28
5268#define DP_LINK_TRAIN_PAT_3_CHV (1 << 14)
5269#define DP_LINK_TRAIN_MASK_CHV ((3 << 28)|(1<<14))
5270 5187
5271/* CPT Link training mode */ 5188/* CPT Link training mode */
5272#define DP_LINK_TRAIN_PAT_1_CPT (0 << 8) 5189#define DP_LINK_TRAIN_PAT_1_CPT (0 << 8)
@@ -6009,6 +5926,7 @@ enum {
6009#define CURSIZE _MMIO(0x700a0) /* 845/865 */ 5926#define CURSIZE _MMIO(0x700a0) /* 845/865 */
6010#define _CUR_FBC_CTL_A 0x700a0 /* ivb+ */ 5927#define _CUR_FBC_CTL_A 0x700a0 /* ivb+ */
6011#define CUR_FBC_CTL_EN (1 << 31) 5928#define CUR_FBC_CTL_EN (1 << 31)
5929#define _CURASURFLIVE 0x700ac /* g4x+ */
6012#define _CURBCNTR 0x700c0 5930#define _CURBCNTR 0x700c0
6013#define _CURBBASE 0x700c4 5931#define _CURBBASE 0x700c4
6014#define _CURBPOS 0x700c8 5932#define _CURBPOS 0x700c8
@@ -6025,6 +5943,7 @@ enum {
6025#define CURBASE(pipe) _CURSOR2(pipe, _CURABASE) 5943#define CURBASE(pipe) _CURSOR2(pipe, _CURABASE)
6026#define CURPOS(pipe) _CURSOR2(pipe, _CURAPOS) 5944#define CURPOS(pipe) _CURSOR2(pipe, _CURAPOS)
6027#define CUR_FBC_CTL(pipe) _CURSOR2(pipe, _CUR_FBC_CTL_A) 5945#define CUR_FBC_CTL(pipe) _CURSOR2(pipe, _CUR_FBC_CTL_A)
5946#define CURSURFLIVE(pipe) _CURSOR2(pipe, _CURASURFLIVE)
6028 5947
6029#define CURSOR_A_OFFSET 0x70080 5948#define CURSOR_A_OFFSET 0x70080
6030#define CURSOR_B_OFFSET 0x700c0 5949#define CURSOR_B_OFFSET 0x700c0
@@ -6492,9 +6411,9 @@ enum {
6492#define _PLANE_COLOR_CTL_1_A 0x701CC /* GLK+ */ 6411#define _PLANE_COLOR_CTL_1_A 0x701CC /* GLK+ */
6493#define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */ 6412#define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */
6494#define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */ 6413#define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */
6495#define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) 6414#define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) /* Pre-ICL */
6496#define PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE (1 << 28) 6415#define PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE (1 << 28)
6497#define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) 6416#define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) /* Pre-ICL */
6498#define PLANE_COLOR_CSC_MODE_BYPASS (0 << 17) 6417#define PLANE_COLOR_CSC_MODE_BYPASS (0 << 17)
6499#define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709 (1 << 17) 6418#define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709 (1 << 17)
6500#define PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709 (2 << 17) 6419#define PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709 (2 << 17)
@@ -6589,6 +6508,9 @@ enum {
6589 6508
6590#define _PLANE_BUF_CFG_1_B 0x7127c 6509#define _PLANE_BUF_CFG_1_B 0x7127c
6591#define _PLANE_BUF_CFG_2_B 0x7137c 6510#define _PLANE_BUF_CFG_2_B 0x7137c
6511#define SKL_DDB_ENTRY_MASK 0x3FF
6512#define ICL_DDB_ENTRY_MASK 0x7FF
6513#define DDB_ENTRY_END_SHIFT 16
6592#define _PLANE_BUF_CFG_1(pipe) \ 6514#define _PLANE_BUF_CFG_1(pipe) \
6593 _PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B) 6515 _PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B)
6594#define _PLANE_BUF_CFG_2(pipe) \ 6516#define _PLANE_BUF_CFG_2(pipe) \
@@ -6779,6 +6701,8 @@ enum {
6779#define PS_SCALER_MODE_MASK (3 << 28) 6701#define PS_SCALER_MODE_MASK (3 << 28)
6780#define PS_SCALER_MODE_DYN (0 << 28) 6702#define PS_SCALER_MODE_DYN (0 << 28)
6781#define PS_SCALER_MODE_HQ (1 << 28) 6703#define PS_SCALER_MODE_HQ (1 << 28)
6704#define SKL_PS_SCALER_MODE_NV12 (2 << 28)
6705#define PS_SCALER_MODE_PLANAR (1 << 29)
6782#define PS_PLANE_SEL_MASK (7 << 25) 6706#define PS_PLANE_SEL_MASK (7 << 25)
6783#define PS_PLANE_SEL(plane) (((plane) + 1) << 25) 6707#define PS_PLANE_SEL(plane) (((plane) + 1) << 25)
6784#define PS_FILTER_MASK (3 << 23) 6708#define PS_FILTER_MASK (3 << 23)
@@ -6950,6 +6874,7 @@ enum {
6950#define DE_PCH_EVENT_IVB (1<<28) 6874#define DE_PCH_EVENT_IVB (1<<28)
6951#define DE_DP_A_HOTPLUG_IVB (1<<27) 6875#define DE_DP_A_HOTPLUG_IVB (1<<27)
6952#define DE_AUX_CHANNEL_A_IVB (1<<26) 6876#define DE_AUX_CHANNEL_A_IVB (1<<26)
6877#define DE_EDP_PSR_INT_HSW (1<<19)
6953#define DE_SPRITEC_FLIP_DONE_IVB (1<<14) 6878#define DE_SPRITEC_FLIP_DONE_IVB (1<<14)
6954#define DE_PLANEC_FLIP_DONE_IVB (1<<13) 6879#define DE_PLANEC_FLIP_DONE_IVB (1<<13)
6955#define DE_PIPEC_VBLANK_IVB (1<<10) 6880#define DE_PIPEC_VBLANK_IVB (1<<10)
@@ -7074,6 +6999,7 @@ enum {
7074#define GEN8_DE_MISC_IIR _MMIO(0x44468) 6999#define GEN8_DE_MISC_IIR _MMIO(0x44468)
7075#define GEN8_DE_MISC_IER _MMIO(0x4446c) 7000#define GEN8_DE_MISC_IER _MMIO(0x4446c)
7076#define GEN8_DE_MISC_GSE (1 << 27) 7001#define GEN8_DE_MISC_GSE (1 << 27)
7002#define GEN8_DE_EDP_PSR (1 << 19)
7077 7003
7078#define GEN8_PCU_ISR _MMIO(0x444e0) 7004#define GEN8_PCU_ISR _MMIO(0x444e0)
7079#define GEN8_PCU_IMR _MMIO(0x444e4) 7005#define GEN8_PCU_IMR _MMIO(0x444e4)
@@ -7117,7 +7043,9 @@ enum {
7117#define GEN11_INTR_IDENTITY_REG0 _MMIO(0x190060) 7043#define GEN11_INTR_IDENTITY_REG0 _MMIO(0x190060)
7118#define GEN11_INTR_IDENTITY_REG1 _MMIO(0x190064) 7044#define GEN11_INTR_IDENTITY_REG1 _MMIO(0x190064)
7119#define GEN11_INTR_DATA_VALID (1 << 31) 7045#define GEN11_INTR_DATA_VALID (1 << 31)
7120#define GEN11_INTR_ENGINE_MASK (0xffff) 7046#define GEN11_INTR_ENGINE_CLASS(x) (((x) & GENMASK(18, 16)) >> 16)
7047#define GEN11_INTR_ENGINE_INSTANCE(x) (((x) & GENMASK(25, 20)) >> 20)
7048#define GEN11_INTR_ENGINE_INTR(x) ((x) & 0xffff)
7121 7049
7122#define GEN11_INTR_IDENTITY_REG(x) _MMIO(0x190060 + (x * 4)) 7050#define GEN11_INTR_IDENTITY_REG(x) _MMIO(0x190060 + (x * 4))
7123 7051
@@ -7197,6 +7125,7 @@ enum {
7197#define CHICKEN_TRANS_A 0x420c0 7125#define CHICKEN_TRANS_A 0x420c0
7198#define CHICKEN_TRANS_B 0x420c4 7126#define CHICKEN_TRANS_B 0x420c4
7199#define CHICKEN_TRANS(trans) _MMIO_TRANS(trans, CHICKEN_TRANS_A, CHICKEN_TRANS_B) 7127#define CHICKEN_TRANS(trans) _MMIO_TRANS(trans, CHICKEN_TRANS_A, CHICKEN_TRANS_B)
7128#define VSC_DATA_SEL_SOFTWARE_CONTROL (1<<25) /* GLK and CNL+ */
7200#define DDI_TRAINING_OVERRIDE_ENABLE (1<<19) 7129#define DDI_TRAINING_OVERRIDE_ENABLE (1<<19)
7201#define DDI_TRAINING_OVERRIDE_VALUE (1<<18) 7130#define DDI_TRAINING_OVERRIDE_VALUE (1<<18)
7202#define DDIE_TRAINING_OVERRIDE_ENABLE (1<<17) /* CHICKEN_TRANS_A only */ 7131#define DDIE_TRAINING_OVERRIDE_ENABLE (1<<17) /* CHICKEN_TRANS_A only */
@@ -7301,18 +7230,22 @@ enum {
7301#define GEN7_L3CNTLREG3 _MMIO(0xB024) 7230#define GEN7_L3CNTLREG3 _MMIO(0xB024)
7302 7231
7303#define GEN7_L3_CHICKEN_MODE_REGISTER _MMIO(0xB030) 7232#define GEN7_L3_CHICKEN_MODE_REGISTER _MMIO(0xB030)
7304#define GEN7_WA_L3_CHICKEN_MODE 0x20000000 7233#define GEN7_WA_L3_CHICKEN_MODE 0x20000000
7234#define GEN10_L3_CHICKEN_MODE_REGISTER _MMIO(0xB114)
7235#define GEN11_I2M_WRITE_DISABLE (1 << 28)
7305 7236
7306#define GEN7_L3SQCREG4 _MMIO(0xb034) 7237#define GEN7_L3SQCREG4 _MMIO(0xb034)
7307#define L3SQ_URB_READ_CAM_MATCH_DISABLE (1<<27) 7238#define L3SQ_URB_READ_CAM_MATCH_DISABLE (1<<27)
7308 7239
7309#define GEN8_L3SQCREG4 _MMIO(0xb118) 7240#define GEN8_L3SQCREG4 _MMIO(0xb118)
7310#define GEN8_LQSC_RO_PERF_DIS (1<<27) 7241#define GEN11_LQSC_CLEAN_EVICT_DISABLE (1 << 6)
7311#define GEN8_LQSC_FLUSH_COHERENT_LINES (1<<21) 7242#define GEN8_LQSC_RO_PERF_DIS (1 << 27)
7243#define GEN8_LQSC_FLUSH_COHERENT_LINES (1 << 21)
7312 7244
7313/* GEN8 chicken */ 7245/* GEN8 chicken */
7314#define HDC_CHICKEN0 _MMIO(0x7300) 7246#define HDC_CHICKEN0 _MMIO(0x7300)
7315#define CNL_HDC_CHICKEN0 _MMIO(0xE5F0) 7247#define CNL_HDC_CHICKEN0 _MMIO(0xE5F0)
7248#define ICL_HDC_MODE _MMIO(0xE5F4)
7316#define HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE (1<<15) 7249#define HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE (1<<15)
7317#define HDC_FENCE_DEST_SLM_DISABLE (1<<14) 7250#define HDC_FENCE_DEST_SLM_DISABLE (1<<14)
7318#define HDC_DONOT_FETCH_MEM_WHEN_MASKED (1<<11) 7251#define HDC_DONOT_FETCH_MEM_WHEN_MASKED (1<<11)
@@ -8327,8 +8260,30 @@ enum {
8327#define GEN8_DOP_CLOCK_GATE_GUC_ENABLE (1<<4) 8260#define GEN8_DOP_CLOCK_GATE_GUC_ENABLE (1<<4)
8328#define GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE (1<<6) 8261#define GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE (1<<6)
8329 8262
8330#define GEN8_GARBCNTL _MMIO(0xB004) 8263#define GEN8_GARBCNTL _MMIO(0xB004)
8331#define GEN9_GAPS_TSV_CREDIT_DISABLE (1<<7) 8264#define GEN9_GAPS_TSV_CREDIT_DISABLE (1 << 7)
8265#define GEN11_ARBITRATION_PRIO_ORDER_MASK (0x3f << 22)
8266#define GEN11_HASH_CTRL_EXCL_MASK (0x7f << 0)
8267#define GEN11_HASH_CTRL_EXCL_BIT0 (1 << 0)
8268
8269#define GEN11_GLBLINVL _MMIO(0xB404)
8270#define GEN11_BANK_HASH_ADDR_EXCL_MASK (0x7f << 5)
8271#define GEN11_BANK_HASH_ADDR_EXCL_BIT0 (1 << 5)
8272
8273#define GEN10_DFR_RATIO_EN_AND_CHICKEN _MMIO(0x9550)
8274#define DFR_DISABLE (1 << 9)
8275
8276#define GEN11_GACB_PERF_CTRL _MMIO(0x4B80)
8277#define GEN11_HASH_CTRL_MASK (0x3 << 12 | 0xf << 0)
8278#define GEN11_HASH_CTRL_BIT0 (1 << 0)
8279#define GEN11_HASH_CTRL_BIT4 (1 << 12)
8280
8281#define GEN11_LSN_UNSLCVC _MMIO(0xB43C)
8282#define GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC (1 << 9)
8283#define GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC (1 << 7)
8284
8285#define GAMW_ECO_DEV_RW_IA_REG _MMIO(0x4080)
8286#define GAMW_ECO_DEV_CTX_RELOAD_DISABLE (1 << 7)
8332 8287
8333/* IVYBRIDGE DPF */ 8288/* IVYBRIDGE DPF */
8334#define GEN7_L3CDERRST1(slice) _MMIO(0xB008 + (slice) * 0x200) /* L3CD Error Status 1 */ 8289#define GEN7_L3CDERRST1(slice) _MMIO(0xB008 + (slice) * 0x200) /* L3CD Error Status 1 */
@@ -8837,6 +8792,12 @@ enum skl_power_gate {
8837#define PORT_CLK_SEL_NONE (7<<29) 8792#define PORT_CLK_SEL_NONE (7<<29)
8838#define PORT_CLK_SEL_MASK (7<<29) 8793#define PORT_CLK_SEL_MASK (7<<29)
8839 8794
8795/* On ICL+ this is the same as PORT_CLK_SEL, but all bits change. */
8796#define DDI_CLK_SEL(port) PORT_CLK_SEL(port)
8797#define DDI_CLK_SEL_NONE (0x0 << 28)
8798#define DDI_CLK_SEL_MG (0x8 << 28)
8799#define DDI_CLK_SEL_MASK (0xF << 28)
8800
8840/* Transcoder clock selection */ 8801/* Transcoder clock selection */
8841#define _TRANS_CLK_SEL_A 0x46140 8802#define _TRANS_CLK_SEL_A 0x46140
8842#define _TRANS_CLK_SEL_B 0x46144 8803#define _TRANS_CLK_SEL_B 0x46144
@@ -8967,6 +8928,7 @@ enum skl_power_gate {
8967 * CNL Clocks 8928 * CNL Clocks
8968 */ 8929 */
8969#define DPCLKA_CFGCR0 _MMIO(0x6C200) 8930#define DPCLKA_CFGCR0 _MMIO(0x6C200)
8931#define DPCLKA_CFGCR0_ICL _MMIO(0x164280)
8970#define DPCLKA_CFGCR0_DDI_CLK_OFF(port) (1 << ((port) == PORT_F ? 23 : \ 8932#define DPCLKA_CFGCR0_DDI_CLK_OFF(port) (1 << ((port) == PORT_F ? 23 : \
8971 (port)+10)) 8933 (port)+10))
8972#define DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port) ((port) == PORT_F ? 21 : \ 8934#define DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port) ((port) == PORT_F ? 21 : \
@@ -8983,10 +8945,141 @@ enum skl_power_gate {
8983#define PLL_POWER_STATE (1 << 26) 8945#define PLL_POWER_STATE (1 << 26)
8984#define CNL_DPLL_ENABLE(pll) _MMIO_PLL(pll, DPLL0_ENABLE, DPLL1_ENABLE) 8946#define CNL_DPLL_ENABLE(pll) _MMIO_PLL(pll, DPLL0_ENABLE, DPLL1_ENABLE)
8985 8947
8948#define _MG_PLL1_ENABLE 0x46030
8949#define _MG_PLL2_ENABLE 0x46034
8950#define _MG_PLL3_ENABLE 0x46038
8951#define _MG_PLL4_ENABLE 0x4603C
8952/* Bits are the same as DPLL0_ENABLE */
8953#define MG_PLL_ENABLE(port) _MMIO_PORT((port) - PORT_C, _MG_PLL1_ENABLE, \
8954 _MG_PLL2_ENABLE)
8955
8956#define _MG_REFCLKIN_CTL_PORT1 0x16892C
8957#define _MG_REFCLKIN_CTL_PORT2 0x16992C
8958#define _MG_REFCLKIN_CTL_PORT3 0x16A92C
8959#define _MG_REFCLKIN_CTL_PORT4 0x16B92C
8960#define MG_REFCLKIN_CTL_OD_2_MUX(x) ((x) << 8)
8961#define MG_REFCLKIN_CTL(port) _MMIO_PORT((port) - PORT_C, \
8962 _MG_REFCLKIN_CTL_PORT1, \
8963 _MG_REFCLKIN_CTL_PORT2)
8964
8965#define _MG_CLKTOP2_CORECLKCTL1_PORT1 0x1688D8
8966#define _MG_CLKTOP2_CORECLKCTL1_PORT2 0x1698D8
8967#define _MG_CLKTOP2_CORECLKCTL1_PORT3 0x16A8D8
8968#define _MG_CLKTOP2_CORECLKCTL1_PORT4 0x16B8D8
8969#define MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO(x) ((x) << 16)
8970#define MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(x) ((x) << 8)
8971#define MG_CLKTOP2_CORECLKCTL1(port) _MMIO_PORT((port) - PORT_C, \
8972 _MG_CLKTOP2_CORECLKCTL1_PORT1, \
8973 _MG_CLKTOP2_CORECLKCTL1_PORT2)
8974
8975#define _MG_CLKTOP2_HSCLKCTL_PORT1 0x1688D4
8976#define _MG_CLKTOP2_HSCLKCTL_PORT2 0x1698D4
8977#define _MG_CLKTOP2_HSCLKCTL_PORT3 0x16A8D4
8978#define _MG_CLKTOP2_HSCLKCTL_PORT4 0x16B8D4
8979#define MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(x) ((x) << 16)
8980#define MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x) ((x) << 14)
8981#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(x) ((x) << 12)
8982#define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x) ((x) << 8)
8983#define MG_CLKTOP2_HSCLKCTL(port) _MMIO_PORT((port) - PORT_C, \
8984 _MG_CLKTOP2_HSCLKCTL_PORT1, \
8985 _MG_CLKTOP2_HSCLKCTL_PORT2)
8986
8987#define _MG_PLL_DIV0_PORT1 0x168A00
8988#define _MG_PLL_DIV0_PORT2 0x169A00
8989#define _MG_PLL_DIV0_PORT3 0x16AA00
8990#define _MG_PLL_DIV0_PORT4 0x16BA00
8991#define MG_PLL_DIV0_FRACNEN_H (1 << 30)
8992#define MG_PLL_DIV0_FBDIV_FRAC(x) ((x) << 8)
8993#define MG_PLL_DIV0_FBDIV_INT(x) ((x) << 0)
8994#define MG_PLL_DIV0(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV0_PORT1, \
8995 _MG_PLL_DIV0_PORT2)
8996
8997#define _MG_PLL_DIV1_PORT1 0x168A04
8998#define _MG_PLL_DIV1_PORT2 0x169A04
8999#define _MG_PLL_DIV1_PORT3 0x16AA04
9000#define _MG_PLL_DIV1_PORT4 0x16BA04
9001#define MG_PLL_DIV1_IREF_NDIVRATIO(x) ((x) << 16)
9002#define MG_PLL_DIV1_DITHER_DIV_1 (0 << 12)
9003#define MG_PLL_DIV1_DITHER_DIV_2 (1 << 12)
9004#define MG_PLL_DIV1_DITHER_DIV_4 (2 << 12)
9005#define MG_PLL_DIV1_DITHER_DIV_8 (3 << 12)
9006#define MG_PLL_DIV1_NDIVRATIO(x) ((x) << 4)
9007#define MG_PLL_DIV1_FBPREDIV(x) ((x) << 0)
9008#define MG_PLL_DIV1(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV1_PORT1, \
9009 _MG_PLL_DIV1_PORT2)
9010
9011#define _MG_PLL_LF_PORT1 0x168A08
9012#define _MG_PLL_LF_PORT2 0x169A08
9013#define _MG_PLL_LF_PORT3 0x16AA08
9014#define _MG_PLL_LF_PORT4 0x16BA08
9015#define MG_PLL_LF_TDCTARGETCNT(x) ((x) << 24)
9016#define MG_PLL_LF_AFCCNTSEL_256 (0 << 20)
9017#define MG_PLL_LF_AFCCNTSEL_512 (1 << 20)
9018#define MG_PLL_LF_GAINCTRL(x) ((x) << 16)
9019#define MG_PLL_LF_INT_COEFF(x) ((x) << 8)
9020#define MG_PLL_LF_PROP_COEFF(x) ((x) << 0)
9021#define MG_PLL_LF(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_LF_PORT1, \
9022 _MG_PLL_LF_PORT2)
9023
9024#define _MG_PLL_FRAC_LOCK_PORT1 0x168A0C
9025#define _MG_PLL_FRAC_LOCK_PORT2 0x169A0C
9026#define _MG_PLL_FRAC_LOCK_PORT3 0x16AA0C
9027#define _MG_PLL_FRAC_LOCK_PORT4 0x16BA0C
9028#define MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32 (1 << 18)
9029#define MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32 (1 << 16)
9030#define MG_PLL_FRAC_LOCK_LOCKTHRESH(x) ((x) << 11)
9031#define MG_PLL_FRAC_LOCK_DCODITHEREN (1 << 10)
9032#define MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN (1 << 8)
9033#define MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(x) ((x) << 0)
9034#define MG_PLL_FRAC_LOCK(port) _MMIO_PORT((port) - PORT_C, \
9035 _MG_PLL_FRAC_LOCK_PORT1, \
9036 _MG_PLL_FRAC_LOCK_PORT2)
9037
9038#define _MG_PLL_SSC_PORT1 0x168A10
9039#define _MG_PLL_SSC_PORT2 0x169A10
9040#define _MG_PLL_SSC_PORT3 0x16AA10
9041#define _MG_PLL_SSC_PORT4 0x16BA10
9042#define MG_PLL_SSC_EN (1 << 28)
9043#define MG_PLL_SSC_TYPE(x) ((x) << 26)
9044#define MG_PLL_SSC_STEPLENGTH(x) ((x) << 16)
9045#define MG_PLL_SSC_STEPNUM(x) ((x) << 10)
9046#define MG_PLL_SSC_FLLEN (1 << 9)
9047#define MG_PLL_SSC_STEPSIZE(x) ((x) << 0)
9048#define MG_PLL_SSC(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_SSC_PORT1, \
9049 _MG_PLL_SSC_PORT2)
9050
9051#define _MG_PLL_BIAS_PORT1 0x168A14
9052#define _MG_PLL_BIAS_PORT2 0x169A14
9053#define _MG_PLL_BIAS_PORT3 0x16AA14
9054#define _MG_PLL_BIAS_PORT4 0x16BA14
9055#define MG_PLL_BIAS_BIAS_GB_SEL(x) ((x) << 30)
9056#define MG_PLL_BIAS_INIT_DCOAMP(x) ((x) << 24)
9057#define MG_PLL_BIAS_BIAS_BONUS(x) ((x) << 16)
9058#define MG_PLL_BIAS_BIASCAL_EN (1 << 15)
9059#define MG_PLL_BIAS_CTRIM(x) ((x) << 8)
9060#define MG_PLL_BIAS_VREF_RDAC(x) ((x) << 5)
9061#define MG_PLL_BIAS_IREFTRIM(x) ((x) << 0)
9062#define MG_PLL_BIAS(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_BIAS_PORT1, \
9063 _MG_PLL_BIAS_PORT2)
9064
9065#define _MG_PLL_TDC_COLDST_BIAS_PORT1 0x168A18
9066#define _MG_PLL_TDC_COLDST_BIAS_PORT2 0x169A18
9067#define _MG_PLL_TDC_COLDST_BIAS_PORT3 0x16AA18
9068#define _MG_PLL_TDC_COLDST_BIAS_PORT4 0x16BA18
9069#define MG_PLL_TDC_COLDST_IREFINT_EN (1 << 27)
9070#define MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(x) ((x) << 17)
9071#define MG_PLL_TDC_COLDST_COLDSTART (1 << 16)
9072#define MG_PLL_TDC_TDCOVCCORR_EN (1 << 2)
9073#define MG_PLL_TDC_TDCSEL(x) ((x) << 0)
9074#define MG_PLL_TDC_COLDST_BIAS(port) _MMIO_PORT((port) - PORT_C, \
9075 _MG_PLL_TDC_COLDST_BIAS_PORT1, \
9076 _MG_PLL_TDC_COLDST_BIAS_PORT2)
9077
8986#define _CNL_DPLL0_CFGCR0 0x6C000 9078#define _CNL_DPLL0_CFGCR0 0x6C000
8987#define _CNL_DPLL1_CFGCR0 0x6C080 9079#define _CNL_DPLL1_CFGCR0 0x6C080
8988#define DPLL_CFGCR0_HDMI_MODE (1 << 30) 9080#define DPLL_CFGCR0_HDMI_MODE (1 << 30)
8989#define DPLL_CFGCR0_SSC_ENABLE (1 << 29) 9081#define DPLL_CFGCR0_SSC_ENABLE (1 << 29)
9082#define DPLL_CFGCR0_SSC_ENABLE_ICL (1 << 25)
8990#define DPLL_CFGCR0_LINK_RATE_MASK (0xf << 25) 9083#define DPLL_CFGCR0_LINK_RATE_MASK (0xf << 25)
8991#define DPLL_CFGCR0_LINK_RATE_2700 (0 << 25) 9084#define DPLL_CFGCR0_LINK_RATE_2700 (0 << 25)
8992#define DPLL_CFGCR0_LINK_RATE_1350 (1 << 25) 9085#define DPLL_CFGCR0_LINK_RATE_1350 (1 << 25)
@@ -9020,8 +9113,19 @@ enum skl_power_gate {
9020#define DPLL_CFGCR1_PDIV_5 (4 << 2) 9113#define DPLL_CFGCR1_PDIV_5 (4 << 2)
9021#define DPLL_CFGCR1_PDIV_7 (8 << 2) 9114#define DPLL_CFGCR1_PDIV_7 (8 << 2)
9022#define DPLL_CFGCR1_CENTRAL_FREQ (3 << 0) 9115#define DPLL_CFGCR1_CENTRAL_FREQ (3 << 0)
9116#define DPLL_CFGCR1_CENTRAL_FREQ_8400 (3 << 0)
9023#define CNL_DPLL_CFGCR1(pll) _MMIO_PLL(pll, _CNL_DPLL0_CFGCR1, _CNL_DPLL1_CFGCR1) 9117#define CNL_DPLL_CFGCR1(pll) _MMIO_PLL(pll, _CNL_DPLL0_CFGCR1, _CNL_DPLL1_CFGCR1)
9024 9118
9119#define _ICL_DPLL0_CFGCR0 0x164000
9120#define _ICL_DPLL1_CFGCR0 0x164080
9121#define ICL_DPLL_CFGCR0(pll) _MMIO_PLL(pll, _ICL_DPLL0_CFGCR0, \
9122 _ICL_DPLL1_CFGCR0)
9123
9124#define _ICL_DPLL0_CFGCR1 0x164004
9125#define _ICL_DPLL1_CFGCR1 0x164084
9126#define ICL_DPLL_CFGCR1(pll) _MMIO_PLL(pll, _ICL_DPLL0_CFGCR1, \
9127 _ICL_DPLL1_CFGCR1)
9128
9025/* BXT display engine PLL */ 9129/* BXT display engine PLL */
9026#define BXT_DE_PLL_CTL _MMIO(0x6d000) 9130#define BXT_DE_PLL_CTL _MMIO(0x6d000)
9027#define BXT_DE_PLL_RATIO(x) (x) /* {60,65,100} * 19.2MHz */ 9131#define BXT_DE_PLL_RATIO(x) (x) /* {60,65,100} * 19.2MHz */
@@ -9793,6 +9897,13 @@ enum skl_power_gate {
9793#define GEN9_MFX1_MOCS(i) _MMIO(0xca00 + (i) * 4) /* Media 1 MOCS registers */ 9897#define GEN9_MFX1_MOCS(i) _MMIO(0xca00 + (i) * 4) /* Media 1 MOCS registers */
9794#define GEN9_VEBOX_MOCS(i) _MMIO(0xcb00 + (i) * 4) /* Video MOCS registers */ 9898#define GEN9_VEBOX_MOCS(i) _MMIO(0xcb00 + (i) * 4) /* Video MOCS registers */
9795#define GEN9_BLT_MOCS(i) _MMIO(0xcc00 + (i) * 4) /* Blitter MOCS registers */ 9899#define GEN9_BLT_MOCS(i) _MMIO(0xcc00 + (i) * 4) /* Blitter MOCS registers */
9900/* Media decoder 2 MOCS registers */
9901#define GEN11_MFX2_MOCS(i) _MMIO(0x10000 + (i) * 4)
9902
9903#define GEN10_SCRATCH_LNCF2 _MMIO(0xb0a0)
9904#define PMFLUSHDONE_LNICRSDROP (1 << 20)
9905#define PMFLUSH_GAPL3UNBLOCK (1 << 21)
9906#define PMFLUSHDONE_LNEBLK (1 << 22)
9796 9907
9797/* gamt regs */ 9908/* gamt regs */
9798#define GEN8_L3_LRA_1_GPGPU _MMIO(0x4dd4) 9909#define GEN8_L3_LRA_1_GPGPU _MMIO(0x4dd4)
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 282f57630cc1..8928894dd9c7 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -49,7 +49,7 @@ static const char *i915_fence_get_timeline_name(struct dma_fence *fence)
49 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) 49 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
50 return "signaled"; 50 return "signaled";
51 51
52 return to_request(fence)->timeline->common->name; 52 return to_request(fence)->timeline->name;
53} 53}
54 54
55static bool i915_fence_signaled(struct dma_fence *fence) 55static bool i915_fence_signaled(struct dma_fence *fence)
@@ -59,11 +59,7 @@ static bool i915_fence_signaled(struct dma_fence *fence)
59 59
60static bool i915_fence_enable_signaling(struct dma_fence *fence) 60static bool i915_fence_enable_signaling(struct dma_fence *fence)
61{ 61{
62 if (i915_fence_signaled(fence)) 62 return intel_engine_enable_signaling(to_request(fence), true);
63 return false;
64
65 intel_engine_enable_signaling(to_request(fence), true);
66 return !i915_fence_signaled(fence);
67} 63}
68 64
69static signed long i915_fence_wait(struct dma_fence *fence, 65static signed long i915_fence_wait(struct dma_fence *fence,
@@ -129,22 +125,22 @@ i915_dependency_free(struct drm_i915_private *i915,
129} 125}
130 126
131static void 127static void
132__i915_priotree_add_dependency(struct i915_priotree *pt, 128__i915_sched_node_add_dependency(struct i915_sched_node *node,
133 struct i915_priotree *signal, 129 struct i915_sched_node *signal,
134 struct i915_dependency *dep, 130 struct i915_dependency *dep,
135 unsigned long flags) 131 unsigned long flags)
136{ 132{
137 INIT_LIST_HEAD(&dep->dfs_link); 133 INIT_LIST_HEAD(&dep->dfs_link);
138 list_add(&dep->wait_link, &signal->waiters_list); 134 list_add(&dep->wait_link, &signal->waiters_list);
139 list_add(&dep->signal_link, &pt->signalers_list); 135 list_add(&dep->signal_link, &node->signalers_list);
140 dep->signaler = signal; 136 dep->signaler = signal;
141 dep->flags = flags; 137 dep->flags = flags;
142} 138}
143 139
144static int 140static int
145i915_priotree_add_dependency(struct drm_i915_private *i915, 141i915_sched_node_add_dependency(struct drm_i915_private *i915,
146 struct i915_priotree *pt, 142 struct i915_sched_node *node,
147 struct i915_priotree *signal) 143 struct i915_sched_node *signal)
148{ 144{
149 struct i915_dependency *dep; 145 struct i915_dependency *dep;
150 146
@@ -152,16 +148,18 @@ i915_priotree_add_dependency(struct drm_i915_private *i915,
152 if (!dep) 148 if (!dep)
153 return -ENOMEM; 149 return -ENOMEM;
154 150
155 __i915_priotree_add_dependency(pt, signal, dep, I915_DEPENDENCY_ALLOC); 151 __i915_sched_node_add_dependency(node, signal, dep,
152 I915_DEPENDENCY_ALLOC);
156 return 0; 153 return 0;
157} 154}
158 155
159static void 156static void
160i915_priotree_fini(struct drm_i915_private *i915, struct i915_priotree *pt) 157i915_sched_node_fini(struct drm_i915_private *i915,
158 struct i915_sched_node *node)
161{ 159{
162 struct i915_dependency *dep, *next; 160 struct i915_dependency *dep, *tmp;
163 161
164 GEM_BUG_ON(!list_empty(&pt->link)); 162 GEM_BUG_ON(!list_empty(&node->link));
165 163
166 /* 164 /*
167 * Everyone we depended upon (the fences we wait to be signaled) 165 * Everyone we depended upon (the fences we wait to be signaled)
@@ -169,8 +167,8 @@ i915_priotree_fini(struct drm_i915_private *i915, struct i915_priotree *pt)
169 * However, retirement is run independently on each timeline and 167 * However, retirement is run independently on each timeline and
170 * so we may be called out-of-order. 168 * so we may be called out-of-order.
171 */ 169 */
172 list_for_each_entry_safe(dep, next, &pt->signalers_list, signal_link) { 170 list_for_each_entry_safe(dep, tmp, &node->signalers_list, signal_link) {
173 GEM_BUG_ON(!i915_priotree_signaled(dep->signaler)); 171 GEM_BUG_ON(!i915_sched_node_signaled(dep->signaler));
174 GEM_BUG_ON(!list_empty(&dep->dfs_link)); 172 GEM_BUG_ON(!list_empty(&dep->dfs_link));
175 173
176 list_del(&dep->wait_link); 174 list_del(&dep->wait_link);
@@ -179,8 +177,8 @@ i915_priotree_fini(struct drm_i915_private *i915, struct i915_priotree *pt)
179 } 177 }
180 178
181 /* Remove ourselves from everyone who depends upon us */ 179 /* Remove ourselves from everyone who depends upon us */
182 list_for_each_entry_safe(dep, next, &pt->waiters_list, wait_link) { 180 list_for_each_entry_safe(dep, tmp, &node->waiters_list, wait_link) {
183 GEM_BUG_ON(dep->signaler != pt); 181 GEM_BUG_ON(dep->signaler != node);
184 GEM_BUG_ON(!list_empty(&dep->dfs_link)); 182 GEM_BUG_ON(!list_empty(&dep->dfs_link));
185 183
186 list_del(&dep->signal_link); 184 list_del(&dep->signal_link);
@@ -190,17 +188,18 @@ i915_priotree_fini(struct drm_i915_private *i915, struct i915_priotree *pt)
190} 188}
191 189
192static void 190static void
193i915_priotree_init(struct i915_priotree *pt) 191i915_sched_node_init(struct i915_sched_node *node)
194{ 192{
195 INIT_LIST_HEAD(&pt->signalers_list); 193 INIT_LIST_HEAD(&node->signalers_list);
196 INIT_LIST_HEAD(&pt->waiters_list); 194 INIT_LIST_HEAD(&node->waiters_list);
197 INIT_LIST_HEAD(&pt->link); 195 INIT_LIST_HEAD(&node->link);
198 pt->priority = I915_PRIORITY_INVALID; 196 node->attr.priority = I915_PRIORITY_INVALID;
199} 197}
200 198
201static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno) 199static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
202{ 200{
203 struct intel_engine_cs *engine; 201 struct intel_engine_cs *engine;
202 struct i915_timeline *timeline;
204 enum intel_engine_id id; 203 enum intel_engine_id id;
205 int ret; 204 int ret;
206 205
@@ -211,30 +210,37 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
211 if (ret) 210 if (ret)
212 return ret; 211 return ret;
213 212
213 GEM_BUG_ON(i915->gt.active_requests);
214
214 /* If the seqno wraps around, we need to clear the breadcrumb rbtree */ 215 /* If the seqno wraps around, we need to clear the breadcrumb rbtree */
215 for_each_engine(engine, i915, id) { 216 for_each_engine(engine, i915, id) {
216 struct i915_gem_timeline *timeline; 217 GEM_TRACE("%s seqno %d (current %d) -> %d\n",
217 struct intel_timeline *tl = engine->timeline; 218 engine->name,
219 engine->timeline.seqno,
220 intel_engine_get_seqno(engine),
221 seqno);
218 222
219 if (!i915_seqno_passed(seqno, tl->seqno)) { 223 if (!i915_seqno_passed(seqno, engine->timeline.seqno)) {
220 /* Flush any waiters before we reuse the seqno */ 224 /* Flush any waiters before we reuse the seqno */
221 intel_engine_disarm_breadcrumbs(engine); 225 intel_engine_disarm_breadcrumbs(engine);
226 intel_engine_init_hangcheck(engine);
222 GEM_BUG_ON(!list_empty(&engine->breadcrumbs.signals)); 227 GEM_BUG_ON(!list_empty(&engine->breadcrumbs.signals));
223 } 228 }
224 229
225 /* Check we are idle before we fiddle with hw state! */ 230 /* Check we are idle before we fiddle with hw state! */
226 GEM_BUG_ON(!intel_engine_is_idle(engine)); 231 GEM_BUG_ON(!intel_engine_is_idle(engine));
227 GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request)); 232 GEM_BUG_ON(i915_gem_active_isset(&engine->timeline.last_request));
228 233
229 /* Finally reset hw state */ 234 /* Finally reset hw state */
230 intel_engine_init_global_seqno(engine, seqno); 235 intel_engine_init_global_seqno(engine, seqno);
231 tl->seqno = seqno; 236 engine->timeline.seqno = seqno;
232
233 list_for_each_entry(timeline, &i915->gt.timelines, link)
234 memset(timeline->engine[id].global_sync, 0,
235 sizeof(timeline->engine[id].global_sync));
236 } 237 }
237 238
239 list_for_each_entry(timeline, &i915->gt.timelines, link)
240 memset(timeline->global_sync, 0, sizeof(timeline->global_sync));
241
242 i915->gt.request_serial = seqno;
243
238 return 0; 244 return 0;
239} 245}
240 246
@@ -251,83 +257,37 @@ int i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno)
251 return reset_all_global_seqno(i915, seqno - 1); 257 return reset_all_global_seqno(i915, seqno - 1);
252} 258}
253 259
254static void mark_busy(struct drm_i915_private *i915) 260static int reserve_gt(struct drm_i915_private *i915)
255{ 261{
256 if (i915->gt.awake) 262 int ret;
257 return;
258
259 GEM_BUG_ON(!i915->gt.active_requests);
260
261 intel_runtime_pm_get_noresume(i915);
262 263
263 /* 264 /*
264 * It seems that the DMC likes to transition between the DC states a lot 265 * Reservation is fine until we may need to wrap around
265 * when there are no connected displays (no active power domains) during
266 * command submission.
267 *
268 * This activity has negative impact on the performance of the chip with
269 * huge latencies observed in the interrupt handler and elsewhere.
270 * 266 *
271 * Work around it by grabbing a GT IRQ power domain whilst there is any 267 * By incrementing the serial for every request, we know that no
272 * GT activity, preventing any DC state transitions. 268 * individual engine may exceed that serial (as each is reset to 0
269 * on any wrap). This protects even the most pessimistic of migrations
270 * of every request from all engines onto just one.
273 */ 271 */
274 intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ); 272 while (unlikely(++i915->gt.request_serial == 0)) {
275
276 i915->gt.awake = true;
277 if (unlikely(++i915->gt.epoch == 0)) /* keep 0 as invalid */
278 i915->gt.epoch = 1;
279
280 intel_enable_gt_powersave(i915);
281 i915_update_gfx_val(i915);
282 if (INTEL_GEN(i915) >= 6)
283 gen6_rps_busy(i915);
284 i915_pmu_gt_unparked(i915);
285
286 intel_engines_unpark(i915);
287
288 i915_queue_hangcheck(i915);
289
290 queue_delayed_work(i915->wq,
291 &i915->gt.retire_work,
292 round_jiffies_up_relative(HZ));
293}
294
295static int reserve_engine(struct intel_engine_cs *engine)
296{
297 struct drm_i915_private *i915 = engine->i915;
298 u32 active = ++engine->timeline->inflight_seqnos;
299 u32 seqno = engine->timeline->seqno;
300 int ret;
301
302 /* Reservation is fine until we need to wrap around */
303 if (unlikely(add_overflows(seqno, active))) {
304 ret = reset_all_global_seqno(i915, 0); 273 ret = reset_all_global_seqno(i915, 0);
305 if (ret) { 274 if (ret) {
306 engine->timeline->inflight_seqnos--; 275 i915->gt.request_serial--;
307 return ret; 276 return ret;
308 } 277 }
309 } 278 }
310 279
311 if (!i915->gt.active_requests++) 280 if (!i915->gt.active_requests++)
312 mark_busy(i915); 281 i915_gem_unpark(i915);
313 282
314 return 0; 283 return 0;
315} 284}
316 285
317static void unreserve_engine(struct intel_engine_cs *engine) 286static void unreserve_gt(struct drm_i915_private *i915)
318{ 287{
319 struct drm_i915_private *i915 = engine->i915; 288 GEM_BUG_ON(!i915->gt.active_requests);
320 289 if (!--i915->gt.active_requests)
321 if (!--i915->gt.active_requests) { 290 i915_gem_park(i915);
322 /* Cancel the mark_busy() from our reserve_engine() */
323 GEM_BUG_ON(!i915->gt.awake);
324 mod_delayed_work(i915->wq,
325 &i915->gt.idle_work,
326 msecs_to_jiffies(100));
327 }
328
329 GEM_BUG_ON(!engine->timeline->inflight_seqnos);
330 engine->timeline->inflight_seqnos--;
331} 291}
332 292
333void i915_gem_retire_noop(struct i915_gem_active *active, 293void i915_gem_retire_noop(struct i915_gem_active *active,
@@ -338,6 +298,7 @@ void i915_gem_retire_noop(struct i915_gem_active *active,
338 298
339static void advance_ring(struct i915_request *request) 299static void advance_ring(struct i915_request *request)
340{ 300{
301 struct intel_ring *ring = request->ring;
341 unsigned int tail; 302 unsigned int tail;
342 303
343 /* 304 /*
@@ -349,7 +310,8 @@ static void advance_ring(struct i915_request *request)
349 * Note this requires that we are always called in request 310 * Note this requires that we are always called in request
350 * completion order. 311 * completion order.
351 */ 312 */
352 if (list_is_last(&request->ring_link, &request->ring->request_list)) { 313 GEM_BUG_ON(!list_is_first(&request->ring_link, &ring->request_list));
314 if (list_is_last(&request->ring_link, &ring->request_list)) {
353 /* 315 /*
354 * We may race here with execlists resubmitting this request 316 * We may race here with execlists resubmitting this request
355 * as we retire it. The resubmission will move the ring->tail 317 * as we retire it. The resubmission will move the ring->tail
@@ -358,13 +320,14 @@ static void advance_ring(struct i915_request *request)
358 * is just about to be. Either works, if we miss the last two 320 * is just about to be. Either works, if we miss the last two
359 * noops - they are safe to be replayed on a reset. 321 * noops - they are safe to be replayed on a reset.
360 */ 322 */
361 tail = READ_ONCE(request->ring->tail); 323 tail = READ_ONCE(request->tail);
324 list_del(&ring->active_link);
362 } else { 325 } else {
363 tail = request->postfix; 326 tail = request->postfix;
364 } 327 }
365 list_del(&request->ring_link); 328 list_del_init(&request->ring_link);
366 329
367 request->ring->head = tail; 330 ring->head = tail;
368} 331}
369 332
370static void free_capture_list(struct i915_request *request) 333static void free_capture_list(struct i915_request *request)
@@ -380,25 +343,84 @@ static void free_capture_list(struct i915_request *request)
380 } 343 }
381} 344}
382 345
346static void __retire_engine_request(struct intel_engine_cs *engine,
347 struct i915_request *rq)
348{
349 GEM_TRACE("%s(%s) fence %llx:%d, global=%d, current %d\n",
350 __func__, engine->name,
351 rq->fence.context, rq->fence.seqno,
352 rq->global_seqno,
353 intel_engine_get_seqno(engine));
354
355 GEM_BUG_ON(!i915_request_completed(rq));
356
357 local_irq_disable();
358
359 spin_lock(&engine->timeline.lock);
360 GEM_BUG_ON(!list_is_first(&rq->link, &engine->timeline.requests));
361 list_del_init(&rq->link);
362 spin_unlock(&engine->timeline.lock);
363
364 spin_lock(&rq->lock);
365 if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags))
366 dma_fence_signal_locked(&rq->fence);
367 if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &rq->fence.flags))
368 intel_engine_cancel_signaling(rq);
369 if (rq->waitboost) {
370 GEM_BUG_ON(!atomic_read(&rq->i915->gt_pm.rps.num_waiters));
371 atomic_dec(&rq->i915->gt_pm.rps.num_waiters);
372 }
373 spin_unlock(&rq->lock);
374
375 local_irq_enable();
376
377 /*
378 * The backing object for the context is done after switching to the
379 * *next* context. Therefore we cannot retire the previous context until
380 * the next context has already started running. However, since we
381 * cannot take the required locks at i915_request_submit() we
382 * defer the unpinning of the active context to now, retirement of
383 * the subsequent request.
384 */
385 if (engine->last_retired_context)
386 intel_context_unpin(engine->last_retired_context, engine);
387 engine->last_retired_context = rq->ctx;
388}
389
390static void __retire_engine_upto(struct intel_engine_cs *engine,
391 struct i915_request *rq)
392{
393 struct i915_request *tmp;
394
395 if (list_empty(&rq->link))
396 return;
397
398 do {
399 tmp = list_first_entry(&engine->timeline.requests,
400 typeof(*tmp), link);
401
402 GEM_BUG_ON(tmp->engine != engine);
403 __retire_engine_request(engine, tmp);
404 } while (tmp != rq);
405}
406
383static void i915_request_retire(struct i915_request *request) 407static void i915_request_retire(struct i915_request *request)
384{ 408{
385 struct intel_engine_cs *engine = request->engine;
386 struct i915_gem_active *active, *next; 409 struct i915_gem_active *active, *next;
387 410
411 GEM_TRACE("%s fence %llx:%d, global=%d, current %d\n",
412 request->engine->name,
413 request->fence.context, request->fence.seqno,
414 request->global_seqno,
415 intel_engine_get_seqno(request->engine));
416
388 lockdep_assert_held(&request->i915->drm.struct_mutex); 417 lockdep_assert_held(&request->i915->drm.struct_mutex);
389 GEM_BUG_ON(!i915_sw_fence_signaled(&request->submit)); 418 GEM_BUG_ON(!i915_sw_fence_signaled(&request->submit));
390 GEM_BUG_ON(!i915_request_completed(request)); 419 GEM_BUG_ON(!i915_request_completed(request));
391 GEM_BUG_ON(!request->i915->gt.active_requests);
392 420
393 trace_i915_request_retire(request); 421 trace_i915_request_retire(request);
394 422
395 spin_lock_irq(&engine->timeline->lock);
396 list_del_init(&request->link);
397 spin_unlock_irq(&engine->timeline->lock);
398
399 unreserve_engine(request->engine);
400 advance_ring(request); 423 advance_ring(request);
401
402 free_capture_list(request); 424 free_capture_list(request);
403 425
404 /* 426 /*
@@ -434,73 +456,74 @@ static void i915_request_retire(struct i915_request *request)
434 456
435 /* Retirement decays the ban score as it is a sign of ctx progress */ 457 /* Retirement decays the ban score as it is a sign of ctx progress */
436 atomic_dec_if_positive(&request->ctx->ban_score); 458 atomic_dec_if_positive(&request->ctx->ban_score);
459 intel_context_unpin(request->ctx, request->engine);
437 460
438 /* 461 __retire_engine_upto(request->engine, request);
439 * The backing object for the context is done after switching to the
440 * *next* context. Therefore we cannot retire the previous context until
441 * the next context has already started running. However, since we
442 * cannot take the required locks at i915_request_submit() we
443 * defer the unpinning of the active context to now, retirement of
444 * the subsequent request.
445 */
446 if (engine->last_retired_context)
447 engine->context_unpin(engine, engine->last_retired_context);
448 engine->last_retired_context = request->ctx;
449 462
450 spin_lock_irq(&request->lock); 463 unreserve_gt(request->i915);
451 if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags))
452 dma_fence_signal_locked(&request->fence);
453 if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
454 intel_engine_cancel_signaling(request);
455 if (request->waitboost) {
456 GEM_BUG_ON(!atomic_read(&request->i915->gt_pm.rps.num_waiters));
457 atomic_dec(&request->i915->gt_pm.rps.num_waiters);
458 }
459 spin_unlock_irq(&request->lock);
460 464
461 i915_priotree_fini(request->i915, &request->priotree); 465 i915_sched_node_fini(request->i915, &request->sched);
462 i915_request_put(request); 466 i915_request_put(request);
463} 467}
464 468
465void i915_request_retire_upto(struct i915_request *rq) 469void i915_request_retire_upto(struct i915_request *rq)
466{ 470{
467 struct intel_engine_cs *engine = rq->engine; 471 struct intel_ring *ring = rq->ring;
468 struct i915_request *tmp; 472 struct i915_request *tmp;
469 473
474 GEM_TRACE("%s fence %llx:%d, global=%d, current %d\n",
475 rq->engine->name,
476 rq->fence.context, rq->fence.seqno,
477 rq->global_seqno,
478 intel_engine_get_seqno(rq->engine));
479
470 lockdep_assert_held(&rq->i915->drm.struct_mutex); 480 lockdep_assert_held(&rq->i915->drm.struct_mutex);
471 GEM_BUG_ON(!i915_request_completed(rq)); 481 GEM_BUG_ON(!i915_request_completed(rq));
472 482
473 if (list_empty(&rq->link)) 483 if (list_empty(&rq->ring_link))
474 return; 484 return;
475 485
476 do { 486 do {
477 tmp = list_first_entry(&engine->timeline->requests, 487 tmp = list_first_entry(&ring->request_list,
478 typeof(*tmp), link); 488 typeof(*tmp), ring_link);
479 489
480 i915_request_retire(tmp); 490 i915_request_retire(tmp);
481 } while (tmp != rq); 491 } while (tmp != rq);
482} 492}
483 493
484static u32 timeline_get_seqno(struct intel_timeline *tl) 494static u32 timeline_get_seqno(struct i915_timeline *tl)
485{ 495{
486 return ++tl->seqno; 496 return ++tl->seqno;
487} 497}
488 498
499static void move_to_timeline(struct i915_request *request,
500 struct i915_timeline *timeline)
501{
502 GEM_BUG_ON(request->timeline == &request->engine->timeline);
503 lockdep_assert_held(&request->engine->timeline.lock);
504
505 spin_lock_nested(&request->timeline->lock, SINGLE_DEPTH_NESTING);
506 list_move_tail(&request->link, &timeline->requests);
507 spin_unlock(&request->timeline->lock);
508}
509
489void __i915_request_submit(struct i915_request *request) 510void __i915_request_submit(struct i915_request *request)
490{ 511{
491 struct intel_engine_cs *engine = request->engine; 512 struct intel_engine_cs *engine = request->engine;
492 struct intel_timeline *timeline;
493 u32 seqno; 513 u32 seqno;
494 514
515 GEM_TRACE("%s fence %llx:%d -> global=%d, current %d\n",
516 engine->name,
517 request->fence.context, request->fence.seqno,
518 engine->timeline.seqno + 1,
519 intel_engine_get_seqno(engine));
520
495 GEM_BUG_ON(!irqs_disabled()); 521 GEM_BUG_ON(!irqs_disabled());
496 lockdep_assert_held(&engine->timeline->lock); 522 lockdep_assert_held(&engine->timeline.lock);
497 523
498 /* Transfer from per-context onto the global per-engine timeline */
499 timeline = engine->timeline;
500 GEM_BUG_ON(timeline == request->timeline);
501 GEM_BUG_ON(request->global_seqno); 524 GEM_BUG_ON(request->global_seqno);
502 525
503 seqno = timeline_get_seqno(timeline); 526 seqno = timeline_get_seqno(&engine->timeline);
504 GEM_BUG_ON(!seqno); 527 GEM_BUG_ON(!seqno);
505 GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno)); 528 GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno));
506 529
@@ -514,9 +537,8 @@ void __i915_request_submit(struct i915_request *request)
514 engine->emit_breadcrumb(request, 537 engine->emit_breadcrumb(request,
515 request->ring->vaddr + request->postfix); 538 request->ring->vaddr + request->postfix);
516 539
517 spin_lock(&request->timeline->lock); 540 /* Transfer from per-context onto the global per-engine timeline */
518 list_move_tail(&request->link, &timeline->requests); 541 move_to_timeline(request, &engine->timeline);
519 spin_unlock(&request->timeline->lock);
520 542
521 trace_i915_request_execute(request); 543 trace_i915_request_execute(request);
522 544
@@ -529,30 +551,35 @@ void i915_request_submit(struct i915_request *request)
529 unsigned long flags; 551 unsigned long flags;
530 552
531 /* Will be called from irq-context when using foreign fences. */ 553 /* Will be called from irq-context when using foreign fences. */
532 spin_lock_irqsave(&engine->timeline->lock, flags); 554 spin_lock_irqsave(&engine->timeline.lock, flags);
533 555
534 __i915_request_submit(request); 556 __i915_request_submit(request);
535 557
536 spin_unlock_irqrestore(&engine->timeline->lock, flags); 558 spin_unlock_irqrestore(&engine->timeline.lock, flags);
537} 559}
538 560
539void __i915_request_unsubmit(struct i915_request *request) 561void __i915_request_unsubmit(struct i915_request *request)
540{ 562{
541 struct intel_engine_cs *engine = request->engine; 563 struct intel_engine_cs *engine = request->engine;
542 struct intel_timeline *timeline; 564
565 GEM_TRACE("%s fence %llx:%d <- global=%d, current %d\n",
566 engine->name,
567 request->fence.context, request->fence.seqno,
568 request->global_seqno,
569 intel_engine_get_seqno(engine));
543 570
544 GEM_BUG_ON(!irqs_disabled()); 571 GEM_BUG_ON(!irqs_disabled());
545 lockdep_assert_held(&engine->timeline->lock); 572 lockdep_assert_held(&engine->timeline.lock);
546 573
547 /* 574 /*
548 * Only unwind in reverse order, required so that the per-context list 575 * Only unwind in reverse order, required so that the per-context list
549 * is kept in seqno/ring order. 576 * is kept in seqno/ring order.
550 */ 577 */
551 GEM_BUG_ON(!request->global_seqno); 578 GEM_BUG_ON(!request->global_seqno);
552 GEM_BUG_ON(request->global_seqno != engine->timeline->seqno); 579 GEM_BUG_ON(request->global_seqno != engine->timeline.seqno);
553 GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), 580 GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine),
554 request->global_seqno)); 581 request->global_seqno));
555 engine->timeline->seqno--; 582 engine->timeline.seqno--;
556 583
557 /* We may be recursing from the signal callback of another i915 fence */ 584 /* We may be recursing from the signal callback of another i915 fence */
558 spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING); 585 spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
@@ -562,12 +589,7 @@ void __i915_request_unsubmit(struct i915_request *request)
562 spin_unlock(&request->lock); 589 spin_unlock(&request->lock);
563 590
564 /* Transfer back from the global per-engine timeline to per-context */ 591 /* Transfer back from the global per-engine timeline to per-context */
565 timeline = request->timeline; 592 move_to_timeline(request, request->timeline);
566 GEM_BUG_ON(timeline == engine->timeline);
567
568 spin_lock(&timeline->lock);
569 list_move(&request->link, &timeline->requests);
570 spin_unlock(&timeline->lock);
571 593
572 /* 594 /*
573 * We don't need to wake_up any waiters on request->execute, they 595 * We don't need to wake_up any waiters on request->execute, they
@@ -584,11 +606,11 @@ void i915_request_unsubmit(struct i915_request *request)
584 unsigned long flags; 606 unsigned long flags;
585 607
586 /* Will be called from irq-context when using foreign fences. */ 608 /* Will be called from irq-context when using foreign fences. */
587 spin_lock_irqsave(&engine->timeline->lock, flags); 609 spin_lock_irqsave(&engine->timeline.lock, flags);
588 610
589 __i915_request_unsubmit(request); 611 __i915_request_unsubmit(request);
590 612
591 spin_unlock_irqrestore(&engine->timeline->lock, flags); 613 spin_unlock_irqrestore(&engine->timeline.lock, flags);
592} 614}
593 615
594static int __i915_sw_fence_call 616static int __i915_sw_fence_call
@@ -659,12 +681,12 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
659 * GGTT space, so do this first before we reserve a seqno for 681 * GGTT space, so do this first before we reserve a seqno for
660 * ourselves. 682 * ourselves.
661 */ 683 */
662 ring = engine->context_pin(engine, ctx); 684 ring = intel_context_pin(ctx, engine);
663 if (IS_ERR(ring)) 685 if (IS_ERR(ring))
664 return ERR_CAST(ring); 686 return ERR_CAST(ring);
665 GEM_BUG_ON(!ring); 687 GEM_BUG_ON(!ring);
666 688
667 ret = reserve_engine(engine); 689 ret = reserve_gt(i915);
668 if (ret) 690 if (ret)
669 goto err_unpin; 691 goto err_unpin;
670 692
@@ -672,10 +694,10 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
672 if (ret) 694 if (ret)
673 goto err_unreserve; 695 goto err_unreserve;
674 696
675 /* Move the oldest request to the slab-cache (if not in use!) */ 697 /* Move our oldest request to the slab-cache (if not in use!) */
676 rq = list_first_entry_or_null(&engine->timeline->requests, 698 rq = list_first_entry(&ring->request_list, typeof(*rq), ring_link);
677 typeof(*rq), link); 699 if (!list_is_last(&rq->ring_link, &ring->request_list) &&
678 if (rq && i915_request_completed(rq)) 700 i915_request_completed(rq))
679 i915_request_retire(rq); 701 i915_request_retire(rq);
680 702
681 /* 703 /*
@@ -735,8 +757,13 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
735 } 757 }
736 } 758 }
737 759
738 rq->timeline = i915_gem_context_lookup_timeline(ctx, engine); 760 INIT_LIST_HEAD(&rq->active_list);
739 GEM_BUG_ON(rq->timeline == engine->timeline); 761 rq->i915 = i915;
762 rq->engine = engine;
763 rq->ctx = ctx;
764 rq->ring = ring;
765 rq->timeline = ring->timeline;
766 GEM_BUG_ON(rq->timeline == &engine->timeline);
740 767
741 spin_lock_init(&rq->lock); 768 spin_lock_init(&rq->lock);
742 dma_fence_init(&rq->fence, 769 dma_fence_init(&rq->fence,
@@ -749,13 +776,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
749 i915_sw_fence_init(&i915_request_get(rq)->submit, submit_notify); 776 i915_sw_fence_init(&i915_request_get(rq)->submit, submit_notify);
750 init_waitqueue_head(&rq->execute); 777 init_waitqueue_head(&rq->execute);
751 778
752 i915_priotree_init(&rq->priotree); 779 i915_sched_node_init(&rq->sched);
753
754 INIT_LIST_HEAD(&rq->active_list);
755 rq->i915 = i915;
756 rq->engine = engine;
757 rq->ctx = ctx;
758 rq->ring = ring;
759 780
760 /* No zalloc, must clear what we need by hand */ 781 /* No zalloc, must clear what we need by hand */
761 rq->global_seqno = 0; 782 rq->global_seqno = 0;
@@ -792,6 +813,9 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
792 if (ret) 813 if (ret)
793 goto err_unwind; 814 goto err_unwind;
794 815
816 /* Keep a second pin for the dual retirement along engine and ring */
817 __intel_context_pin(rq->ctx, engine);
818
795 /* Check that we didn't interrupt ourselves with a new request */ 819 /* Check that we didn't interrupt ourselves with a new request */
796 GEM_BUG_ON(rq->timeline->seqno != rq->fence.seqno); 820 GEM_BUG_ON(rq->timeline->seqno != rq->fence.seqno);
797 return rq; 821 return rq;
@@ -801,14 +825,14 @@ err_unwind:
801 825
802 /* Make sure we didn't add ourselves to external state before freeing */ 826 /* Make sure we didn't add ourselves to external state before freeing */
803 GEM_BUG_ON(!list_empty(&rq->active_list)); 827 GEM_BUG_ON(!list_empty(&rq->active_list));
804 GEM_BUG_ON(!list_empty(&rq->priotree.signalers_list)); 828 GEM_BUG_ON(!list_empty(&rq->sched.signalers_list));
805 GEM_BUG_ON(!list_empty(&rq->priotree.waiters_list)); 829 GEM_BUG_ON(!list_empty(&rq->sched.waiters_list));
806 830
807 kmem_cache_free(i915->requests, rq); 831 kmem_cache_free(i915->requests, rq);
808err_unreserve: 832err_unreserve:
809 unreserve_engine(engine); 833 unreserve_gt(i915);
810err_unpin: 834err_unpin:
811 engine->context_unpin(engine, ctx); 835 intel_context_unpin(ctx, engine);
812 return ERR_PTR(ret); 836 return ERR_PTR(ret);
813} 837}
814 838
@@ -824,9 +848,9 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from)
824 return 0; 848 return 0;
825 849
826 if (to->engine->schedule) { 850 if (to->engine->schedule) {
827 ret = i915_priotree_add_dependency(to->i915, 851 ret = i915_sched_node_add_dependency(to->i915,
828 &to->priotree, 852 &to->sched,
829 &from->priotree); 853 &from->sched);
830 if (ret < 0) 854 if (ret < 0)
831 return ret; 855 return ret;
832 } 856 }
@@ -904,7 +928,7 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
904 928
905 /* Squash repeated waits to the same timelines */ 929 /* Squash repeated waits to the same timelines */
906 if (fence->context != rq->i915->mm.unordered_timeline && 930 if (fence->context != rq->i915->mm.unordered_timeline &&
907 intel_timeline_sync_is_later(rq->timeline, fence)) 931 i915_timeline_sync_is_later(rq->timeline, fence))
908 continue; 932 continue;
909 933
910 if (dma_fence_is_i915(fence)) 934 if (dma_fence_is_i915(fence))
@@ -918,7 +942,7 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
918 942
919 /* Record the latest fence used against each timeline */ 943 /* Record the latest fence used against each timeline */
920 if (fence->context != rq->i915->mm.unordered_timeline) 944 if (fence->context != rq->i915->mm.unordered_timeline)
921 intel_timeline_sync_set(rq->timeline, fence); 945 i915_timeline_sync_set(rq->timeline, fence);
922 } while (--nchild); 946 } while (--nchild);
923 947
924 return 0; 948 return 0;
@@ -995,11 +1019,14 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
995{ 1019{
996 struct intel_engine_cs *engine = request->engine; 1020 struct intel_engine_cs *engine = request->engine;
997 struct intel_ring *ring = request->ring; 1021 struct intel_ring *ring = request->ring;
998 struct intel_timeline *timeline = request->timeline; 1022 struct i915_timeline *timeline = request->timeline;
999 struct i915_request *prev; 1023 struct i915_request *prev;
1000 u32 *cs; 1024 u32 *cs;
1001 int err; 1025 int err;
1002 1026
1027 GEM_TRACE("%s fence %llx:%d\n",
1028 engine->name, request->fence.context, request->fence.seqno);
1029
1003 lockdep_assert_held(&request->i915->drm.struct_mutex); 1030 lockdep_assert_held(&request->i915->drm.struct_mutex);
1004 trace_i915_request_add(request); 1031 trace_i915_request_add(request);
1005 1032
@@ -1054,10 +1081,10 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
1054 i915_sw_fence_await_sw_fence(&request->submit, &prev->submit, 1081 i915_sw_fence_await_sw_fence(&request->submit, &prev->submit,
1055 &request->submitq); 1082 &request->submitq);
1056 if (engine->schedule) 1083 if (engine->schedule)
1057 __i915_priotree_add_dependency(&request->priotree, 1084 __i915_sched_node_add_dependency(&request->sched,
1058 &prev->priotree, 1085 &prev->sched,
1059 &request->dep, 1086 &request->dep,
1060 0); 1087 0);
1061 } 1088 }
1062 1089
1063 spin_lock_irq(&timeline->lock); 1090 spin_lock_irq(&timeline->lock);
@@ -1068,6 +1095,8 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
1068 i915_gem_active_set(&timeline->last_request, request); 1095 i915_gem_active_set(&timeline->last_request, request);
1069 1096
1070 list_add_tail(&request->ring_link, &ring->request_list); 1097 list_add_tail(&request->ring_link, &ring->request_list);
1098 if (list_is_first(&request->ring_link, &ring->request_list))
1099 list_add(&ring->active_link, &request->i915->gt.active_rings);
1071 request->emitted_jiffies = jiffies; 1100 request->emitted_jiffies = jiffies;
1072 1101
1073 /* 1102 /*
@@ -1081,12 +1110,11 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
1081 * decide whether to preempt the entire chain so that it is ready to 1110 * decide whether to preempt the entire chain so that it is ready to
1082 * run at the earliest possible convenience. 1111 * run at the earliest possible convenience.
1083 */ 1112 */
1084 rcu_read_lock(); 1113 local_bh_disable();
1114 rcu_read_lock(); /* RCU serialisation for set-wedged protection */
1085 if (engine->schedule) 1115 if (engine->schedule)
1086 engine->schedule(request, request->ctx->priority); 1116 engine->schedule(request, &request->ctx->sched);
1087 rcu_read_unlock(); 1117 rcu_read_unlock();
1088
1089 local_bh_disable();
1090 i915_sw_fence_commit(&request->submit); 1118 i915_sw_fence_commit(&request->submit);
1091 local_bh_enable(); /* Kick the execlists tasklet if just scheduled */ 1119 local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
1092 1120
@@ -1206,11 +1234,13 @@ static bool __i915_spin_request(const struct i915_request *rq,
1206 1234
1207static bool __i915_wait_request_check_and_reset(struct i915_request *request) 1235static bool __i915_wait_request_check_and_reset(struct i915_request *request)
1208{ 1236{
1209 if (likely(!i915_reset_handoff(&request->i915->gpu_error))) 1237 struct i915_gpu_error *error = &request->i915->gpu_error;
1238
1239 if (likely(!i915_reset_handoff(error)))
1210 return false; 1240 return false;
1211 1241
1212 __set_current_state(TASK_RUNNING); 1242 __set_current_state(TASK_RUNNING);
1213 i915_reset(request->i915, 0); 1243 i915_reset(request->i915, error->stalled_mask, error->reason);
1214 return true; 1244 return true;
1215} 1245}
1216 1246
@@ -1373,38 +1403,30 @@ complete:
1373 return timeout; 1403 return timeout;
1374} 1404}
1375 1405
1376static void engine_retire_requests(struct intel_engine_cs *engine) 1406static void ring_retire_requests(struct intel_ring *ring)
1377{ 1407{
1378 struct i915_request *request, *next; 1408 struct i915_request *request, *next;
1379 u32 seqno = intel_engine_get_seqno(engine);
1380 LIST_HEAD(retire);
1381 1409
1382 spin_lock_irq(&engine->timeline->lock);
1383 list_for_each_entry_safe(request, next, 1410 list_for_each_entry_safe(request, next,
1384 &engine->timeline->requests, link) { 1411 &ring->request_list, ring_link) {
1385 if (!i915_seqno_passed(seqno, request->global_seqno)) 1412 if (!i915_request_completed(request))
1386 break; 1413 break;
1387 1414
1388 list_move_tail(&request->link, &retire);
1389 }
1390 spin_unlock_irq(&engine->timeline->lock);
1391
1392 list_for_each_entry_safe(request, next, &retire, link)
1393 i915_request_retire(request); 1415 i915_request_retire(request);
1416 }
1394} 1417}
1395 1418
1396void i915_retire_requests(struct drm_i915_private *i915) 1419void i915_retire_requests(struct drm_i915_private *i915)
1397{ 1420{
1398 struct intel_engine_cs *engine; 1421 struct intel_ring *ring, *tmp;
1399 enum intel_engine_id id;
1400 1422
1401 lockdep_assert_held(&i915->drm.struct_mutex); 1423 lockdep_assert_held(&i915->drm.struct_mutex);
1402 1424
1403 if (!i915->gt.active_requests) 1425 if (!i915->gt.active_requests)
1404 return; 1426 return;
1405 1427
1406 for_each_engine(engine, i915, id) 1428 list_for_each_entry_safe(ring, tmp, &i915->gt.active_rings, active_link)
1407 engine_retire_requests(engine); 1429 ring_retire_requests(ring);
1408} 1430}
1409 1431
1410#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 1432#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 7d6eb82eeb91..eddbd4245cb3 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -28,13 +28,16 @@
28#include <linux/dma-fence.h> 28#include <linux/dma-fence.h>
29 29
30#include "i915_gem.h" 30#include "i915_gem.h"
31#include "i915_scheduler.h"
31#include "i915_sw_fence.h" 32#include "i915_sw_fence.h"
33#include "i915_scheduler.h"
32 34
33#include <uapi/drm/i915_drm.h> 35#include <uapi/drm/i915_drm.h>
34 36
35struct drm_file; 37struct drm_file;
36struct drm_i915_gem_object; 38struct drm_i915_gem_object;
37struct i915_request; 39struct i915_request;
40struct i915_timeline;
38 41
39struct intel_wait { 42struct intel_wait {
40 struct rb_node node; 43 struct rb_node node;
@@ -48,44 +51,6 @@ struct intel_signal_node {
48 struct list_head link; 51 struct list_head link;
49}; 52};
50 53
51struct i915_dependency {
52 struct i915_priotree *signaler;
53 struct list_head signal_link;
54 struct list_head wait_link;
55 struct list_head dfs_link;
56 unsigned long flags;
57#define I915_DEPENDENCY_ALLOC BIT(0)
58};
59
60/*
61 * "People assume that time is a strict progression of cause to effect, but
62 * actually, from a nonlinear, non-subjective viewpoint, it's more like a big
63 * ball of wibbly-wobbly, timey-wimey ... stuff." -The Doctor, 2015
64 *
65 * Requests exist in a complex web of interdependencies. Each request
66 * has to wait for some other request to complete before it is ready to be run
67 * (e.g. we have to wait until the pixels have been rendering into a texture
68 * before we can copy from it). We track the readiness of a request in terms
69 * of fences, but we also need to keep the dependency tree for the lifetime
70 * of the request (beyond the life of an individual fence). We use the tree
71 * at various points to reorder the requests whilst keeping the requests
72 * in order with respect to their various dependencies.
73 */
74struct i915_priotree {
75 struct list_head signalers_list; /* those before us, we depend upon */
76 struct list_head waiters_list; /* those after us, they depend upon us */
77 struct list_head link;
78 int priority;
79};
80
81enum {
82 I915_PRIORITY_MIN = I915_CONTEXT_MIN_USER_PRIORITY - 1,
83 I915_PRIORITY_NORMAL = I915_CONTEXT_DEFAULT_PRIORITY,
84 I915_PRIORITY_MAX = I915_CONTEXT_MAX_USER_PRIORITY + 1,
85
86 I915_PRIORITY_INVALID = INT_MIN
87};
88
89struct i915_capture_list { 54struct i915_capture_list {
90 struct i915_capture_list *next; 55 struct i915_capture_list *next;
91 struct i915_vma *vma; 56 struct i915_vma *vma;
@@ -131,7 +96,7 @@ struct i915_request {
131 struct i915_gem_context *ctx; 96 struct i915_gem_context *ctx;
132 struct intel_engine_cs *engine; 97 struct intel_engine_cs *engine;
133 struct intel_ring *ring; 98 struct intel_ring *ring;
134 struct intel_timeline *timeline; 99 struct i915_timeline *timeline;
135 struct intel_signal_node signaling; 100 struct intel_signal_node signaling;
136 101
137 /* 102 /*
@@ -154,7 +119,7 @@ struct i915_request {
154 * to retirement), i.e. bidirectional dependency information for the 119 * to retirement), i.e. bidirectional dependency information for the
155 * request not tied to individual fences. 120 * request not tied to individual fences.
156 */ 121 */
157 struct i915_priotree priotree; 122 struct i915_sched_node sched;
158 struct i915_dependency dep; 123 struct i915_dependency dep;
159 124
160 /** 125 /**
@@ -343,10 +308,10 @@ static inline bool i915_request_started(const struct i915_request *rq)
343 seqno - 1); 308 seqno - 1);
344} 309}
345 310
346static inline bool i915_priotree_signaled(const struct i915_priotree *pt) 311static inline bool i915_sched_node_signaled(const struct i915_sched_node *node)
347{ 312{
348 const struct i915_request *rq = 313 const struct i915_request *rq =
349 container_of(pt, const struct i915_request, priotree); 314 container_of(node, const struct i915_request, sched);
350 315
351 return i915_request_completed(rq); 316 return i915_request_completed(rq);
352} 317}
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h
new file mode 100644
index 000000000000..70a42220358d
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -0,0 +1,72 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright © 2018 Intel Corporation
5 */
6
7#ifndef _I915_SCHEDULER_H_
8#define _I915_SCHEDULER_H_
9
10#include <linux/bitops.h>
11
12#include <uapi/drm/i915_drm.h>
13
14enum {
15 I915_PRIORITY_MIN = I915_CONTEXT_MIN_USER_PRIORITY - 1,
16 I915_PRIORITY_NORMAL = I915_CONTEXT_DEFAULT_PRIORITY,
17 I915_PRIORITY_MAX = I915_CONTEXT_MAX_USER_PRIORITY + 1,
18
19 I915_PRIORITY_INVALID = INT_MIN
20};
21
22struct i915_sched_attr {
23 /**
24 * @priority: execution and service priority
25 *
26 * All clients are equal, but some are more equal than others!
27 *
28 * Requests from a context with a greater (more positive) value of
29 * @priority will be executed before those with a lower @priority
30 * value, forming a simple QoS.
31 *
32 * The &drm_i915_private.kernel_context is assigned the lowest priority.
33 */
34 int priority;
35};
36
37/*
38 * "People assume that time is a strict progression of cause to effect, but
39 * actually, from a nonlinear, non-subjective viewpoint, it's more like a big
40 * ball of wibbly-wobbly, timey-wimey ... stuff." -The Doctor, 2015
41 *
42 * Requests exist in a complex web of interdependencies. Each request
43 * has to wait for some other request to complete before it is ready to be run
44 * (e.g. we have to wait until the pixels have been rendering into a texture
45 * before we can copy from it). We track the readiness of a request in terms
46 * of fences, but we also need to keep the dependency tree for the lifetime
47 * of the request (beyond the life of an individual fence). We use the tree
48 * at various points to reorder the requests whilst keeping the requests
49 * in order with respect to their various dependencies.
50 *
51 * There is no active component to the "scheduler". As we know the dependency
52 * DAG of each request, we are able to insert it into a sorted queue when it
53 * is ready, and are able to reorder its portion of the graph to accommodate
54 * dynamic priority changes.
55 */
56struct i915_sched_node {
57 struct list_head signalers_list; /* those before us, we depend upon */
58 struct list_head waiters_list; /* those after us, they depend upon us */
59 struct list_head link;
60 struct i915_sched_attr attr;
61};
62
63struct i915_dependency {
64 struct i915_sched_node *signaler;
65 struct list_head signal_link;
66 struct list_head wait_link;
67 struct list_head dfs_link;
68 unsigned long flags;
69#define I915_DEPENDENCY_ALLOC BIT(0)
70};
71
72#endif /* _I915_SCHEDULER_H_ */
diff --git a/drivers/gpu/drm/i915/i915_timeline.c b/drivers/gpu/drm/i915/i915_timeline.c
new file mode 100644
index 000000000000..4667cc08c416
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_timeline.c
@@ -0,0 +1,105 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright © 2016-2018 Intel Corporation
5 */
6
7#include "i915_drv.h"
8
9#include "i915_timeline.h"
10#include "i915_syncmap.h"
11
12void i915_timeline_init(struct drm_i915_private *i915,
13 struct i915_timeline *timeline,
14 const char *name)
15{
16 lockdep_assert_held(&i915->drm.struct_mutex);
17
18 /*
19 * Ideally we want a set of engines on a single leaf as we expect
20 * to mostly be tracking synchronisation between engines. It is not
21 * a huge issue if this is not the case, but we may want to mitigate
22 * any page crossing penalties if they become an issue.
23 */
24 BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES);
25
26 timeline->name = name;
27
28 list_add(&timeline->link, &i915->gt.timelines);
29
30 /* Called during early_init before we know how many engines there are */
31
32 timeline->fence_context = dma_fence_context_alloc(1);
33
34 spin_lock_init(&timeline->lock);
35
36 init_request_active(&timeline->last_request, NULL);
37 INIT_LIST_HEAD(&timeline->requests);
38
39 i915_syncmap_init(&timeline->sync);
40}
41
42/**
43 * i915_timelines_park - called when the driver idles
44 * @i915: the drm_i915_private device
45 *
46 * When the driver is completely idle, we know that all of our sync points
47 * have been signaled and our tracking is then entirely redundant. Any request
48 * to wait upon an older sync point will be completed instantly as we know
49 * the fence is signaled and therefore we will not even look them up in the
50 * sync point map.
51 */
52void i915_timelines_park(struct drm_i915_private *i915)
53{
54 struct i915_timeline *timeline;
55
56 lockdep_assert_held(&i915->drm.struct_mutex);
57
58 list_for_each_entry(timeline, &i915->gt.timelines, link) {
59 /*
60 * All known fences are completed so we can scrap
61 * the current sync point tracking and start afresh,
62 * any attempt to wait upon a previous sync point
63 * will be skipped as the fence was signaled.
64 */
65 i915_syncmap_free(&timeline->sync);
66 }
67}
68
69void i915_timeline_fini(struct i915_timeline *timeline)
70{
71 GEM_BUG_ON(!list_empty(&timeline->requests));
72
73 i915_syncmap_free(&timeline->sync);
74
75 list_del(&timeline->link);
76}
77
78struct i915_timeline *
79i915_timeline_create(struct drm_i915_private *i915, const char *name)
80{
81 struct i915_timeline *timeline;
82
83 timeline = kzalloc(sizeof(*timeline), GFP_KERNEL);
84 if (!timeline)
85 return ERR_PTR(-ENOMEM);
86
87 i915_timeline_init(i915, timeline, name);
88 kref_init(&timeline->kref);
89
90 return timeline;
91}
92
93void __i915_timeline_free(struct kref *kref)
94{
95 struct i915_timeline *timeline =
96 container_of(kref, typeof(*timeline), kref);
97
98 i915_timeline_fini(timeline);
99 kfree(timeline);
100}
101
102#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
103#include "selftests/mock_timeline.c"
104#include "selftests/i915_timeline.c"
105#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_timeline.h
index 33e01bf6aa36..dc2a4632faa7 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_timeline.h
@@ -22,27 +22,20 @@
22 * 22 *
23 */ 23 */
24 24
25#ifndef I915_GEM_TIMELINE_H 25#ifndef I915_TIMELINE_H
26#define I915_GEM_TIMELINE_H 26#define I915_TIMELINE_H
27 27
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/kref.h>
29 30
30#include "i915_request.h" 31#include "i915_request.h"
31#include "i915_syncmap.h" 32#include "i915_syncmap.h"
32#include "i915_utils.h" 33#include "i915_utils.h"
33 34
34struct i915_gem_timeline; 35struct i915_timeline {
35
36struct intel_timeline {
37 u64 fence_context; 36 u64 fence_context;
38 u32 seqno; 37 u32 seqno;
39 38
40 /**
41 * Count of outstanding requests, from the time they are constructed
42 * to the moment they are retired. Loosely coupled to hardware.
43 */
44 u32 inflight_seqnos;
45
46 spinlock_t lock; 39 spinlock_t lock;
47 40
48 /** 41 /**
@@ -77,47 +70,57 @@ struct intel_timeline {
77 */ 70 */
78 u32 global_sync[I915_NUM_ENGINES]; 71 u32 global_sync[I915_NUM_ENGINES];
79 72
80 struct i915_gem_timeline *common;
81};
82
83struct i915_gem_timeline {
84 struct list_head link; 73 struct list_head link;
85
86 struct drm_i915_private *i915;
87 const char *name; 74 const char *name;
88 75
89 struct intel_timeline engine[I915_NUM_ENGINES]; 76 struct kref kref;
90}; 77};
91 78
92int i915_gem_timeline_init(struct drm_i915_private *i915, 79void i915_timeline_init(struct drm_i915_private *i915,
93 struct i915_gem_timeline *tl, 80 struct i915_timeline *tl,
94 const char *name); 81 const char *name);
95int i915_gem_timeline_init__global(struct drm_i915_private *i915); 82void i915_timeline_fini(struct i915_timeline *tl);
96void i915_gem_timelines_park(struct drm_i915_private *i915); 83
97void i915_gem_timeline_fini(struct i915_gem_timeline *tl); 84struct i915_timeline *
85i915_timeline_create(struct drm_i915_private *i915, const char *name);
98 86
99static inline int __intel_timeline_sync_set(struct intel_timeline *tl, 87static inline struct i915_timeline *
100 u64 context, u32 seqno) 88i915_timeline_get(struct i915_timeline *timeline)
89{
90 kref_get(&timeline->kref);
91 return timeline;
92}
93
94void __i915_timeline_free(struct kref *kref);
95static inline void i915_timeline_put(struct i915_timeline *timeline)
96{
97 kref_put(&timeline->kref, __i915_timeline_free);
98}
99
100static inline int __i915_timeline_sync_set(struct i915_timeline *tl,
101 u64 context, u32 seqno)
101{ 102{
102 return i915_syncmap_set(&tl->sync, context, seqno); 103 return i915_syncmap_set(&tl->sync, context, seqno);
103} 104}
104 105
105static inline int intel_timeline_sync_set(struct intel_timeline *tl, 106static inline int i915_timeline_sync_set(struct i915_timeline *tl,
106 const struct dma_fence *fence) 107 const struct dma_fence *fence)
107{ 108{
108 return __intel_timeline_sync_set(tl, fence->context, fence->seqno); 109 return __i915_timeline_sync_set(tl, fence->context, fence->seqno);
109} 110}
110 111
111static inline bool __intel_timeline_sync_is_later(struct intel_timeline *tl, 112static inline bool __i915_timeline_sync_is_later(struct i915_timeline *tl,
112 u64 context, u32 seqno) 113 u64 context, u32 seqno)
113{ 114{
114 return i915_syncmap_is_later(&tl->sync, context, seqno); 115 return i915_syncmap_is_later(&tl->sync, context, seqno);
115} 116}
116 117
117static inline bool intel_timeline_sync_is_later(struct intel_timeline *tl, 118static inline bool i915_timeline_sync_is_later(struct i915_timeline *tl,
118 const struct dma_fence *fence) 119 const struct dma_fence *fence)
119{ 120{
120 return __intel_timeline_sync_is_later(tl, fence->context, fence->seqno); 121 return __i915_timeline_sync_is_later(tl, fence->context, fence->seqno);
121} 122}
122 123
124void i915_timelines_park(struct drm_i915_private *i915);
125
123#endif 126#endif
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 408827bf5d96..8cc3a256f29d 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -679,45 +679,68 @@ DEFINE_EVENT(i915_request, i915_request_execute,
679 TP_ARGS(rq) 679 TP_ARGS(rq)
680); 680);
681 681
682DECLARE_EVENT_CLASS(i915_request_hw, 682TRACE_EVENT(i915_request_in,
683 TP_PROTO(struct i915_request *rq, unsigned int port), 683 TP_PROTO(struct i915_request *rq, unsigned int port),
684 TP_ARGS(rq, port), 684 TP_ARGS(rq, port),
685 685
686 TP_STRUCT__entry( 686 TP_STRUCT__entry(
687 __field(u32, dev) 687 __field(u32, dev)
688 __field(u32, hw_id) 688 __field(u32, hw_id)
689 __field(u32, ring) 689 __field(u32, ring)
690 __field(u32, ctx) 690 __field(u32, ctx)
691 __field(u32, seqno) 691 __field(u32, seqno)
692 __field(u32, global_seqno) 692 __field(u32, global_seqno)
693 __field(u32, port) 693 __field(u32, port)
694 ), 694 __field(u32, prio)
695 695 ),
696 TP_fast_assign( 696
697 __entry->dev = rq->i915->drm.primary->index; 697 TP_fast_assign(
698 __entry->hw_id = rq->ctx->hw_id; 698 __entry->dev = rq->i915->drm.primary->index;
699 __entry->ring = rq->engine->id; 699 __entry->hw_id = rq->ctx->hw_id;
700 __entry->ctx = rq->fence.context; 700 __entry->ring = rq->engine->id;
701 __entry->seqno = rq->fence.seqno; 701 __entry->ctx = rq->fence.context;
702 __entry->global_seqno = rq->global_seqno; 702 __entry->seqno = rq->fence.seqno;
703 __entry->port = port; 703 __entry->global_seqno = rq->global_seqno;
704 ), 704 __entry->prio = rq->sched.attr.priority;
705 705 __entry->port = port;
706 TP_printk("dev=%u, hw_id=%u, ring=%u, ctx=%u, seqno=%u, global=%u, port=%u", 706 ),
707 __entry->dev, __entry->hw_id, __entry->ring,
708 __entry->ctx, __entry->seqno,
709 __entry->global_seqno, __entry->port)
710);
711 707
712DEFINE_EVENT(i915_request_hw, i915_request_in, 708 TP_printk("dev=%u, hw_id=%u, ring=%u, ctx=%u, seqno=%u, prio=%u, global=%u, port=%u",
713 TP_PROTO(struct i915_request *rq, unsigned int port), 709 __entry->dev, __entry->hw_id, __entry->ring, __entry->ctx,
714 TP_ARGS(rq, port) 710 __entry->seqno, __entry->prio, __entry->global_seqno,
711 __entry->port)
715); 712);
716 713
717DEFINE_EVENT(i915_request, i915_request_out, 714TRACE_EVENT(i915_request_out,
718 TP_PROTO(struct i915_request *rq), 715 TP_PROTO(struct i915_request *rq),
719 TP_ARGS(rq) 716 TP_ARGS(rq),
717
718 TP_STRUCT__entry(
719 __field(u32, dev)
720 __field(u32, hw_id)
721 __field(u32, ring)
722 __field(u32, ctx)
723 __field(u32, seqno)
724 __field(u32, global_seqno)
725 __field(u32, completed)
726 ),
727
728 TP_fast_assign(
729 __entry->dev = rq->i915->drm.primary->index;
730 __entry->hw_id = rq->ctx->hw_id;
731 __entry->ring = rq->engine->id;
732 __entry->ctx = rq->fence.context;
733 __entry->seqno = rq->fence.seqno;
734 __entry->global_seqno = rq->global_seqno;
735 __entry->completed = i915_request_completed(rq);
736 ),
737
738 TP_printk("dev=%u, hw_id=%u, ring=%u, ctx=%u, seqno=%u, global=%u, completed?=%u",
739 __entry->dev, __entry->hw_id, __entry->ring,
740 __entry->ctx, __entry->seqno,
741 __entry->global_seqno, __entry->completed)
720); 742);
743
721#else 744#else
722#if !defined(TRACE_HEADER_MULTI_READ) 745#if !defined(TRACE_HEADER_MULTI_READ)
723static inline void 746static inline void
@@ -811,42 +834,6 @@ DEFINE_EVENT(i915_request, i915_request_wait_end,
811 TP_ARGS(rq) 834 TP_ARGS(rq)
812); 835);
813 836
814TRACE_EVENT(i915_flip_request,
815 TP_PROTO(int plane, struct drm_i915_gem_object *obj),
816
817 TP_ARGS(plane, obj),
818
819 TP_STRUCT__entry(
820 __field(int, plane)
821 __field(struct drm_i915_gem_object *, obj)
822 ),
823
824 TP_fast_assign(
825 __entry->plane = plane;
826 __entry->obj = obj;
827 ),
828
829 TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj)
830);
831
832TRACE_EVENT(i915_flip_complete,
833 TP_PROTO(int plane, struct drm_i915_gem_object *obj),
834
835 TP_ARGS(plane, obj),
836
837 TP_STRUCT__entry(
838 __field(int, plane)
839 __field(struct drm_i915_gem_object *, obj)
840 ),
841
842 TP_fast_assign(
843 __entry->plane = plane;
844 __entry->obj = obj;
845 ),
846
847 TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj)
848);
849
850TRACE_EVENT_CONDITION(i915_reg_rw, 837TRACE_EVENT_CONDITION(i915_reg_rw,
851 TP_PROTO(bool write, i915_reg_t reg, u64 val, int len, bool trace), 838 TP_PROTO(bool write, i915_reg_t reg, u64 val, int len, bool trace),
852 839
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index 51dbfe5bb418..00165ad55fb3 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -40,8 +40,8 @@
40#undef WARN_ON_ONCE 40#undef WARN_ON_ONCE
41#define WARN_ON_ONCE(x) WARN_ONCE((x), "%s", "WARN_ON_ONCE(" __stringify(x) ")") 41#define WARN_ON_ONCE(x) WARN_ONCE((x), "%s", "WARN_ON_ONCE(" __stringify(x) ")")
42 42
43#define MISSING_CASE(x) WARN(1, "Missing switch case (%lu) in %s\n", \ 43#define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \
44 (long)(x), __func__) 44 __stringify(x), (long)(x))
45 45
46#if GCC_VERSION >= 70000 46#if GCC_VERSION >= 70000
47#define add_overflows(A, B) \ 47#define add_overflows(A, B) \
@@ -120,6 +120,12 @@ static inline u64 ptr_to_u64(const void *ptr)
120 120
121#include <linux/list.h> 121#include <linux/list.h>
122 122
123static inline int list_is_first(const struct list_head *list,
124 const struct list_head *head)
125{
126 return head->next == list;
127}
128
123static inline void __list_del_many(struct list_head *head, 129static inline void __list_del_many(struct list_head *head,
124 struct list_head *first) 130 struct list_head *first)
125{ 131{
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 4bda3bd29bf5..9324d476e0a7 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -46,8 +46,6 @@ i915_vma_retire(struct i915_gem_active *active, struct i915_request *rq)
46 46
47 GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); 47 GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
48 list_move_tail(&vma->vm_link, &vma->vm->inactive_list); 48 list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
49 if (unlikely(i915_vma_is_closed(vma) && !i915_vma_is_pinned(vma)))
50 WARN_ON(i915_vma_unbind(vma));
51 49
52 GEM_BUG_ON(!i915_gem_object_is_active(obj)); 50 GEM_BUG_ON(!i915_gem_object_is_active(obj));
53 if (--obj->active_count) 51 if (--obj->active_count)
@@ -232,7 +230,6 @@ i915_vma_instance(struct drm_i915_gem_object *obj,
232 if (!vma) 230 if (!vma)
233 vma = vma_create(obj, vm, view); 231 vma = vma_create(obj, vm, view);
234 232
235 GEM_BUG_ON(!IS_ERR(vma) && i915_vma_is_closed(vma));
236 GEM_BUG_ON(!IS_ERR(vma) && i915_vma_compare(vma, vm, view)); 233 GEM_BUG_ON(!IS_ERR(vma) && i915_vma_compare(vma, vm, view));
237 GEM_BUG_ON(!IS_ERR(vma) && vma_lookup(obj, vm, view) != vma); 234 GEM_BUG_ON(!IS_ERR(vma) && vma_lookup(obj, vm, view) != vma);
238 return vma; 235 return vma;
@@ -684,13 +681,43 @@ err_unpin:
684 return ret; 681 return ret;
685} 682}
686 683
687static void i915_vma_destroy(struct i915_vma *vma) 684void i915_vma_close(struct i915_vma *vma)
685{
686 lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
687
688 GEM_BUG_ON(i915_vma_is_closed(vma));
689 vma->flags |= I915_VMA_CLOSED;
690
691 /*
692 * We defer actually closing, unbinding and destroying the VMA until
693 * the next idle point, or if the object is freed in the meantime. By
694 * postponing the unbind, we allow for it to be resurrected by the
695 * client, avoiding the work required to rebind the VMA. This is
696 * advantageous for DRI, where the client/server pass objects
697 * between themselves, temporarily opening a local VMA to the
698 * object, and then closing it again. The same object is then reused
699 * on the next frame (or two, depending on the depth of the swap queue)
700 * causing us to rebind the VMA once more. This ends up being a lot
701 * of wasted work for the steady state.
702 */
703 list_add_tail(&vma->closed_link, &vma->vm->i915->gt.closed_vma);
704}
705
706void i915_vma_reopen(struct i915_vma *vma)
707{
708 lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
709
710 if (vma->flags & I915_VMA_CLOSED) {
711 vma->flags &= ~I915_VMA_CLOSED;
712 list_del(&vma->closed_link);
713 }
714}
715
716static void __i915_vma_destroy(struct i915_vma *vma)
688{ 717{
689 int i; 718 int i;
690 719
691 GEM_BUG_ON(vma->node.allocated); 720 GEM_BUG_ON(vma->node.allocated);
692 GEM_BUG_ON(i915_vma_is_active(vma));
693 GEM_BUG_ON(!i915_vma_is_closed(vma));
694 GEM_BUG_ON(vma->fence); 721 GEM_BUG_ON(vma->fence);
695 722
696 for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) 723 for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
@@ -699,6 +726,7 @@ static void i915_vma_destroy(struct i915_vma *vma)
699 726
700 list_del(&vma->obj_link); 727 list_del(&vma->obj_link);
701 list_del(&vma->vm_link); 728 list_del(&vma->vm_link);
729 rb_erase(&vma->obj_node, &vma->obj->vma_tree);
702 730
703 if (!i915_vma_is_ggtt(vma)) 731 if (!i915_vma_is_ggtt(vma))
704 i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm)); 732 i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
@@ -706,15 +734,30 @@ static void i915_vma_destroy(struct i915_vma *vma)
706 kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma); 734 kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma);
707} 735}
708 736
709void i915_vma_close(struct i915_vma *vma) 737void i915_vma_destroy(struct i915_vma *vma)
710{ 738{
711 GEM_BUG_ON(i915_vma_is_closed(vma)); 739 lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
712 vma->flags |= I915_VMA_CLOSED;
713 740
714 rb_erase(&vma->obj_node, &vma->obj->vma_tree); 741 GEM_BUG_ON(i915_vma_is_active(vma));
742 GEM_BUG_ON(i915_vma_is_pinned(vma));
743
744 if (i915_vma_is_closed(vma))
745 list_del(&vma->closed_link);
746
747 WARN_ON(i915_vma_unbind(vma));
748 __i915_vma_destroy(vma);
749}
750
751void i915_vma_parked(struct drm_i915_private *i915)
752{
753 struct i915_vma *vma, *next;
715 754
716 if (!i915_vma_is_active(vma) && !i915_vma_is_pinned(vma)) 755 list_for_each_entry_safe(vma, next, &i915->gt.closed_vma, closed_link) {
717 WARN_ON(i915_vma_unbind(vma)); 756 GEM_BUG_ON(!i915_vma_is_closed(vma));
757 i915_vma_destroy(vma);
758 }
759
760 GEM_BUG_ON(!list_empty(&i915->gt.closed_vma));
718} 761}
719 762
720static void __i915_vma_iounmap(struct i915_vma *vma) 763static void __i915_vma_iounmap(struct i915_vma *vma)
@@ -804,7 +847,7 @@ int i915_vma_unbind(struct i915_vma *vma)
804 return -EBUSY; 847 return -EBUSY;
805 848
806 if (!drm_mm_node_allocated(&vma->node)) 849 if (!drm_mm_node_allocated(&vma->node))
807 goto destroy; 850 return 0;
808 851
809 GEM_BUG_ON(obj->bind_count == 0); 852 GEM_BUG_ON(obj->bind_count == 0);
810 GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); 853 GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
@@ -841,10 +884,6 @@ int i915_vma_unbind(struct i915_vma *vma)
841 884
842 i915_vma_remove(vma); 885 i915_vma_remove(vma);
843 886
844destroy:
845 if (unlikely(i915_vma_is_closed(vma)))
846 i915_vma_destroy(vma);
847
848 return 0; 887 return 0;
849} 888}
850 889
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 8c5022095418..fc4294cfaa91 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -119,6 +119,8 @@ struct i915_vma {
119 /** This vma's place in the eviction list */ 119 /** This vma's place in the eviction list */
120 struct list_head evict_link; 120 struct list_head evict_link;
121 121
122 struct list_head closed_link;
123
122 /** 124 /**
123 * Used for performing relocations during execbuffer insertion. 125 * Used for performing relocations during execbuffer insertion.
124 */ 126 */
@@ -285,6 +287,8 @@ void i915_vma_revoke_mmap(struct i915_vma *vma);
285int __must_check i915_vma_unbind(struct i915_vma *vma); 287int __must_check i915_vma_unbind(struct i915_vma *vma);
286void i915_vma_unlink_ctx(struct i915_vma *vma); 288void i915_vma_unlink_ctx(struct i915_vma *vma);
287void i915_vma_close(struct i915_vma *vma); 289void i915_vma_close(struct i915_vma *vma);
290void i915_vma_reopen(struct i915_vma *vma);
291void i915_vma_destroy(struct i915_vma *vma);
288 292
289int __i915_vma_do_pin(struct i915_vma *vma, 293int __i915_vma_do_pin(struct i915_vma *vma,
290 u64 size, u64 alignment, u64 flags); 294 u64 size, u64 alignment, u64 flags);
@@ -408,6 +412,8 @@ i915_vma_unpin_fence(struct i915_vma *vma)
408 __i915_vma_unpin_fence(vma); 412 __i915_vma_unpin_fence(vma);
409} 413}
410 414
415void i915_vma_parked(struct drm_i915_private *i915);
416
411#define for_each_until(cond) if (cond) break; else 417#define for_each_until(cond) if (cond) break; else
412 418
413/** 419/**
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index e9fb692076d7..40285d1b91b7 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -227,6 +227,7 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
227 struct intel_crtc_scaler_state *scaler_state = 227 struct intel_crtc_scaler_state *scaler_state =
228 &crtc_state->scaler_state; 228 &crtc_state->scaler_state;
229 struct drm_atomic_state *drm_state = crtc_state->base.state; 229 struct drm_atomic_state *drm_state = crtc_state->base.state;
230 struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state);
230 int num_scalers_need; 231 int num_scalers_need;
231 int i, j; 232 int i, j;
232 233
@@ -304,8 +305,8 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
304 continue; 305 continue;
305 } 306 }
306 307
307 plane_state = intel_atomic_get_existing_plane_state(drm_state, 308 plane_state = intel_atomic_get_new_plane_state(intel_state,
308 intel_plane); 309 intel_plane);
309 scaler_id = &plane_state->scaler_id; 310 scaler_id = &plane_state->scaler_id;
310 } 311 }
311 312
@@ -328,8 +329,18 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
328 } 329 }
329 330
330 /* set scaler mode */ 331 /* set scaler mode */
331 if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) { 332 if ((INTEL_GEN(dev_priv) >= 9) &&
332 scaler_state->scalers[*scaler_id].mode = 0; 333 plane_state && plane_state->base.fb &&
334 plane_state->base.fb->format->format ==
335 DRM_FORMAT_NV12) {
336 if (INTEL_GEN(dev_priv) == 9 &&
337 !IS_GEMINILAKE(dev_priv) &&
338 !IS_SKYLAKE(dev_priv))
339 scaler_state->scalers[*scaler_id].mode =
340 SKL_PS_SCALER_MODE_NV12;
341 else
342 scaler_state->scalers[*scaler_id].mode =
343 PS_SCALER_MODE_PLANAR;
333 } else if (num_scalers_need == 1 && intel_crtc->pipe != PIPE_C) { 344 } else if (num_scalers_need == 1 && intel_crtc->pipe != PIPE_C) {
334 /* 345 /*
335 * when only 1 scaler is in use on either pipe A or B, 346 * when only 1 scaler is in use on either pipe A or B,
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index 7481ce85746b..6d068786eb41 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -183,11 +183,16 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
183 } 183 }
184 184
185 /* FIXME pre-g4x don't work like this */ 185 /* FIXME pre-g4x don't work like this */
186 if (intel_state->base.visible) 186 if (state->visible)
187 crtc_state->active_planes |= BIT(intel_plane->id); 187 crtc_state->active_planes |= BIT(intel_plane->id);
188 else 188 else
189 crtc_state->active_planes &= ~BIT(intel_plane->id); 189 crtc_state->active_planes &= ~BIT(intel_plane->id);
190 190
191 if (state->visible && state->fb->format->format == DRM_FORMAT_NV12)
192 crtc_state->nv12_planes |= BIT(intel_plane->id);
193 else
194 crtc_state->nv12_planes &= ~BIT(intel_plane->id);
195
191 return intel_plane_atomic_calc_changes(old_crtc_state, 196 return intel_plane_atomic_calc_changes(old_crtc_state,
192 &crtc_state->base, 197 &crtc_state->base,
193 old_plane_state, 198 old_plane_state,
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 447b721c3be9..54270bdde100 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -530,6 +530,7 @@ parse_driver_features(struct drm_i915_private *dev_priv,
530 */ 530 */
531 if (!driver->drrs_enabled) 531 if (!driver->drrs_enabled)
532 dev_priv->vbt.drrs_type = DRRS_NOT_SUPPORTED; 532 dev_priv->vbt.drrs_type = DRRS_NOT_SUPPORTED;
533 dev_priv->vbt.psr.enable = driver->psr_enabled;
533} 534}
534 535
535static void 536static void
@@ -1215,10 +1216,8 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
1215{ 1216{
1216 struct child_device_config *it, *child = NULL; 1217 struct child_device_config *it, *child = NULL;
1217 struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port]; 1218 struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port];
1218 uint8_t hdmi_level_shift;
1219 int i, j; 1219 int i, j;
1220 bool is_dvi, is_hdmi, is_dp, is_edp, is_crt; 1220 bool is_dvi, is_hdmi, is_dp, is_edp, is_crt;
1221 uint8_t aux_channel, ddc_pin;
1222 /* Each DDI port can have more than one value on the "DVO Port" field, 1221 /* Each DDI port can have more than one value on the "DVO Port" field,
1223 * so look for all the possible values for each port. 1222 * so look for all the possible values for each port.
1224 */ 1223 */
@@ -1255,8 +1254,6 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
1255 if (!child) 1254 if (!child)
1256 return; 1255 return;
1257 1256
1258 aux_channel = child->aux_channel;
1259
1260 is_dvi = child->device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING; 1257 is_dvi = child->device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
1261 is_dp = child->device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT; 1258 is_dp = child->device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT;
1262 is_crt = child->device_type & DEVICE_TYPE_ANALOG_OUTPUT; 1259 is_crt = child->device_type & DEVICE_TYPE_ANALOG_OUTPUT;
@@ -1270,13 +1267,6 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
1270 is_hdmi = false; 1267 is_hdmi = false;
1271 } 1268 }
1272 1269
1273 if (port == PORT_A && is_dvi) {
1274 DRM_DEBUG_KMS("VBT claims port A supports DVI%s, ignoring\n",
1275 is_hdmi ? "/HDMI" : "");
1276 is_dvi = false;
1277 is_hdmi = false;
1278 }
1279
1280 info->supports_dvi = is_dvi; 1270 info->supports_dvi = is_dvi;
1281 info->supports_hdmi = is_hdmi; 1271 info->supports_hdmi = is_hdmi;
1282 info->supports_dp = is_dp; 1272 info->supports_dp = is_dp;
@@ -1302,6 +1292,8 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
1302 DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port)); 1292 DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));
1303 1293
1304 if (is_dvi) { 1294 if (is_dvi) {
1295 u8 ddc_pin;
1296
1305 ddc_pin = map_ddc_pin(dev_priv, child->ddc_pin); 1297 ddc_pin = map_ddc_pin(dev_priv, child->ddc_pin);
1306 if (intel_gmbus_is_valid_pin(dev_priv, ddc_pin)) { 1298 if (intel_gmbus_is_valid_pin(dev_priv, ddc_pin)) {
1307 info->alternate_ddc_pin = ddc_pin; 1299 info->alternate_ddc_pin = ddc_pin;
@@ -1314,14 +1306,14 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
1314 } 1306 }
1315 1307
1316 if (is_dp) { 1308 if (is_dp) {
1317 info->alternate_aux_channel = aux_channel; 1309 info->alternate_aux_channel = child->aux_channel;
1318 1310
1319 sanitize_aux_ch(dev_priv, port); 1311 sanitize_aux_ch(dev_priv, port);
1320 } 1312 }
1321 1313
1322 if (bdb_version >= 158) { 1314 if (bdb_version >= 158) {
1323 /* The VBT HDMI level shift values match the table we have. */ 1315 /* The VBT HDMI level shift values match the table we have. */
1324 hdmi_level_shift = child->hdmi_level_shifter_value; 1316 u8 hdmi_level_shift = child->hdmi_level_shifter_value;
1325 DRM_DEBUG_KMS("VBT HDMI level shift for port %c: %d\n", 1317 DRM_DEBUG_KMS("VBT HDMI level shift for port %c: %d\n",
1326 port_name(port), 1318 port_name(port),
1327 hdmi_level_shift); 1319 hdmi_level_shift);
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 1f79e7a47433..18e643df523e 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -82,7 +82,7 @@ static unsigned long wait_timeout(void)
82 82
83static noinline void missed_breadcrumb(struct intel_engine_cs *engine) 83static noinline void missed_breadcrumb(struct intel_engine_cs *engine)
84{ 84{
85 if (drm_debug & DRM_UT_DRIVER) { 85 if (GEM_SHOW_DEBUG()) {
86 struct drm_printer p = drm_debug_printer(__func__); 86 struct drm_printer p = drm_debug_printer(__func__);
87 87
88 intel_engine_dump(engine, &p, 88 intel_engine_dump(engine, &p,
@@ -130,11 +130,12 @@ static void intel_breadcrumbs_hangcheck(struct timer_list *t)
130 130
131static void intel_breadcrumbs_fake_irq(struct timer_list *t) 131static void intel_breadcrumbs_fake_irq(struct timer_list *t)
132{ 132{
133 struct intel_engine_cs *engine = from_timer(engine, t, 133 struct intel_engine_cs *engine =
134 breadcrumbs.fake_irq); 134 from_timer(engine, t, breadcrumbs.fake_irq);
135 struct intel_breadcrumbs *b = &engine->breadcrumbs; 135 struct intel_breadcrumbs *b = &engine->breadcrumbs;
136 136
137 /* The timer persists in case we cannot enable interrupts, 137 /*
138 * The timer persists in case we cannot enable interrupts,
138 * or if we have previously seen seqno/interrupt incoherency 139 * or if we have previously seen seqno/interrupt incoherency
139 * ("missed interrupt" syndrome, better known as a "missed breadcrumb"). 140 * ("missed interrupt" syndrome, better known as a "missed breadcrumb").
140 * Here the worker will wake up every jiffie in order to kick the 141 * Here the worker will wake up every jiffie in order to kick the
@@ -148,6 +149,12 @@ static void intel_breadcrumbs_fake_irq(struct timer_list *t)
148 if (!b->irq_armed) 149 if (!b->irq_armed)
149 return; 150 return;
150 151
152 /* If the user has disabled the fake-irq, restore the hangchecking */
153 if (!test_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings)) {
154 mod_timer(&b->hangcheck, wait_timeout());
155 return;
156 }
157
151 mod_timer(&b->fake_irq, jiffies + 1); 158 mod_timer(&b->fake_irq, jiffies + 1);
152} 159}
153 160
@@ -730,10 +737,11 @@ static void insert_signal(struct intel_breadcrumbs *b,
730 list_add(&request->signaling.link, &iter->signaling.link); 737 list_add(&request->signaling.link, &iter->signaling.link);
731} 738}
732 739
733void intel_engine_enable_signaling(struct i915_request *request, bool wakeup) 740bool intel_engine_enable_signaling(struct i915_request *request, bool wakeup)
734{ 741{
735 struct intel_engine_cs *engine = request->engine; 742 struct intel_engine_cs *engine = request->engine;
736 struct intel_breadcrumbs *b = &engine->breadcrumbs; 743 struct intel_breadcrumbs *b = &engine->breadcrumbs;
744 struct intel_wait *wait = &request->signaling.wait;
737 u32 seqno; 745 u32 seqno;
738 746
739 /* 747 /*
@@ -750,12 +758,12 @@ void intel_engine_enable_signaling(struct i915_request *request, bool wakeup)
750 758
751 seqno = i915_request_global_seqno(request); 759 seqno = i915_request_global_seqno(request);
752 if (!seqno) /* will be enabled later upon execution */ 760 if (!seqno) /* will be enabled later upon execution */
753 return; 761 return true;
754 762
755 GEM_BUG_ON(request->signaling.wait.seqno); 763 GEM_BUG_ON(wait->seqno);
756 request->signaling.wait.tsk = b->signaler; 764 wait->tsk = b->signaler;
757 request->signaling.wait.request = request; 765 wait->request = request;
758 request->signaling.wait.seqno = seqno; 766 wait->seqno = seqno;
759 767
760 /* 768 /*
761 * Add ourselves into the list of waiters, but registering our 769 * Add ourselves into the list of waiters, but registering our
@@ -768,11 +776,15 @@ void intel_engine_enable_signaling(struct i915_request *request, bool wakeup)
768 */ 776 */
769 spin_lock(&b->rb_lock); 777 spin_lock(&b->rb_lock);
770 insert_signal(b, request, seqno); 778 insert_signal(b, request, seqno);
771 wakeup &= __intel_engine_add_wait(engine, &request->signaling.wait); 779 wakeup &= __intel_engine_add_wait(engine, wait);
772 spin_unlock(&b->rb_lock); 780 spin_unlock(&b->rb_lock);
773 781
774 if (wakeup) 782 if (wakeup) {
775 wake_up_process(b->signaler); 783 wake_up_process(b->signaler);
784 return !intel_wait_complete(wait);
785 }
786
787 return true;
776} 788}
777 789
778void intel_engine_cancel_signaling(struct i915_request *request) 790void intel_engine_cancel_signaling(struct i915_request *request)
@@ -826,8 +838,8 @@ static void cancel_fake_irq(struct intel_engine_cs *engine)
826{ 838{
827 struct intel_breadcrumbs *b = &engine->breadcrumbs; 839 struct intel_breadcrumbs *b = &engine->breadcrumbs;
828 840
841 del_timer_sync(&b->fake_irq); /* may queue b->hangcheck */
829 del_timer_sync(&b->hangcheck); 842 del_timer_sync(&b->hangcheck);
830 del_timer_sync(&b->fake_irq);
831 clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings); 843 clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
832} 844}
833 845
@@ -835,15 +847,22 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
835{ 847{
836 struct intel_breadcrumbs *b = &engine->breadcrumbs; 848 struct intel_breadcrumbs *b = &engine->breadcrumbs;
837 849
838 cancel_fake_irq(engine);
839 spin_lock_irq(&b->irq_lock); 850 spin_lock_irq(&b->irq_lock);
840 851
852 /*
853 * Leave the fake_irq timer enabled (if it is running), but clear the
854 * bit so that it turns itself off on its next wake up and goes back
855 * to the long hangcheck interval if still required.
856 */
857 clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
858
841 if (b->irq_enabled) 859 if (b->irq_enabled)
842 irq_enable(engine); 860 irq_enable(engine);
843 else 861 else
844 irq_disable(engine); 862 irq_disable(engine);
845 863
846 /* We set the IRQ_BREADCRUMB bit when we enable the irq presuming the 864 /*
865 * We set the IRQ_BREADCRUMB bit when we enable the irq presuming the
847 * GPU is active and may have already executed the MI_USER_INTERRUPT 866 * GPU is active and may have already executed the MI_USER_INTERRUPT
848 * before the CPU is ready to receive. However, the engine is currently 867 * before the CPU is ready to receive. However, the engine is currently
849 * idle (we haven't started it yet), there is no possibility for a 868 * idle (we haven't started it yet), there is no possibility for a
@@ -852,9 +871,6 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
852 */ 871 */
853 clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted); 872 clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
854 873
855 if (b->irq_armed)
856 enable_fake_irq(b);
857
858 spin_unlock_irq(&b->irq_lock); 874 spin_unlock_irq(&b->irq_lock);
859} 875}
860 876
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index c0a8805b277f..de0e22322c76 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -748,6 +748,11 @@ intel_crt_detect(struct drm_connector *connector,
748 connector->base.id, connector->name, 748 connector->base.id, connector->name,
749 force); 749 force);
750 750
751 if (i915_modparams.load_detect_test) {
752 intel_display_power_get(dev_priv, intel_encoder->power_domain);
753 goto load_detect;
754 }
755
751 /* Skip machines without VGA that falsely report hotplug events */ 756 /* Skip machines without VGA that falsely report hotplug events */
752 if (dmi_check_system(intel_spurious_crt_detect)) 757 if (dmi_check_system(intel_spurious_crt_detect))
753 return connector_status_disconnected; 758 return connector_status_disconnected;
@@ -776,11 +781,12 @@ intel_crt_detect(struct drm_connector *connector,
776 * broken monitor (without edid) to work behind a broken kvm (that fails 781 * broken monitor (without edid) to work behind a broken kvm (that fails
777 * to have the right resistors for HP detection) needs to fix this up. 782 * to have the right resistors for HP detection) needs to fix this up.
778 * For now just bail out. */ 783 * For now just bail out. */
779 if (I915_HAS_HOTPLUG(dev_priv) && !i915_modparams.load_detect_test) { 784 if (I915_HAS_HOTPLUG(dev_priv)) {
780 status = connector_status_disconnected; 785 status = connector_status_disconnected;
781 goto out; 786 goto out;
782 } 787 }
783 788
789load_detect:
784 if (!force) { 790 if (!force) {
785 status = connector->status; 791 status = connector->status;
786 goto out; 792 goto out;
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
index f9550ea46c26..cf9b600cca79 100644
--- a/drivers/gpu/drm/i915/intel_csr.c
+++ b/drivers/gpu/drm/i915/intel_csr.c
@@ -298,7 +298,10 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
298 298
299 csr->version = css_header->version; 299 csr->version = css_header->version;
300 300
301 if (IS_CANNONLAKE(dev_priv)) { 301 if (csr->fw_path == i915_modparams.dmc_firmware_path) {
302 /* Bypass version check for firmware override. */
303 required_version = csr->version;
304 } else if (IS_CANNONLAKE(dev_priv)) {
302 required_version = CNL_CSR_VERSION_REQUIRED; 305 required_version = CNL_CSR_VERSION_REQUIRED;
303 } else if (IS_GEMINILAKE(dev_priv)) { 306 } else if (IS_GEMINILAKE(dev_priv)) {
304 required_version = GLK_CSR_VERSION_REQUIRED; 307 required_version = GLK_CSR_VERSION_REQUIRED;
@@ -453,7 +456,9 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
453 if (!HAS_CSR(dev_priv)) 456 if (!HAS_CSR(dev_priv))
454 return; 457 return;
455 458
456 if (IS_CANNONLAKE(dev_priv)) 459 if (i915_modparams.dmc_firmware_path)
460 csr->fw_path = i915_modparams.dmc_firmware_path;
461 else if (IS_CANNONLAKE(dev_priv))
457 csr->fw_path = I915_CSR_CNL; 462 csr->fw_path = I915_CSR_CNL;
458 else if (IS_GEMINILAKE(dev_priv)) 463 else if (IS_GEMINILAKE(dev_priv))
459 csr->fw_path = I915_CSR_GLK; 464 csr->fw_path = I915_CSR_GLK;
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 8c2d778560f0..b98ac0541f19 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -493,6 +493,125 @@ static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_1_05V[] = {
493 { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */ 493 { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
494}; 494};
495 495
496struct icl_combo_phy_ddi_buf_trans {
497 u32 dw2_swing_select;
498 u32 dw2_swing_scalar;
499 u32 dw4_scaling;
500};
501
502/* Voltage Swing Programming for VccIO 0.85V for DP */
503static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hdmi_0_85V[] = {
504 /* Voltage mV db */
505 { 0x2, 0x98, 0x0018 }, /* 400 0.0 */
506 { 0x2, 0x98, 0x3015 }, /* 400 3.5 */
507 { 0x2, 0x98, 0x6012 }, /* 400 6.0 */
508 { 0x2, 0x98, 0x900F }, /* 400 9.5 */
509 { 0xB, 0x70, 0x0018 }, /* 600 0.0 */
510 { 0xB, 0x70, 0x3015 }, /* 600 3.5 */
511 { 0xB, 0x70, 0x6012 }, /* 600 6.0 */
512 { 0x5, 0x00, 0x0018 }, /* 800 0.0 */
513 { 0x5, 0x00, 0x3015 }, /* 800 3.5 */
514 { 0x6, 0x98, 0x0018 }, /* 1200 0.0 */
515};
516
517/* FIXME - After table is updated in Bspec */
518/* Voltage Swing Programming for VccIO 0.85V for eDP */
519static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_edp_0_85V[] = {
520 /* Voltage mV db */
521 { 0x0, 0x00, 0x00 }, /* 200 0.0 */
522 { 0x0, 0x00, 0x00 }, /* 200 1.5 */
523 { 0x0, 0x00, 0x00 }, /* 200 4.0 */
524 { 0x0, 0x00, 0x00 }, /* 200 6.0 */
525 { 0x0, 0x00, 0x00 }, /* 250 0.0 */
526 { 0x0, 0x00, 0x00 }, /* 250 1.5 */
527 { 0x0, 0x00, 0x00 }, /* 250 4.0 */
528 { 0x0, 0x00, 0x00 }, /* 300 0.0 */
529 { 0x0, 0x00, 0x00 }, /* 300 1.5 */
530 { 0x0, 0x00, 0x00 }, /* 350 0.0 */
531};
532
533/* Voltage Swing Programming for VccIO 0.95V for DP */
534static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hdmi_0_95V[] = {
535 /* Voltage mV db */
536 { 0x2, 0x98, 0x0018 }, /* 400 0.0 */
537 { 0x2, 0x98, 0x3015 }, /* 400 3.5 */
538 { 0x2, 0x98, 0x6012 }, /* 400 6.0 */
539 { 0x2, 0x98, 0x900F }, /* 400 9.5 */
540 { 0x4, 0x98, 0x0018 }, /* 600 0.0 */
541 { 0x4, 0x98, 0x3015 }, /* 600 3.5 */
542 { 0x4, 0x98, 0x6012 }, /* 600 6.0 */
543 { 0x5, 0x76, 0x0018 }, /* 800 0.0 */
544 { 0x5, 0x76, 0x3015 }, /* 800 3.5 */
545 { 0x6, 0x98, 0x0018 }, /* 1200 0.0 */
546};
547
548/* FIXME - After table is updated in Bspec */
549/* Voltage Swing Programming for VccIO 0.95V for eDP */
550static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_edp_0_95V[] = {
551 /* Voltage mV db */
552 { 0x0, 0x00, 0x00 }, /* 200 0.0 */
553 { 0x0, 0x00, 0x00 }, /* 200 1.5 */
554 { 0x0, 0x00, 0x00 }, /* 200 4.0 */
555 { 0x0, 0x00, 0x00 }, /* 200 6.0 */
556 { 0x0, 0x00, 0x00 }, /* 250 0.0 */
557 { 0x0, 0x00, 0x00 }, /* 250 1.5 */
558 { 0x0, 0x00, 0x00 }, /* 250 4.0 */
559 { 0x0, 0x00, 0x00 }, /* 300 0.0 */
560 { 0x0, 0x00, 0x00 }, /* 300 1.5 */
561 { 0x0, 0x00, 0x00 }, /* 350 0.0 */
562};
563
564/* Voltage Swing Programming for VccIO 1.05V for DP */
565static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hdmi_1_05V[] = {
566 /* Voltage mV db */
567 { 0x2, 0x98, 0x0018 }, /* 400 0.0 */
568 { 0x2, 0x98, 0x3015 }, /* 400 3.5 */
569 { 0x2, 0x98, 0x6012 }, /* 400 6.0 */
570 { 0x2, 0x98, 0x900F }, /* 400 9.5 */
571 { 0x4, 0x98, 0x0018 }, /* 600 0.0 */
572 { 0x4, 0x98, 0x3015 }, /* 600 3.5 */
573 { 0x4, 0x98, 0x6012 }, /* 600 6.0 */
574 { 0x5, 0x71, 0x0018 }, /* 800 0.0 */
575 { 0x5, 0x71, 0x3015 }, /* 800 3.5 */
576 { 0x6, 0x98, 0x0018 }, /* 1200 0.0 */
577};
578
579/* FIXME - After table is updated in Bspec */
580/* Voltage Swing Programming for VccIO 1.05V for eDP */
581static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_edp_1_05V[] = {
582 /* Voltage mV db */
583 { 0x0, 0x00, 0x00 }, /* 200 0.0 */
584 { 0x0, 0x00, 0x00 }, /* 200 1.5 */
585 { 0x0, 0x00, 0x00 }, /* 200 4.0 */
586 { 0x0, 0x00, 0x00 }, /* 200 6.0 */
587 { 0x0, 0x00, 0x00 }, /* 250 0.0 */
588 { 0x0, 0x00, 0x00 }, /* 250 1.5 */
589 { 0x0, 0x00, 0x00 }, /* 250 4.0 */
590 { 0x0, 0x00, 0x00 }, /* 300 0.0 */
591 { 0x0, 0x00, 0x00 }, /* 300 1.5 */
592 { 0x0, 0x00, 0x00 }, /* 350 0.0 */
593};
594
595struct icl_mg_phy_ddi_buf_trans {
596 u32 cri_txdeemph_override_5_0;
597 u32 cri_txdeemph_override_11_6;
598 u32 cri_txdeemph_override_17_12;
599};
600
601static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations[] = {
602 /* Voltage swing pre-emphasis */
603 { 0x0, 0x1B, 0x00 }, /* 0 0 */
604 { 0x0, 0x23, 0x08 }, /* 0 1 */
605 { 0x0, 0x2D, 0x12 }, /* 0 2 */
606 { 0x0, 0x00, 0x00 }, /* 0 3 */
607 { 0x0, 0x23, 0x00 }, /* 1 0 */
608 { 0x0, 0x2B, 0x09 }, /* 1 1 */
609 { 0x0, 0x2E, 0x11 }, /* 1 2 */
610 { 0x0, 0x2F, 0x00 }, /* 2 0 */
611 { 0x0, 0x33, 0x0C }, /* 2 1 */
612 { 0x0, 0x00, 0x00 }, /* 3 0 */
613};
614
496static const struct ddi_buf_trans * 615static const struct ddi_buf_trans *
497bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) 616bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
498{ 617{
@@ -751,6 +870,45 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
751 } 870 }
752} 871}
753 872
873static const struct icl_combo_phy_ddi_buf_trans *
874icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, enum port port,
875 int type, int *n_entries)
876{
877 u32 voltage = I915_READ(ICL_PORT_COMP_DW3(port)) & VOLTAGE_INFO_MASK;
878
879 if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
880 switch (voltage) {
881 case VOLTAGE_INFO_0_85V:
882 *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);
883 return icl_combo_phy_ddi_translations_edp_0_85V;
884 case VOLTAGE_INFO_0_95V:
885 *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);
886 return icl_combo_phy_ddi_translations_edp_0_95V;
887 case VOLTAGE_INFO_1_05V:
888 *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);
889 return icl_combo_phy_ddi_translations_edp_1_05V;
890 default:
891 MISSING_CASE(voltage);
892 return NULL;
893 }
894 } else {
895 switch (voltage) {
896 case VOLTAGE_INFO_0_85V:
897 *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);
898 return icl_combo_phy_ddi_translations_dp_hdmi_0_85V;
899 case VOLTAGE_INFO_0_95V:
900 *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);
901 return icl_combo_phy_ddi_translations_dp_hdmi_0_95V;
902 case VOLTAGE_INFO_1_05V:
903 *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);
904 return icl_combo_phy_ddi_translations_dp_hdmi_1_05V;
905 default:
906 MISSING_CASE(voltage);
907 return NULL;
908 }
909 }
910}
911
754static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port) 912static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port)
755{ 913{
756 int n_entries, level, default_entry; 914 int n_entries, level, default_entry;
@@ -875,7 +1033,7 @@ static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
875 1033
876static uint32_t hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll) 1034static uint32_t hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
877{ 1035{
878 switch (pll->id) { 1036 switch (pll->info->id) {
879 case DPLL_ID_WRPLL1: 1037 case DPLL_ID_WRPLL1:
880 return PORT_CLK_SEL_WRPLL1; 1038 return PORT_CLK_SEL_WRPLL1;
881 case DPLL_ID_WRPLL2: 1039 case DPLL_ID_WRPLL2:
@@ -889,11 +1047,30 @@ static uint32_t hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
889 case DPLL_ID_LCPLL_2700: 1047 case DPLL_ID_LCPLL_2700:
890 return PORT_CLK_SEL_LCPLL_2700; 1048 return PORT_CLK_SEL_LCPLL_2700;
891 default: 1049 default:
892 MISSING_CASE(pll->id); 1050 MISSING_CASE(pll->info->id);
893 return PORT_CLK_SEL_NONE; 1051 return PORT_CLK_SEL_NONE;
894 } 1052 }
895} 1053}
896 1054
1055static uint32_t icl_pll_to_ddi_pll_sel(struct intel_encoder *encoder,
1056 const struct intel_shared_dpll *pll)
1057{
1058 const enum intel_dpll_id id = pll->info->id;
1059
1060 switch (id) {
1061 default:
1062 MISSING_CASE(id);
1063 case DPLL_ID_ICL_DPLL0:
1064 case DPLL_ID_ICL_DPLL1:
1065 return DDI_CLK_SEL_NONE;
1066 case DPLL_ID_ICL_MGPLL1:
1067 case DPLL_ID_ICL_MGPLL2:
1068 case DPLL_ID_ICL_MGPLL3:
1069 case DPLL_ID_ICL_MGPLL4:
1070 return DDI_CLK_SEL_MG;
1071 }
1072}
1073
897/* Starting with Haswell, different DDI ports can work in FDI mode for 1074/* Starting with Haswell, different DDI ports can work in FDI mode for
898 * connection to the PCH-located connectors. For this, it is necessary to train 1075 * connection to the PCH-located connectors. For this, it is necessary to train
899 * both the DDI port and PCH receiver for the desired DDI buffer settings. 1076 * both the DDI port and PCH receiver for the desired DDI buffer settings.
@@ -1906,7 +2083,13 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
1906 enum port port = encoder->port; 2083 enum port port = encoder->port;
1907 int n_entries; 2084 int n_entries;
1908 2085
1909 if (IS_CANNONLAKE(dev_priv)) { 2086 if (IS_ICELAKE(dev_priv)) {
2087 if (port == PORT_A || port == PORT_B)
2088 icl_get_combo_buf_trans(dev_priv, port, encoder->type,
2089 &n_entries);
2090 else
2091 n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
2092 } else if (IS_CANNONLAKE(dev_priv)) {
1910 if (encoder->type == INTEL_OUTPUT_EDP) 2093 if (encoder->type == INTEL_OUTPUT_EDP)
1911 cnl_get_buf_trans_edp(dev_priv, &n_entries); 2094 cnl_get_buf_trans_edp(dev_priv, &n_entries);
1912 else 2095 else
@@ -2063,6 +2246,146 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
2063 I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val); 2246 I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
2064} 2247}
2065 2248
2249static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
2250 u32 level, enum port port, int type)
2251{
2252 const struct icl_combo_phy_ddi_buf_trans *ddi_translations = NULL;
2253 u32 n_entries, val;
2254 int ln;
2255
2256 ddi_translations = icl_get_combo_buf_trans(dev_priv, port, type,
2257 &n_entries);
2258 if (!ddi_translations)
2259 return;
2260
2261 if (level >= n_entries) {
2262 DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1);
2263 level = n_entries - 1;
2264 }
2265
2266 /* Set PORT_TX_DW5 Rterm Sel to 110b. */
2267 val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
2268 val &= ~RTERM_SELECT_MASK;
2269 val |= RTERM_SELECT(0x6);
2270 I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
2271
2272 /* Program PORT_TX_DW5 */
2273 val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
2274 /* Set DisableTap2 and DisableTap3 if MIPI DSI
2275 * Clear DisableTap2 and DisableTap3 for all other Ports
2276 */
2277 if (type == INTEL_OUTPUT_DSI) {
2278 val |= TAP2_DISABLE;
2279 val |= TAP3_DISABLE;
2280 } else {
2281 val &= ~TAP2_DISABLE;
2282 val &= ~TAP3_DISABLE;
2283 }
2284 I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
2285
2286 /* Program PORT_TX_DW2 */
2287 val = I915_READ(ICL_PORT_TX_DW2_LN0(port));
2288 val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
2289 RCOMP_SCALAR_MASK);
2290 val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_select);
2291 val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_select);
2292 /* Program Rcomp scalar for every table entry */
2293 val |= RCOMP_SCALAR(ddi_translations[level].dw2_swing_scalar);
2294 I915_WRITE(ICL_PORT_TX_DW2_GRP(port), val);
2295
2296 /* Program PORT_TX_DW4 */
2297 /* We cannot write to GRP. It would overwrite individual loadgen. */
2298 for (ln = 0; ln <= 3; ln++) {
2299 val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
2300 val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
2301 CURSOR_COEFF_MASK);
2302 val |= ddi_translations[level].dw4_scaling;
2303 I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
2304 }
2305}
2306
2307static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
2308 u32 level,
2309 enum intel_output_type type)
2310{
2311 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2312 enum port port = encoder->port;
2313 int width = 0;
2314 int rate = 0;
2315 u32 val;
2316 int ln = 0;
2317
2318 if (type == INTEL_OUTPUT_HDMI) {
2319 width = 4;
2320 /* Rate is always < than 6GHz for HDMI */
2321 } else {
2322 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
2323
2324 width = intel_dp->lane_count;
2325 rate = intel_dp->link_rate;
2326 }
2327
2328 /*
2329 * 1. If port type is eDP or DP,
2330 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
2331 * else clear to 0b.
2332 */
2333 val = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
2334 if (type == INTEL_OUTPUT_HDMI)
2335 val &= ~COMMON_KEEPER_EN;
2336 else
2337 val |= COMMON_KEEPER_EN;
2338 I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), val);
2339
2340 /* 2. Program loadgen select */
2341 /*
2342 * Program PORT_TX_DW4_LN depending on Bit rate and used lanes
2343 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
2344 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
2345 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
2346 */
2347 for (ln = 0; ln <= 3; ln++) {
2348 val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
2349 val &= ~LOADGEN_SELECT;
2350
2351 if ((rate <= 600000 && width == 4 && ln >= 1) ||
2352 (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
2353 val |= LOADGEN_SELECT;
2354 }
2355 I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
2356 }
2357
2358 /* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
2359 val = I915_READ(ICL_PORT_CL_DW5(port));
2360 val |= SUS_CLOCK_CONFIG;
2361 I915_WRITE(ICL_PORT_CL_DW5(port), val);
2362
2363 /* 4. Clear training enable to change swing values */
2364 val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
2365 val &= ~TX_TRAINING_EN;
2366 I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
2367
2368 /* 5. Program swing and de-emphasis */
2369 icl_ddi_combo_vswing_program(dev_priv, level, port, type);
2370
2371 /* 6. Set training enable to trigger update */
2372 val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
2373 val |= TX_TRAINING_EN;
2374 I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
2375}
2376
2377static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level,
2378 enum intel_output_type type)
2379{
2380 enum port port = encoder->port;
2381
2382 if (port == PORT_A || port == PORT_B)
2383 icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
2384 else
2385 /* Not Implemented Yet */
2386 WARN_ON(1);
2387}
2388
2066static uint32_t translate_signal_level(int signal_levels) 2389static uint32_t translate_signal_level(int signal_levels)
2067{ 2390{
2068 int i; 2391 int i;
@@ -2094,7 +2417,9 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp)
2094 struct intel_encoder *encoder = &dport->base; 2417 struct intel_encoder *encoder = &dport->base;
2095 int level = intel_ddi_dp_level(intel_dp); 2418 int level = intel_ddi_dp_level(intel_dp);
2096 2419
2097 if (IS_CANNONLAKE(dev_priv)) 2420 if (IS_ICELAKE(dev_priv))
2421 icl_ddi_vswing_sequence(encoder, level, encoder->type);
2422 else if (IS_CANNONLAKE(dev_priv))
2098 cnl_ddi_vswing_sequence(encoder, level, encoder->type); 2423 cnl_ddi_vswing_sequence(encoder, level, encoder->type);
2099 else 2424 else
2100 bxt_ddi_vswing_sequence(encoder, level, encoder->type); 2425 bxt_ddi_vswing_sequence(encoder, level, encoder->type);
@@ -2115,6 +2440,69 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2115 return DDI_BUF_TRANS_SELECT(level); 2440 return DDI_BUF_TRANS_SELECT(level);
2116} 2441}
2117 2442
2443void icl_map_plls_to_ports(struct drm_crtc *crtc,
2444 struct intel_crtc_state *crtc_state,
2445 struct drm_atomic_state *old_state)
2446{
2447 struct intel_shared_dpll *pll = crtc_state->shared_dpll;
2448 struct drm_i915_private *dev_priv = to_i915(crtc->dev);
2449 struct drm_connector_state *conn_state;
2450 struct drm_connector *conn;
2451 int i;
2452
2453 for_each_new_connector_in_state(old_state, conn, conn_state, i) {
2454 struct intel_encoder *encoder =
2455 to_intel_encoder(conn_state->best_encoder);
2456 enum port port = encoder->port;
2457 uint32_t val;
2458
2459 if (conn_state->crtc != crtc)
2460 continue;
2461
2462 mutex_lock(&dev_priv->dpll_lock);
2463
2464 val = I915_READ(DPCLKA_CFGCR0_ICL);
2465 WARN_ON((val & DPCLKA_CFGCR0_DDI_CLK_OFF(port)) == 0);
2466
2467 if (port == PORT_A || port == PORT_B) {
2468 val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
2469 val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port);
2470 I915_WRITE(DPCLKA_CFGCR0_ICL, val);
2471 POSTING_READ(DPCLKA_CFGCR0_ICL);
2472 }
2473
2474 val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
2475 I915_WRITE(DPCLKA_CFGCR0_ICL, val);
2476
2477 mutex_unlock(&dev_priv->dpll_lock);
2478 }
2479}
2480
2481void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
2482 struct intel_crtc_state *crtc_state,
2483 struct drm_atomic_state *old_state)
2484{
2485 struct drm_i915_private *dev_priv = to_i915(crtc->dev);
2486 struct drm_connector_state *old_conn_state;
2487 struct drm_connector *conn;
2488 int i;
2489
2490 for_each_old_connector_in_state(old_state, conn, old_conn_state, i) {
2491 struct intel_encoder *encoder =
2492 to_intel_encoder(old_conn_state->best_encoder);
2493 enum port port = encoder->port;
2494
2495 if (old_conn_state->crtc != crtc)
2496 continue;
2497
2498 mutex_lock(&dev_priv->dpll_lock);
2499 I915_WRITE(DPCLKA_CFGCR0_ICL,
2500 I915_READ(DPCLKA_CFGCR0_ICL) |
2501 DPCLKA_CFGCR0_DDI_CLK_OFF(port));
2502 mutex_unlock(&dev_priv->dpll_lock);
2503 }
2504}
2505
2118static void intel_ddi_clk_select(struct intel_encoder *encoder, 2506static void intel_ddi_clk_select(struct intel_encoder *encoder,
2119 const struct intel_shared_dpll *pll) 2507 const struct intel_shared_dpll *pll)
2120{ 2508{
@@ -2127,11 +2515,15 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
2127 2515
2128 mutex_lock(&dev_priv->dpll_lock); 2516 mutex_lock(&dev_priv->dpll_lock);
2129 2517
2130 if (IS_CANNONLAKE(dev_priv)) { 2518 if (IS_ICELAKE(dev_priv)) {
2519 if (port >= PORT_C)
2520 I915_WRITE(DDI_CLK_SEL(port),
2521 icl_pll_to_ddi_pll_sel(encoder, pll));
2522 } else if (IS_CANNONLAKE(dev_priv)) {
2131 /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */ 2523 /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */
2132 val = I915_READ(DPCLKA_CFGCR0); 2524 val = I915_READ(DPCLKA_CFGCR0);
2133 val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port); 2525 val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
2134 val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->id, port); 2526 val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port);
2135 I915_WRITE(DPCLKA_CFGCR0, val); 2527 I915_WRITE(DPCLKA_CFGCR0, val);
2136 2528
2137 /* 2529 /*
@@ -2148,7 +2540,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
2148 2540
2149 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) | 2541 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2150 DPLL_CTRL2_DDI_CLK_SEL_MASK(port)); 2542 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2151 val |= (DPLL_CTRL2_DDI_CLK_SEL(pll->id, port) | 2543 val |= (DPLL_CTRL2_DDI_CLK_SEL(pll->info->id, port) |
2152 DPLL_CTRL2_DDI_SEL_OVERRIDE(port)); 2544 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2153 2545
2154 I915_WRITE(DPLL_CTRL2, val); 2546 I915_WRITE(DPLL_CTRL2, val);
@@ -2165,14 +2557,18 @@ static void intel_ddi_clk_disable(struct intel_encoder *encoder)
2165 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2557 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2166 enum port port = encoder->port; 2558 enum port port = encoder->port;
2167 2559
2168 if (IS_CANNONLAKE(dev_priv)) 2560 if (IS_ICELAKE(dev_priv)) {
2561 if (port >= PORT_C)
2562 I915_WRITE(DDI_CLK_SEL(port), DDI_CLK_SEL_NONE);
2563 } else if (IS_CANNONLAKE(dev_priv)) {
2169 I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) | 2564 I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) |
2170 DPCLKA_CFGCR0_DDI_CLK_OFF(port)); 2565 DPCLKA_CFGCR0_DDI_CLK_OFF(port));
2171 else if (IS_GEN9_BC(dev_priv)) 2566 } else if (IS_GEN9_BC(dev_priv)) {
2172 I915_WRITE(DPLL_CTRL2, I915_READ(DPLL_CTRL2) | 2567 I915_WRITE(DPLL_CTRL2, I915_READ(DPLL_CTRL2) |
2173 DPLL_CTRL2_DDI_CLK_OFF(port)); 2568 DPLL_CTRL2_DDI_CLK_OFF(port));
2174 else if (INTEL_GEN(dev_priv) < 9) 2569 } else if (INTEL_GEN(dev_priv) < 9) {
2175 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); 2570 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
2571 }
2176} 2572}
2177 2573
2178static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, 2574static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
@@ -2197,7 +2593,9 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
2197 2593
2198 intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); 2594 intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
2199 2595
2200 if (IS_CANNONLAKE(dev_priv)) 2596 if (IS_ICELAKE(dev_priv))
2597 icl_ddi_vswing_sequence(encoder, level, encoder->type);
2598 else if (IS_CANNONLAKE(dev_priv))
2201 cnl_ddi_vswing_sequence(encoder, level, encoder->type); 2599 cnl_ddi_vswing_sequence(encoder, level, encoder->type);
2202 else if (IS_GEN9_LP(dev_priv)) 2600 else if (IS_GEN9_LP(dev_priv))
2203 bxt_ddi_vswing_sequence(encoder, level, encoder->type); 2601 bxt_ddi_vswing_sequence(encoder, level, encoder->type);
@@ -2205,7 +2603,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
2205 intel_prepare_dp_ddi_buffers(encoder, crtc_state); 2603 intel_prepare_dp_ddi_buffers(encoder, crtc_state);
2206 2604
2207 intel_ddi_init_dp_buf_reg(encoder); 2605 intel_ddi_init_dp_buf_reg(encoder);
2208 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); 2606 if (!is_mst)
2607 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2209 intel_dp_start_link_train(intel_dp); 2608 intel_dp_start_link_train(intel_dp);
2210 if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) 2609 if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
2211 intel_dp_stop_link_train(intel_dp); 2610 intel_dp_stop_link_train(intel_dp);
@@ -2227,7 +2626,9 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
2227 2626
2228 intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); 2627 intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
2229 2628
2230 if (IS_CANNONLAKE(dev_priv)) 2629 if (IS_ICELAKE(dev_priv))
2630 icl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
2631 else if (IS_CANNONLAKE(dev_priv))
2231 cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); 2632 cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
2232 else if (IS_GEN9_LP(dev_priv)) 2633 else if (IS_GEN9_LP(dev_priv))
2233 bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); 2634 bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
@@ -2303,12 +2704,15 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
2303 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2704 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2304 struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); 2705 struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
2305 struct intel_dp *intel_dp = &dig_port->dp; 2706 struct intel_dp *intel_dp = &dig_port->dp;
2707 bool is_mst = intel_crtc_has_type(old_crtc_state,
2708 INTEL_OUTPUT_DP_MST);
2306 2709
2307 /* 2710 /*
2308 * Power down sink before disabling the port, otherwise we end 2711 * Power down sink before disabling the port, otherwise we end
2309 * up getting interrupts from the sink on detecting link loss. 2712 * up getting interrupts from the sink on detecting link loss.
2310 */ 2713 */
2311 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); 2714 if (!is_mst)
2715 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
2312 2716
2313 intel_disable_ddi_buf(encoder); 2717 intel_disable_ddi_buf(encoder);
2314 2718
@@ -2424,12 +2828,14 @@ static void intel_enable_ddi_hdmi(struct intel_encoder *encoder,
2424{ 2828{
2425 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2829 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2426 struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); 2830 struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
2831 struct drm_connector *connector = conn_state->connector;
2427 enum port port = encoder->port; 2832 enum port port = encoder->port;
2428 2833
2429 intel_hdmi_handle_sink_scrambling(encoder, 2834 if (!intel_hdmi_handle_sink_scrambling(encoder, connector,
2430 conn_state->connector, 2835 crtc_state->hdmi_high_tmds_clock_ratio,
2431 crtc_state->hdmi_high_tmds_clock_ratio, 2836 crtc_state->hdmi_scrambling))
2432 crtc_state->hdmi_scrambling); 2837 DRM_ERROR("[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n",
2838 connector->base.id, connector->name);
2433 2839
2434 /* Display WA #1143: skl,kbl,cfl */ 2840 /* Display WA #1143: skl,kbl,cfl */
2435 if (IS_GEN9_BC(dev_priv)) { 2841 if (IS_GEN9_BC(dev_priv)) {
@@ -2520,13 +2926,16 @@ static void intel_disable_ddi_hdmi(struct intel_encoder *encoder,
2520 const struct intel_crtc_state *old_crtc_state, 2926 const struct intel_crtc_state *old_crtc_state,
2521 const struct drm_connector_state *old_conn_state) 2927 const struct drm_connector_state *old_conn_state)
2522{ 2928{
2929 struct drm_connector *connector = old_conn_state->connector;
2930
2523 if (old_crtc_state->has_audio) 2931 if (old_crtc_state->has_audio)
2524 intel_audio_codec_disable(encoder, 2932 intel_audio_codec_disable(encoder,
2525 old_crtc_state, old_conn_state); 2933 old_crtc_state, old_conn_state);
2526 2934
2527 intel_hdmi_handle_sink_scrambling(encoder, 2935 if (!intel_hdmi_handle_sink_scrambling(encoder, connector,
2528 old_conn_state->connector, 2936 false, false))
2529 false, false); 2937 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Failed to reset sink scrambling/TMDS bit clock ratio\n",
2938 connector->base.id, connector->name);
2530} 2939}
2531 2940
2532static void intel_disable_ddi(struct intel_encoder *encoder, 2941static void intel_disable_ddi(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index 3dd350f7b8e6..0fd13df424cf 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -83,11 +83,11 @@ static void sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p)
83{ 83{
84 int s; 84 int s;
85 85
86 drm_printf(p, "slice mask: %04x\n", sseu->slice_mask); 86 drm_printf(p, "slice total: %u, mask=%04x\n",
87 drm_printf(p, "slice total: %u\n", hweight8(sseu->slice_mask)); 87 hweight8(sseu->slice_mask), sseu->slice_mask);
88 drm_printf(p, "subslice total: %u\n", sseu_subslice_total(sseu)); 88 drm_printf(p, "subslice total: %u\n", sseu_subslice_total(sseu));
89 for (s = 0; s < ARRAY_SIZE(sseu->subslice_mask); s++) { 89 for (s = 0; s < sseu->max_slices; s++) {
90 drm_printf(p, "slice%d %u subslices mask=%04x\n", 90 drm_printf(p, "slice%d: %u subslices, mask=%04x\n",
91 s, hweight8(sseu->subslice_mask[s]), 91 s, hweight8(sseu->subslice_mask[s]),
92 sseu->subslice_mask[s]); 92 sseu->subslice_mask[s]);
93 } 93 }
@@ -158,6 +158,45 @@ static u16 compute_eu_total(const struct sseu_dev_info *sseu)
158 return total; 158 return total;
159} 159}
160 160
161static void gen11_sseu_info_init(struct drm_i915_private *dev_priv)
162{
163 struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu;
164 u8 s_en;
165 u32 ss_en, ss_en_mask;
166 u8 eu_en;
167 int s;
168
169 sseu->max_slices = 1;
170 sseu->max_subslices = 8;
171 sseu->max_eus_per_subslice = 8;
172
173 s_en = I915_READ(GEN11_GT_SLICE_ENABLE) & GEN11_GT_S_ENA_MASK;
174 ss_en = ~I915_READ(GEN11_GT_SUBSLICE_DISABLE);
175 ss_en_mask = BIT(sseu->max_subslices) - 1;
176 eu_en = ~(I915_READ(GEN11_EU_DISABLE) & GEN11_EU_DIS_MASK);
177
178 for (s = 0; s < sseu->max_slices; s++) {
179 if (s_en & BIT(s)) {
180 int ss_idx = sseu->max_subslices * s;
181 int ss;
182
183 sseu->slice_mask |= BIT(s);
184 sseu->subslice_mask[s] = (ss_en >> ss_idx) & ss_en_mask;
185 for (ss = 0; ss < sseu->max_subslices; ss++) {
186 if (sseu->subslice_mask[s] & BIT(ss))
187 sseu_set_eus(sseu, s, ss, eu_en);
188 }
189 }
190 }
191 sseu->eu_per_subslice = hweight8(eu_en);
192 sseu->eu_total = compute_eu_total(sseu);
193
194 /* ICL has no power gating restrictions. */
195 sseu->has_slice_pg = 1;
196 sseu->has_subslice_pg = 1;
197 sseu->has_eu_pg = 1;
198}
199
161static void gen10_sseu_info_init(struct drm_i915_private *dev_priv) 200static void gen10_sseu_info_init(struct drm_i915_private *dev_priv)
162{ 201{
163 struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu; 202 struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu;
@@ -557,6 +596,52 @@ static u32 read_reference_ts_freq(struct drm_i915_private *dev_priv)
557 return base_freq + frac_freq; 596 return base_freq + frac_freq;
558} 597}
559 598
599static u32 gen10_get_crystal_clock_freq(struct drm_i915_private *dev_priv,
600 u32 rpm_config_reg)
601{
602 u32 f19_2_mhz = 19200;
603 u32 f24_mhz = 24000;
604 u32 crystal_clock = (rpm_config_reg &
605 GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>
606 GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;
607
608 switch (crystal_clock) {
609 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
610 return f19_2_mhz;
611 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
612 return f24_mhz;
613 default:
614 MISSING_CASE(crystal_clock);
615 return 0;
616 }
617}
618
619static u32 gen11_get_crystal_clock_freq(struct drm_i915_private *dev_priv,
620 u32 rpm_config_reg)
621{
622 u32 f19_2_mhz = 19200;
623 u32 f24_mhz = 24000;
624 u32 f25_mhz = 25000;
625 u32 f38_4_mhz = 38400;
626 u32 crystal_clock = (rpm_config_reg &
627 GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>
628 GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;
629
630 switch (crystal_clock) {
631 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
632 return f24_mhz;
633 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
634 return f19_2_mhz;
635 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ:
636 return f38_4_mhz;
637 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ:
638 return f25_mhz;
639 default:
640 MISSING_CASE(crystal_clock);
641 return 0;
642 }
643}
644
560static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv) 645static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv)
561{ 646{
562 u32 f12_5_mhz = 12500; 647 u32 f12_5_mhz = 12500;
@@ -597,10 +682,9 @@ static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv)
597 } 682 }
598 683
599 return freq; 684 return freq;
600 } else if (INTEL_GEN(dev_priv) <= 10) { 685 } else if (INTEL_GEN(dev_priv) <= 11) {
601 u32 ctc_reg = I915_READ(CTC_MODE); 686 u32 ctc_reg = I915_READ(CTC_MODE);
602 u32 freq = 0; 687 u32 freq = 0;
603 u32 rpm_config_reg = 0;
604 688
605 /* First figure out the reference frequency. There are 2 ways 689 /* First figure out the reference frequency. There are 2 ways
606 * we can compute the frequency, either through the 690 * we can compute the frequency, either through the
@@ -610,20 +694,14 @@ static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv)
610 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { 694 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {
611 freq = read_reference_ts_freq(dev_priv); 695 freq = read_reference_ts_freq(dev_priv);
612 } else { 696 } else {
613 u32 crystal_clock; 697 u32 rpm_config_reg = I915_READ(RPM_CONFIG0);
614 698
615 rpm_config_reg = I915_READ(RPM_CONFIG0); 699 if (INTEL_GEN(dev_priv) <= 10)
616 crystal_clock = (rpm_config_reg & 700 freq = gen10_get_crystal_clock_freq(dev_priv,
617 GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >> 701 rpm_config_reg);
618 GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT; 702 else
619 switch (crystal_clock) { 703 freq = gen11_get_crystal_clock_freq(dev_priv,
620 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ: 704 rpm_config_reg);
621 freq = f19_2_mhz;
622 break;
623 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
624 freq = f24_mhz;
625 break;
626 }
627 705
628 /* Now figure out how the command stream's timestamp 706 /* Now figure out how the command stream's timestamp
629 * register increments from this frequency (it might 707 * register increments from this frequency (it might
@@ -768,8 +846,10 @@ void intel_device_info_runtime_init(struct intel_device_info *info)
768 broadwell_sseu_info_init(dev_priv); 846 broadwell_sseu_info_init(dev_priv);
769 else if (INTEL_GEN(dev_priv) == 9) 847 else if (INTEL_GEN(dev_priv) == 9)
770 gen9_sseu_info_init(dev_priv); 848 gen9_sseu_info_init(dev_priv);
771 else if (INTEL_GEN(dev_priv) >= 10) 849 else if (INTEL_GEN(dev_priv) == 10)
772 gen10_sseu_info_init(dev_priv); 850 gen10_sseu_info_init(dev_priv);
851 else if (INTEL_GEN(dev_priv) >= 11)
852 gen11_sseu_info_init(dev_priv);
773 853
774 /* Initialize command stream timestamp frequency */ 854 /* Initialize command stream timestamp frequency */
775 info->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv); 855 info->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv);
@@ -780,3 +860,50 @@ void intel_driver_caps_print(const struct intel_driver_caps *caps,
780{ 860{
781 drm_printf(p, "scheduler: %x\n", caps->scheduler); 861 drm_printf(p, "scheduler: %x\n", caps->scheduler);
782} 862}
863
864/*
865 * Determine which engines are fused off in our particular hardware. Since the
866 * fuse register is in the blitter powerwell, we need forcewake to be ready at
867 * this point (but later we need to prune the forcewake domains for engines that
868 * are indeed fused off).
869 */
870void intel_device_info_init_mmio(struct drm_i915_private *dev_priv)
871{
872 struct intel_device_info *info = mkwrite_device_info(dev_priv);
873 u8 vdbox_disable, vebox_disable;
874 u32 media_fuse;
875 int i;
876
877 if (INTEL_GEN(dev_priv) < 11)
878 return;
879
880 media_fuse = I915_READ(GEN11_GT_VEBOX_VDBOX_DISABLE);
881
882 vdbox_disable = media_fuse & GEN11_GT_VDBOX_DISABLE_MASK;
883 vebox_disable = (media_fuse & GEN11_GT_VEBOX_DISABLE_MASK) >>
884 GEN11_GT_VEBOX_DISABLE_SHIFT;
885
886 DRM_DEBUG_DRIVER("vdbox disable: %04x\n", vdbox_disable);
887 for (i = 0; i < I915_MAX_VCS; i++) {
888 if (!HAS_ENGINE(dev_priv, _VCS(i)))
889 continue;
890
891 if (!(BIT(i) & vdbox_disable))
892 continue;
893
894 info->ring_mask &= ~ENGINE_MASK(_VCS(i));
895 DRM_DEBUG_DRIVER("vcs%u fused off\n", i);
896 }
897
898 DRM_DEBUG_DRIVER("vebox disable: %04x\n", vebox_disable);
899 for (i = 0; i < I915_MAX_VECS; i++) {
900 if (!HAS_ENGINE(dev_priv, _VECS(i)))
901 continue;
902
903 if (!(BIT(i) & vebox_disable))
904 continue;
905
906 info->ring_mask &= ~ENGINE_MASK(_VECS(i));
907 DRM_DEBUG_DRIVER("vecs%u fused off\n", i);
908 }
909}
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index 0835752c8b22..933e31669557 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -114,7 +114,7 @@ enum intel_platform {
114 func(has_ipc); 114 func(has_ipc);
115 115
116#define GEN_MAX_SLICES (6) /* CNL upper bound */ 116#define GEN_MAX_SLICES (6) /* CNL upper bound */
117#define GEN_MAX_SUBSLICES (7) 117#define GEN_MAX_SUBSLICES (8) /* ICL upper bound */
118 118
119struct sseu_dev_info { 119struct sseu_dev_info {
120 u8 slice_mask; 120 u8 slice_mask;
@@ -247,6 +247,8 @@ void intel_device_info_dump_runtime(const struct intel_device_info *info,
247void intel_device_info_dump_topology(const struct sseu_dev_info *sseu, 247void intel_device_info_dump_topology(const struct sseu_dev_info *sseu,
248 struct drm_printer *p); 248 struct drm_printer *p);
249 249
250void intel_device_info_init_mmio(struct drm_i915_private *dev_priv);
251
250void intel_driver_caps_print(const struct intel_driver_caps *caps, 252void intel_driver_caps_print(const struct intel_driver_caps *caps,
251 struct drm_printer *p); 253 struct drm_printer *p);
252 254
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 56004ffbd8bb..ad588d564198 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -88,6 +88,22 @@ static const uint32_t skl_primary_formats[] = {
88 DRM_FORMAT_VYUY, 88 DRM_FORMAT_VYUY,
89}; 89};
90 90
91static const uint32_t skl_pri_planar_formats[] = {
92 DRM_FORMAT_C8,
93 DRM_FORMAT_RGB565,
94 DRM_FORMAT_XRGB8888,
95 DRM_FORMAT_XBGR8888,
96 DRM_FORMAT_ARGB8888,
97 DRM_FORMAT_ABGR8888,
98 DRM_FORMAT_XRGB2101010,
99 DRM_FORMAT_XBGR2101010,
100 DRM_FORMAT_YUYV,
101 DRM_FORMAT_YVYU,
102 DRM_FORMAT_UYVY,
103 DRM_FORMAT_VYUY,
104 DRM_FORMAT_NV12,
105};
106
91static const uint64_t skl_format_modifiers_noccs[] = { 107static const uint64_t skl_format_modifiers_noccs[] = {
92 I915_FORMAT_MOD_Yf_TILED, 108 I915_FORMAT_MOD_Yf_TILED,
93 I915_FORMAT_MOD_Y_TILED, 109 I915_FORMAT_MOD_Y_TILED,
@@ -488,6 +504,33 @@ static const struct intel_limit intel_limits_bxt = {
488 .p2 = { .p2_slow = 1, .p2_fast = 20 }, 504 .p2 = { .p2_slow = 1, .p2_fast = 20 },
489}; 505};
490 506
507static void
508skl_wa_528(struct drm_i915_private *dev_priv, int pipe, bool enable)
509{
510 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
511 return;
512
513 if (enable)
514 I915_WRITE(CHICKEN_PIPESL_1(pipe), HSW_FBCQ_DIS);
515 else
516 I915_WRITE(CHICKEN_PIPESL_1(pipe), 0);
517}
518
519static void
520skl_wa_clkgate(struct drm_i915_private *dev_priv, int pipe, bool enable)
521{
522 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
523 return;
524
525 if (enable)
526 I915_WRITE(CLKGATE_DIS_PSL(pipe),
527 DUPS1_GATING_DIS | DUPS2_GATING_DIS);
528 else
529 I915_WRITE(CLKGATE_DIS_PSL(pipe),
530 I915_READ(CLKGATE_DIS_PSL(pipe)) &
531 ~(DUPS1_GATING_DIS | DUPS2_GATING_DIS));
532}
533
491static bool 534static bool
492needs_modeset(const struct drm_crtc_state *state) 535needs_modeset(const struct drm_crtc_state *state)
493{ 536{
@@ -2657,11 +2700,13 @@ static int i9xx_format_to_fourcc(int format)
2657 } 2700 }
2658} 2701}
2659 2702
2660static int skl_format_to_fourcc(int format, bool rgb_order, bool alpha) 2703int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
2661{ 2704{
2662 switch (format) { 2705 switch (format) {
2663 case PLANE_CTL_FORMAT_RGB_565: 2706 case PLANE_CTL_FORMAT_RGB_565:
2664 return DRM_FORMAT_RGB565; 2707 return DRM_FORMAT_RGB565;
2708 case PLANE_CTL_FORMAT_NV12:
2709 return DRM_FORMAT_NV12;
2665 default: 2710 default:
2666 case PLANE_CTL_FORMAT_XRGB_8888: 2711 case PLANE_CTL_FORMAT_XRGB_8888:
2667 if (rgb_order) { 2712 if (rgb_order) {
@@ -2824,7 +2869,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
2824 continue; 2869 continue;
2825 2870
2826 if (intel_plane_ggtt_offset(state) == plane_config->base) { 2871 if (intel_plane_ggtt_offset(state) == plane_config->base) {
2827 fb = c->primary->fb; 2872 fb = state->base.fb;
2828 drm_framebuffer_get(fb); 2873 drm_framebuffer_get(fb);
2829 goto valid_fb; 2874 goto valid_fb;
2830 } 2875 }
@@ -2858,6 +2903,9 @@ valid_fb:
2858 return; 2903 return;
2859 } 2904 }
2860 2905
2906 obj = intel_fb_obj(fb);
2907 intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
2908
2861 plane_state->src_x = 0; 2909 plane_state->src_x = 0;
2862 plane_state->src_y = 0; 2910 plane_state->src_y = 0;
2863 plane_state->src_w = fb->width << 16; 2911 plane_state->src_w = fb->width << 16;
@@ -2871,7 +2919,6 @@ valid_fb:
2871 intel_state->base.src = drm_plane_state_src(plane_state); 2919 intel_state->base.src = drm_plane_state_src(plane_state);
2872 intel_state->base.dst = drm_plane_state_dest(plane_state); 2920 intel_state->base.dst = drm_plane_state_dest(plane_state);
2873 2921
2874 obj = intel_fb_obj(fb);
2875 if (i915_gem_object_is_tiled(obj)) 2922 if (i915_gem_object_is_tiled(obj))
2876 dev_priv->preserve_bios_swizzle = true; 2923 dev_priv->preserve_bios_swizzle = true;
2877 2924
@@ -3071,6 +3118,29 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
3071 return 0; 3118 return 0;
3072} 3119}
3073 3120
3121static int
3122skl_check_nv12_surface(const struct intel_crtc_state *crtc_state,
3123 struct intel_plane_state *plane_state)
3124{
3125 /* Display WA #1106 */
3126 if (plane_state->base.rotation !=
3127 (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90) &&
3128 plane_state->base.rotation != DRM_MODE_ROTATE_270)
3129 return 0;
3130
3131 /*
3132 * src coordinates are rotated here.
3133 * We check height but report it as width
3134 */
3135 if (((drm_rect_height(&plane_state->base.src) >> 16) % 4) != 0) {
3136 DRM_DEBUG_KMS("src width must be multiple "
3137 "of 4 for rotated NV12\n");
3138 return -EINVAL;
3139 }
3140
3141 return 0;
3142}
3143
3074static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) 3144static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
3075{ 3145{
3076 const struct drm_framebuffer *fb = plane_state->base.fb; 3146 const struct drm_framebuffer *fb = plane_state->base.fb;
@@ -3154,6 +3224,9 @@ int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
3154 * the main surface setup depends on it. 3224 * the main surface setup depends on it.
3155 */ 3225 */
3156 if (fb->format->format == DRM_FORMAT_NV12) { 3226 if (fb->format->format == DRM_FORMAT_NV12) {
3227 ret = skl_check_nv12_surface(crtc_state, plane_state);
3228 if (ret)
3229 return ret;
3157 ret = skl_check_nv12_aux_surface(plane_state); 3230 ret = skl_check_nv12_aux_surface(plane_state);
3158 if (ret) 3231 if (ret)
3159 return ret; 3232 return ret;
@@ -3464,6 +3537,8 @@ static u32 skl_plane_ctl_format(uint32_t pixel_format)
3464 return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY; 3537 return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
3465 case DRM_FORMAT_VYUY: 3538 case DRM_FORMAT_VYUY:
3466 return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY; 3539 return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
3540 case DRM_FORMAT_NV12:
3541 return PLANE_CTL_FORMAT_NV12;
3467 default: 3542 default:
3468 MISSING_CASE(pixel_format); 3543 MISSING_CASE(pixel_format);
3469 } 3544 }
@@ -3602,15 +3677,24 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
3602u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, 3677u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
3603 const struct intel_plane_state *plane_state) 3678 const struct intel_plane_state *plane_state)
3604{ 3679{
3680 struct drm_i915_private *dev_priv =
3681 to_i915(plane_state->base.plane->dev);
3605 const struct drm_framebuffer *fb = plane_state->base.fb; 3682 const struct drm_framebuffer *fb = plane_state->base.fb;
3606 u32 plane_color_ctl = 0; 3683 u32 plane_color_ctl = 0;
3607 3684
3608 plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE; 3685 if (INTEL_GEN(dev_priv) < 11) {
3609 plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE; 3686 plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
3687 plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
3688 }
3610 plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; 3689 plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
3611 plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format); 3690 plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
3612 3691
3613 if (intel_format_is_yuv(fb->format->format)) { 3692 if (intel_format_is_yuv(fb->format->format)) {
3693 if (fb->format->format == DRM_FORMAT_NV12) {
3694 plane_color_ctl |=
3695 PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
3696 goto out;
3697 }
3614 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) 3698 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
3615 plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709; 3699 plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
3616 else 3700 else
@@ -3619,7 +3703,7 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
3619 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 3703 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
3620 plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE; 3704 plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
3621 } 3705 }
3622 3706out:
3623 return plane_color_ctl; 3707 return plane_color_ctl;
3624} 3708}
3625 3709
@@ -3675,7 +3759,6 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
3675 struct drm_atomic_state *state; 3759 struct drm_atomic_state *state;
3676 int ret; 3760 int ret;
3677 3761
3678
3679 /* reset doesn't touch the display */ 3762 /* reset doesn't touch the display */
3680 if (!i915_modparams.force_reset_modeset_test && 3763 if (!i915_modparams.force_reset_modeset_test &&
3681 !gpu_reset_clobbers_display(dev_priv)) 3764 !gpu_reset_clobbers_display(dev_priv))
@@ -3729,19 +3812,17 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
3729{ 3812{
3730 struct drm_device *dev = &dev_priv->drm; 3813 struct drm_device *dev = &dev_priv->drm;
3731 struct drm_modeset_acquire_ctx *ctx = &dev_priv->reset_ctx; 3814 struct drm_modeset_acquire_ctx *ctx = &dev_priv->reset_ctx;
3732 struct drm_atomic_state *state = dev_priv->modeset_restore_state; 3815 struct drm_atomic_state *state;
3733 int ret; 3816 int ret;
3734 3817
3735 /* reset doesn't touch the display */ 3818 /* reset doesn't touch the display */
3736 if (!i915_modparams.force_reset_modeset_test && 3819 if (!test_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags))
3737 !gpu_reset_clobbers_display(dev_priv))
3738 return; 3820 return;
3739 3821
3822 state = fetch_and_zero(&dev_priv->modeset_restore_state);
3740 if (!state) 3823 if (!state)
3741 goto unlock; 3824 goto unlock;
3742 3825
3743 dev_priv->modeset_restore_state = NULL;
3744
3745 /* reset doesn't touch the display */ 3826 /* reset doesn't touch the display */
3746 if (!gpu_reset_clobbers_display(dev_priv)) { 3827 if (!gpu_reset_clobbers_display(dev_priv)) {
3747 /* for testing only restore the display */ 3828 /* for testing only restore the display */
@@ -4703,7 +4784,9 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
4703static int 4784static int
4704skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, 4785skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
4705 unsigned int scaler_user, int *scaler_id, 4786 unsigned int scaler_user, int *scaler_id,
4706 int src_w, int src_h, int dst_w, int dst_h) 4787 int src_w, int src_h, int dst_w, int dst_h,
4788 bool plane_scaler_check,
4789 uint32_t pixel_format)
4707{ 4790{
4708 struct intel_crtc_scaler_state *scaler_state = 4791 struct intel_crtc_scaler_state *scaler_state =
4709 &crtc_state->scaler_state; 4792 &crtc_state->scaler_state;
@@ -4721,6 +4804,10 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
4721 */ 4804 */
4722 need_scaling = src_w != dst_w || src_h != dst_h; 4805 need_scaling = src_w != dst_w || src_h != dst_h;
4723 4806
4807 if (plane_scaler_check)
4808 if (pixel_format == DRM_FORMAT_NV12)
4809 need_scaling = true;
4810
4724 if (crtc_state->ycbcr420 && scaler_user == SKL_CRTC_INDEX) 4811 if (crtc_state->ycbcr420 && scaler_user == SKL_CRTC_INDEX)
4725 need_scaling = true; 4812 need_scaling = true;
4726 4813
@@ -4760,12 +4847,21 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
4760 return 0; 4847 return 0;
4761 } 4848 }
4762 4849
4850 if (plane_scaler_check && pixel_format == DRM_FORMAT_NV12 &&
4851 (src_h < SKL_MIN_YUV_420_SRC_H || src_w < SKL_MIN_YUV_420_SRC_W)) {
4852 DRM_DEBUG_KMS("NV12: src dimensions not met\n");
4853 return -EINVAL;
4854 }
4855
4763 /* range checks */ 4856 /* range checks */
4764 if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H || 4857 if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H ||
4765 dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H || 4858 dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H ||
4766 4859 (IS_GEN11(dev_priv) &&
4767 src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H || 4860 (src_w > ICL_MAX_SRC_W || src_h > ICL_MAX_SRC_H ||
4768 dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H) { 4861 dst_w > ICL_MAX_DST_W || dst_h > ICL_MAX_DST_H)) ||
4862 (!IS_GEN11(dev_priv) &&
4863 (src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
4864 dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H))) {
4769 DRM_DEBUG_KMS("scaler_user index %u.%u: src %ux%u dst %ux%u " 4865 DRM_DEBUG_KMS("scaler_user index %u.%u: src %ux%u dst %ux%u "
4770 "size is out of scaler range\n", 4866 "size is out of scaler range\n",
4771 intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h); 4867 intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h);
@@ -4796,9 +4892,10 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
4796 const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode; 4892 const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
4797 4893
4798 return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX, 4894 return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
4799 &state->scaler_state.scaler_id, 4895 &state->scaler_state.scaler_id,
4800 state->pipe_src_w, state->pipe_src_h, 4896 state->pipe_src_w, state->pipe_src_h,
4801 adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay); 4897 adjusted_mode->crtc_hdisplay,
4898 adjusted_mode->crtc_vdisplay, false, 0);
4802} 4899}
4803 4900
4804/** 4901/**
@@ -4827,7 +4924,8 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
4827 drm_rect_width(&plane_state->base.src) >> 16, 4924 drm_rect_width(&plane_state->base.src) >> 16,
4828 drm_rect_height(&plane_state->base.src) >> 16, 4925 drm_rect_height(&plane_state->base.src) >> 16,
4829 drm_rect_width(&plane_state->base.dst), 4926 drm_rect_width(&plane_state->base.dst),
4830 drm_rect_height(&plane_state->base.dst)); 4927 drm_rect_height(&plane_state->base.dst),
4928 fb ? true : false, fb ? fb->format->format : 0);
4831 4929
4832 if (ret || plane_state->scaler_id < 0) 4930 if (ret || plane_state->scaler_id < 0)
4833 return ret; 4931 return ret;
@@ -4853,6 +4951,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
4853 case DRM_FORMAT_YVYU: 4951 case DRM_FORMAT_YVYU:
4854 case DRM_FORMAT_UYVY: 4952 case DRM_FORMAT_UYVY:
4855 case DRM_FORMAT_VYUY: 4953 case DRM_FORMAT_VYUY:
4954 case DRM_FORMAT_NV12:
4856 break; 4955 break;
4857 default: 4956 default:
4858 DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n", 4957 DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n",
@@ -5096,16 +5195,34 @@ static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_s
5096 return !old_crtc_state->ips_enabled; 5195 return !old_crtc_state->ips_enabled;
5097} 5196}
5098 5197
5198static bool needs_nv12_wa(struct drm_i915_private *dev_priv,
5199 const struct intel_crtc_state *crtc_state)
5200{
5201 if (!crtc_state->nv12_planes)
5202 return false;
5203
5204 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
5205 return false;
5206
5207 if ((INTEL_GEN(dev_priv) == 9 && !IS_GEMINILAKE(dev_priv)) ||
5208 IS_CANNONLAKE(dev_priv))
5209 return true;
5210
5211 return false;
5212}
5213
5099static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) 5214static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
5100{ 5215{
5101 struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); 5216 struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
5217 struct drm_device *dev = crtc->base.dev;
5218 struct drm_i915_private *dev_priv = to_i915(dev);
5102 struct drm_atomic_state *old_state = old_crtc_state->base.state; 5219 struct drm_atomic_state *old_state = old_crtc_state->base.state;
5103 struct intel_crtc_state *pipe_config = 5220 struct intel_crtc_state *pipe_config =
5104 intel_atomic_get_new_crtc_state(to_intel_atomic_state(old_state), 5221 intel_atomic_get_new_crtc_state(to_intel_atomic_state(old_state),
5105 crtc); 5222 crtc);
5106 struct drm_plane *primary = crtc->base.primary; 5223 struct drm_plane *primary = crtc->base.primary;
5107 struct drm_plane_state *old_pri_state = 5224 struct drm_plane_state *old_primary_state =
5108 drm_atomic_get_existing_plane_state(old_state, primary); 5225 drm_atomic_get_old_plane_state(old_state, primary);
5109 5226
5110 intel_frontbuffer_flip(to_i915(crtc->base.dev), pipe_config->fb_bits); 5227 intel_frontbuffer_flip(to_i915(crtc->base.dev), pipe_config->fb_bits);
5111 5228
@@ -5115,20 +5232,24 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
5115 if (hsw_post_update_enable_ips(old_crtc_state, pipe_config)) 5232 if (hsw_post_update_enable_ips(old_crtc_state, pipe_config))
5116 hsw_enable_ips(pipe_config); 5233 hsw_enable_ips(pipe_config);
5117 5234
5118 if (old_pri_state) { 5235 if (old_primary_state) {
5119 struct intel_plane_state *primary_state = 5236 struct drm_plane_state *new_primary_state =
5120 intel_atomic_get_new_plane_state(to_intel_atomic_state(old_state), 5237 drm_atomic_get_new_plane_state(old_state, primary);
5121 to_intel_plane(primary));
5122 struct intel_plane_state *old_primary_state =
5123 to_intel_plane_state(old_pri_state);
5124 5238
5125 intel_fbc_post_update(crtc); 5239 intel_fbc_post_update(crtc);
5126 5240
5127 if (primary_state->base.visible && 5241 if (new_primary_state->visible &&
5128 (needs_modeset(&pipe_config->base) || 5242 (needs_modeset(&pipe_config->base) ||
5129 !old_primary_state->base.visible)) 5243 !old_primary_state->visible))
5130 intel_post_enable_primary(&crtc->base, pipe_config); 5244 intel_post_enable_primary(&crtc->base, pipe_config);
5131 } 5245 }
5246
5247 /* Display WA 827 */
5248 if (needs_nv12_wa(dev_priv, old_crtc_state) &&
5249 !needs_nv12_wa(dev_priv, pipe_config)) {
5250 skl_wa_clkgate(dev_priv, crtc->pipe, false);
5251 skl_wa_528(dev_priv, crtc->pipe, false);
5252 }
5132} 5253}
5133 5254
5134static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state, 5255static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
@@ -5139,8 +5260,8 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
5139 struct drm_i915_private *dev_priv = to_i915(dev); 5260 struct drm_i915_private *dev_priv = to_i915(dev);
5140 struct drm_atomic_state *old_state = old_crtc_state->base.state; 5261 struct drm_atomic_state *old_state = old_crtc_state->base.state;
5141 struct drm_plane *primary = crtc->base.primary; 5262 struct drm_plane *primary = crtc->base.primary;
5142 struct drm_plane_state *old_pri_state = 5263 struct drm_plane_state *old_primary_state =
5143 drm_atomic_get_existing_plane_state(old_state, primary); 5264 drm_atomic_get_old_plane_state(old_state, primary);
5144 bool modeset = needs_modeset(&pipe_config->base); 5265 bool modeset = needs_modeset(&pipe_config->base);
5145 struct intel_atomic_state *old_intel_state = 5266 struct intel_atomic_state *old_intel_state =
5146 to_intel_atomic_state(old_state); 5267 to_intel_atomic_state(old_state);
@@ -5148,23 +5269,28 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
5148 if (hsw_pre_update_disable_ips(old_crtc_state, pipe_config)) 5269 if (hsw_pre_update_disable_ips(old_crtc_state, pipe_config))
5149 hsw_disable_ips(old_crtc_state); 5270 hsw_disable_ips(old_crtc_state);
5150 5271
5151 if (old_pri_state) { 5272 if (old_primary_state) {
5152 struct intel_plane_state *primary_state = 5273 struct intel_plane_state *new_primary_state =
5153 intel_atomic_get_new_plane_state(old_intel_state, 5274 intel_atomic_get_new_plane_state(old_intel_state,
5154 to_intel_plane(primary)); 5275 to_intel_plane(primary));
5155 struct intel_plane_state *old_primary_state =
5156 to_intel_plane_state(old_pri_state);
5157 5276
5158 intel_fbc_pre_update(crtc, pipe_config, primary_state); 5277 intel_fbc_pre_update(crtc, pipe_config, new_primary_state);
5159 /* 5278 /*
5160 * Gen2 reports pipe underruns whenever all planes are disabled. 5279 * Gen2 reports pipe underruns whenever all planes are disabled.
5161 * So disable underrun reporting before all the planes get disabled. 5280 * So disable underrun reporting before all the planes get disabled.
5162 */ 5281 */
5163 if (IS_GEN2(dev_priv) && old_primary_state->base.visible && 5282 if (IS_GEN2(dev_priv) && old_primary_state->visible &&
5164 (modeset || !primary_state->base.visible)) 5283 (modeset || !new_primary_state->base.visible))
5165 intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false); 5284 intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
5166 } 5285 }
5167 5286
5287 /* Display WA 827 */
5288 if (!needs_nv12_wa(dev_priv, old_crtc_state) &&
5289 needs_nv12_wa(dev_priv, pipe_config)) {
5290 skl_wa_clkgate(dev_priv, crtc->pipe, true);
5291 skl_wa_528(dev_priv, crtc->pipe, true);
5292 }
5293
5168 /* 5294 /*
5169 * Vblank time updates from the shadow to live plane control register 5295 * Vblank time updates from the shadow to live plane control register
5170 * are blocked if the memory self-refresh mode is active at that 5296 * are blocked if the memory self-refresh mode is active at that
@@ -5499,6 +5625,9 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
5499 if (intel_crtc->config->shared_dpll) 5625 if (intel_crtc->config->shared_dpll)
5500 intel_enable_shared_dpll(intel_crtc); 5626 intel_enable_shared_dpll(intel_crtc);
5501 5627
5628 if (INTEL_GEN(dev_priv) >= 11)
5629 icl_map_plls_to_ports(crtc, pipe_config, old_state);
5630
5502 if (intel_crtc_has_dp_encoder(intel_crtc->config)) 5631 if (intel_crtc_has_dp_encoder(intel_crtc->config))
5503 intel_dp_set_m_n(intel_crtc, M1_N1); 5632 intel_dp_set_m_n(intel_crtc, M1_N1);
5504 5633
@@ -5696,6 +5825,9 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
5696 intel_ddi_disable_pipe_clock(intel_crtc->config); 5825 intel_ddi_disable_pipe_clock(intel_crtc->config);
5697 5826
5698 intel_encoders_post_disable(crtc, old_crtc_state, old_state); 5827 intel_encoders_post_disable(crtc, old_crtc_state, old_state);
5828
5829 if (INTEL_GEN(dev_priv) >= 11)
5830 icl_unmap_plls_to_ports(crtc, old_crtc_state, old_state);
5699} 5831}
5700 5832
5701static void i9xx_pfit_enable(struct intel_crtc *crtc) 5833static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@ -8766,8 +8898,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
8766 intel_get_shared_dpll_by_id(dev_priv, pll_id); 8898 intel_get_shared_dpll_by_id(dev_priv, pll_id);
8767 pll = pipe_config->shared_dpll; 8899 pll = pipe_config->shared_dpll;
8768 8900
8769 WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll, 8901 WARN_ON(!pll->info->funcs->get_hw_state(dev_priv, pll,
8770 &pipe_config->dpll_hw_state)); 8902 &pipe_config->dpll_hw_state));
8771 8903
8772 tmp = pipe_config->dpll_hw_state.dpll; 8904 tmp = pipe_config->dpll_hw_state.dpll;
8773 pipe_config->pixel_multiplier = 8905 pipe_config->pixel_multiplier =
@@ -9243,8 +9375,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
9243 9375
9244 pll = pipe_config->shared_dpll; 9376 pll = pipe_config->shared_dpll;
9245 if (pll) { 9377 if (pll) {
9246 WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll, 9378 WARN_ON(!pll->info->funcs->get_hw_state(dev_priv, pll,
9247 &pipe_config->dpll_hw_state)); 9379 &pipe_config->dpll_hw_state));
9248 } 9380 }
9249 9381
9250 /* 9382 /*
@@ -9974,6 +10106,8 @@ found:
9974 ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector)); 10106 ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector));
9975 if (!ret) 10107 if (!ret)
9976 ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, crtc)); 10108 ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, crtc));
10109 if (!ret)
10110 ret = drm_atomic_add_affected_planes(restore_state, crtc);
9977 if (ret) { 10111 if (ret) {
9978 DRM_DEBUG_KMS("Failed to create a copy of old state to restore: %i\n", ret); 10112 DRM_DEBUG_KMS("Failed to create a copy of old state to restore: %i\n", ret);
9979 goto fail; 10113 goto fail;
@@ -10773,7 +10907,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
10773 struct drm_connector_state *connector_state; 10907 struct drm_connector_state *connector_state;
10774 struct intel_encoder *encoder; 10908 struct intel_encoder *encoder;
10775 10909
10776 connector_state = drm_atomic_get_existing_connector_state(state, connector); 10910 connector_state = drm_atomic_get_new_connector_state(state, connector);
10777 if (!connector_state) 10911 if (!connector_state)
10778 connector_state = connector->state; 10912 connector_state = connector->state;
10779 10913
@@ -11085,39 +11219,42 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
11085 (current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) && 11219 (current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
11086 !(pipe_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED); 11220 !(pipe_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED);
11087 11221
11088#define PIPE_CONF_CHECK_X(name) \ 11222#define PIPE_CONF_CHECK_X(name) do { \
11089 if (current_config->name != pipe_config->name) { \ 11223 if (current_config->name != pipe_config->name) { \
11090 pipe_config_err(adjust, __stringify(name), \ 11224 pipe_config_err(adjust, __stringify(name), \
11091 "(expected 0x%08x, found 0x%08x)\n", \ 11225 "(expected 0x%08x, found 0x%08x)\n", \
11092 current_config->name, \ 11226 current_config->name, \
11093 pipe_config->name); \ 11227 pipe_config->name); \
11094 ret = false; \ 11228 ret = false; \
11095 } 11229 } \
11230} while (0)
11096 11231
11097#define PIPE_CONF_CHECK_I(name) \ 11232#define PIPE_CONF_CHECK_I(name) do { \
11098 if (current_config->name != pipe_config->name) { \ 11233 if (current_config->name != pipe_config->name) { \
11099 pipe_config_err(adjust, __stringify(name), \ 11234 pipe_config_err(adjust, __stringify(name), \
11100 "(expected %i, found %i)\n", \ 11235 "(expected %i, found %i)\n", \
11101 current_config->name, \ 11236 current_config->name, \
11102 pipe_config->name); \ 11237 pipe_config->name); \
11103 ret = false; \ 11238 ret = false; \
11104 } 11239 } \
11240} while (0)
11105 11241
11106#define PIPE_CONF_CHECK_BOOL(name) \ 11242#define PIPE_CONF_CHECK_BOOL(name) do { \
11107 if (current_config->name != pipe_config->name) { \ 11243 if (current_config->name != pipe_config->name) { \
11108 pipe_config_err(adjust, __stringify(name), \ 11244 pipe_config_err(adjust, __stringify(name), \
11109 "(expected %s, found %s)\n", \ 11245 "(expected %s, found %s)\n", \
11110 yesno(current_config->name), \ 11246 yesno(current_config->name), \
11111 yesno(pipe_config->name)); \ 11247 yesno(pipe_config->name)); \
11112 ret = false; \ 11248 ret = false; \
11113 } 11249 } \
11250} while (0)
11114 11251
11115/* 11252/*
11116 * Checks state where we only read out the enabling, but not the entire 11253 * Checks state where we only read out the enabling, but not the entire
11117 * state itself (like full infoframes or ELD for audio). These states 11254 * state itself (like full infoframes or ELD for audio). These states
11118 * require a full modeset on bootup to fix up. 11255 * require a full modeset on bootup to fix up.
11119 */ 11256 */
11120#define PIPE_CONF_CHECK_BOOL_INCOMPLETE(name) \ 11257#define PIPE_CONF_CHECK_BOOL_INCOMPLETE(name) do { \
11121 if (!fixup_inherited || (!current_config->name && !pipe_config->name)) { \ 11258 if (!fixup_inherited || (!current_config->name && !pipe_config->name)) { \
11122 PIPE_CONF_CHECK_BOOL(name); \ 11259 PIPE_CONF_CHECK_BOOL(name); \
11123 } else { \ 11260 } else { \
@@ -11126,18 +11263,20 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
11126 yesno(current_config->name), \ 11263 yesno(current_config->name), \
11127 yesno(pipe_config->name)); \ 11264 yesno(pipe_config->name)); \
11128 ret = false; \ 11265 ret = false; \
11129 } 11266 } \
11267} while (0)
11130 11268
11131#define PIPE_CONF_CHECK_P(name) \ 11269#define PIPE_CONF_CHECK_P(name) do { \
11132 if (current_config->name != pipe_config->name) { \ 11270 if (current_config->name != pipe_config->name) { \
11133 pipe_config_err(adjust, __stringify(name), \ 11271 pipe_config_err(adjust, __stringify(name), \
11134 "(expected %p, found %p)\n", \ 11272 "(expected %p, found %p)\n", \
11135 current_config->name, \ 11273 current_config->name, \
11136 pipe_config->name); \ 11274 pipe_config->name); \
11137 ret = false; \ 11275 ret = false; \
11138 } 11276 } \
11277} while (0)
11139 11278
11140#define PIPE_CONF_CHECK_M_N(name) \ 11279#define PIPE_CONF_CHECK_M_N(name) do { \
11141 if (!intel_compare_link_m_n(&current_config->name, \ 11280 if (!intel_compare_link_m_n(&current_config->name, \
11142 &pipe_config->name,\ 11281 &pipe_config->name,\
11143 adjust)) { \ 11282 adjust)) { \
@@ -11155,14 +11294,15 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
11155 pipe_config->name.link_m, \ 11294 pipe_config->name.link_m, \
11156 pipe_config->name.link_n); \ 11295 pipe_config->name.link_n); \
11157 ret = false; \ 11296 ret = false; \
11158 } 11297 } \
11298} while (0)
11159 11299
11160/* This is required for BDW+ where there is only one set of registers for 11300/* This is required for BDW+ where there is only one set of registers for
11161 * switching between high and low RR. 11301 * switching between high and low RR.
11162 * This macro can be used whenever a comparison has to be made between one 11302 * This macro can be used whenever a comparison has to be made between one
11163 * hw state and multiple sw state variables. 11303 * hw state and multiple sw state variables.
11164 */ 11304 */
11165#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) \ 11305#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) do { \
11166 if (!intel_compare_link_m_n(&current_config->name, \ 11306 if (!intel_compare_link_m_n(&current_config->name, \
11167 &pipe_config->name, adjust) && \ 11307 &pipe_config->name, adjust) && \
11168 !intel_compare_link_m_n(&current_config->alt_name, \ 11308 !intel_compare_link_m_n(&current_config->alt_name, \
@@ -11187,9 +11327,10 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
11187 pipe_config->name.link_m, \ 11327 pipe_config->name.link_m, \
11188 pipe_config->name.link_n); \ 11328 pipe_config->name.link_n); \
11189 ret = false; \ 11329 ret = false; \
11190 } 11330 } \
11331} while (0)
11191 11332
11192#define PIPE_CONF_CHECK_FLAGS(name, mask) \ 11333#define PIPE_CONF_CHECK_FLAGS(name, mask) do { \
11193 if ((current_config->name ^ pipe_config->name) & (mask)) { \ 11334 if ((current_config->name ^ pipe_config->name) & (mask)) { \
11194 pipe_config_err(adjust, __stringify(name), \ 11335 pipe_config_err(adjust, __stringify(name), \
11195 "(%x) (expected %i, found %i)\n", \ 11336 "(%x) (expected %i, found %i)\n", \
@@ -11197,16 +11338,18 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
11197 current_config->name & (mask), \ 11338 current_config->name & (mask), \
11198 pipe_config->name & (mask)); \ 11339 pipe_config->name & (mask)); \
11199 ret = false; \ 11340 ret = false; \
11200 } 11341 } \
11342} while (0)
11201 11343
11202#define PIPE_CONF_CHECK_CLOCK_FUZZY(name) \ 11344#define PIPE_CONF_CHECK_CLOCK_FUZZY(name) do { \
11203 if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \ 11345 if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
11204 pipe_config_err(adjust, __stringify(name), \ 11346 pipe_config_err(adjust, __stringify(name), \
11205 "(expected %i, found %i)\n", \ 11347 "(expected %i, found %i)\n", \
11206 current_config->name, \ 11348 current_config->name, \
11207 pipe_config->name); \ 11349 pipe_config->name); \
11208 ret = false; \ 11350 ret = false; \
11209 } 11351 } \
11352} while (0)
11210 11353
11211#define PIPE_CONF_QUIRK(quirk) \ 11354#define PIPE_CONF_QUIRK(quirk) \
11212 ((current_config->quirks | pipe_config->quirks) & (quirk)) 11355 ((current_config->quirks | pipe_config->quirks) & (quirk))
@@ -11315,6 +11458,16 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
11315 PIPE_CONF_CHECK_X(dpll_hw_state.pll9); 11458 PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
11316 PIPE_CONF_CHECK_X(dpll_hw_state.pll10); 11459 PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
11317 PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12); 11460 PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
11461 PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
11462 PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
11463 PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
11464 PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
11465 PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
11466 PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
11467 PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
11468 PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
11469 PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
11470 PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
11318 11471
11319 PIPE_CONF_CHECK_X(dsi_pll.ctrl); 11472 PIPE_CONF_CHECK_X(dsi_pll.ctrl);
11320 PIPE_CONF_CHECK_X(dsi_pll.div); 11473 PIPE_CONF_CHECK_X(dsi_pll.div);
@@ -11378,6 +11531,11 @@ static void verify_wm_state(struct drm_crtc *crtc,
11378 skl_ddb_get_hw_state(dev_priv, &hw_ddb); 11531 skl_ddb_get_hw_state(dev_priv, &hw_ddb);
11379 sw_ddb = &dev_priv->wm.skl_hw.ddb; 11532 sw_ddb = &dev_priv->wm.skl_hw.ddb;
11380 11533
11534 if (INTEL_GEN(dev_priv) >= 11)
11535 if (hw_ddb.enabled_slices != sw_ddb->enabled_slices)
11536 DRM_ERROR("mismatch in DBUF Slices (expected %u, got %u)\n",
11537 sw_ddb->enabled_slices,
11538 hw_ddb.enabled_slices);
11381 /* planes */ 11539 /* planes */
11382 for_each_universal_plane(dev_priv, pipe, plane) { 11540 for_each_universal_plane(dev_priv, pipe, plane) {
11383 hw_plane_wm = &hw_wm.planes[plane]; 11541 hw_plane_wm = &hw_wm.planes[plane];
@@ -11643,11 +11801,11 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv,
11643 11801
11644 memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); 11802 memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
11645 11803
11646 DRM_DEBUG_KMS("%s\n", pll->name); 11804 DRM_DEBUG_KMS("%s\n", pll->info->name);
11647 11805
11648 active = pll->funcs.get_hw_state(dev_priv, pll, &dpll_hw_state); 11806 active = pll->info->funcs->get_hw_state(dev_priv, pll, &dpll_hw_state);
11649 11807
11650 if (!(pll->flags & INTEL_DPLL_ALWAYS_ON)) { 11808 if (!(pll->info->flags & INTEL_DPLL_ALWAYS_ON)) {
11651 I915_STATE_WARN(!pll->on && pll->active_mask, 11809 I915_STATE_WARN(!pll->on && pll->active_mask,
11652 "pll in active use but not on in sw tracking\n"); 11810 "pll in active use but not on in sw tracking\n");
11653 I915_STATE_WARN(pll->on && !pll->active_mask, 11811 I915_STATE_WARN(pll->on && !pll->active_mask,
@@ -12136,20 +12294,23 @@ static void intel_update_crtc(struct drm_crtc *crtc,
12136 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 12294 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
12137 struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state); 12295 struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state);
12138 bool modeset = needs_modeset(new_crtc_state); 12296 bool modeset = needs_modeset(new_crtc_state);
12297 struct intel_plane_state *new_plane_state =
12298 intel_atomic_get_new_plane_state(to_intel_atomic_state(state),
12299 to_intel_plane(crtc->primary));
12139 12300
12140 if (modeset) { 12301 if (modeset) {
12141 update_scanline_offset(intel_crtc); 12302 update_scanline_offset(intel_crtc);
12142 dev_priv->display.crtc_enable(pipe_config, state); 12303 dev_priv->display.crtc_enable(pipe_config, state);
12304
12305 /* vblanks work again, re-enable pipe CRC. */
12306 intel_crtc_enable_pipe_crc(intel_crtc);
12143 } else { 12307 } else {
12144 intel_pre_plane_update(to_intel_crtc_state(old_crtc_state), 12308 intel_pre_plane_update(to_intel_crtc_state(old_crtc_state),
12145 pipe_config); 12309 pipe_config);
12146 } 12310 }
12147 12311
12148 if (drm_atomic_get_existing_plane_state(state, crtc->primary)) { 12312 if (new_plane_state)
12149 intel_fbc_enable( 12313 intel_fbc_enable(intel_crtc, pipe_config, new_plane_state);
12150 intel_crtc, pipe_config,
12151 to_intel_plane_state(crtc->primary->state));
12152 }
12153 12314
12154 drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); 12315 drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
12155} 12316}
@@ -12181,6 +12342,8 @@ static void skl_update_crtcs(struct drm_atomic_state *state)
12181 bool progress; 12342 bool progress;
12182 enum pipe pipe; 12343 enum pipe pipe;
12183 int i; 12344 int i;
12345 u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
12346 u8 required_slices = intel_state->wm_results.ddb.enabled_slices;
12184 12347
12185 const struct skl_ddb_entry *entries[I915_MAX_PIPES] = {}; 12348 const struct skl_ddb_entry *entries[I915_MAX_PIPES] = {};
12186 12349
@@ -12189,6 +12352,10 @@ static void skl_update_crtcs(struct drm_atomic_state *state)
12189 if (new_crtc_state->active) 12352 if (new_crtc_state->active)
12190 entries[i] = &to_intel_crtc_state(old_crtc_state)->wm.skl.ddb; 12353 entries[i] = &to_intel_crtc_state(old_crtc_state)->wm.skl.ddb;
12191 12354
12355 /* If 2nd DBuf slice required, enable it here */
12356 if (INTEL_GEN(dev_priv) >= 11 && required_slices > hw_enabled_slices)
12357 icl_dbuf_slices_update(dev_priv, required_slices);
12358
12192 /* 12359 /*
12193 * Whenever the number of active pipes changes, we need to make sure we 12360 * Whenever the number of active pipes changes, we need to make sure we
12194 * update the pipes in the right order so that their ddb allocations 12361 * update the pipes in the right order so that their ddb allocations
@@ -12239,6 +12406,10 @@ static void skl_update_crtcs(struct drm_atomic_state *state)
12239 progress = true; 12406 progress = true;
12240 } 12407 }
12241 } while (progress); 12408 } while (progress);
12409
12410 /* If 2nd DBuf slice is no more required disable it */
12411 if (INTEL_GEN(dev_priv) >= 11 && required_slices < hw_enabled_slices)
12412 icl_dbuf_slices_update(dev_priv, required_slices);
12242} 12413}
12243 12414
12244static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv) 12415static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv)
@@ -12320,6 +12491,13 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
12320 12491
12321 if (old_crtc_state->active) { 12492 if (old_crtc_state->active) {
12322 intel_crtc_disable_planes(crtc, old_crtc_state->plane_mask); 12493 intel_crtc_disable_planes(crtc, old_crtc_state->plane_mask);
12494
12495 /*
12496 * We need to disable pipe CRC before disabling the pipe,
12497 * or we race against vblank off.
12498 */
12499 intel_crtc_disable_pipe_crc(intel_crtc);
12500
12323 dev_priv->display.crtc_disable(to_intel_crtc_state(old_crtc_state), state); 12501 dev_priv->display.crtc_disable(to_intel_crtc_state(old_crtc_state), state);
12324 intel_crtc->active = false; 12502 intel_crtc->active = false;
12325 intel_fbc_disable(intel_crtc); 12503 intel_fbc_disable(intel_crtc);
@@ -12695,6 +12873,15 @@ static void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state)
12695 intel_unpin_fb_vma(vma, old_plane_state->flags); 12873 intel_unpin_fb_vma(vma, old_plane_state->flags);
12696} 12874}
12697 12875
12876static void fb_obj_bump_render_priority(struct drm_i915_gem_object *obj)
12877{
12878 struct i915_sched_attr attr = {
12879 .priority = I915_PRIORITY_DISPLAY,
12880 };
12881
12882 i915_gem_object_wait_priority(obj, 0, &attr);
12883}
12884
12698/** 12885/**
12699 * intel_prepare_plane_fb - Prepare fb for usage on plane 12886 * intel_prepare_plane_fb - Prepare fb for usage on plane
12700 * @plane: drm plane to prepare for 12887 * @plane: drm plane to prepare for
@@ -12723,8 +12910,8 @@ intel_prepare_plane_fb(struct drm_plane *plane,
12723 12910
12724 if (old_obj) { 12911 if (old_obj) {
12725 struct drm_crtc_state *crtc_state = 12912 struct drm_crtc_state *crtc_state =
12726 drm_atomic_get_existing_crtc_state(new_state->state, 12913 drm_atomic_get_new_crtc_state(new_state->state,
12727 plane->state->crtc); 12914 plane->state->crtc);
12728 12915
12729 /* Big Hammer, we also need to ensure that any pending 12916 /* Big Hammer, we also need to ensure that any pending
12730 * MI_WAIT_FOR_EVENT inside a user batch buffer on the 12917 * MI_WAIT_FOR_EVENT inside a user batch buffer on the
@@ -12771,13 +12958,15 @@ intel_prepare_plane_fb(struct drm_plane *plane,
12771 12958
12772 ret = intel_plane_pin_fb(to_intel_plane_state(new_state)); 12959 ret = intel_plane_pin_fb(to_intel_plane_state(new_state));
12773 12960
12774 i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY); 12961 fb_obj_bump_render_priority(obj);
12775 12962
12776 mutex_unlock(&dev_priv->drm.struct_mutex); 12963 mutex_unlock(&dev_priv->drm.struct_mutex);
12777 i915_gem_object_unpin_pages(obj); 12964 i915_gem_object_unpin_pages(obj);
12778 if (ret) 12965 if (ret)
12779 return ret; 12966 return ret;
12780 12967
12968 intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
12969
12781 if (!new_state->fence) { /* implicit fencing */ 12970 if (!new_state->fence) { /* implicit fencing */
12782 struct dma_fence *fence; 12971 struct dma_fence *fence;
12783 12972
@@ -12822,11 +13011,13 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
12822} 13011}
12823 13012
12824int 13013int
12825skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state) 13014skl_max_scale(struct intel_crtc *intel_crtc,
13015 struct intel_crtc_state *crtc_state,
13016 uint32_t pixel_format)
12826{ 13017{
12827 struct drm_i915_private *dev_priv; 13018 struct drm_i915_private *dev_priv;
12828 int max_scale; 13019 int max_scale, mult;
12829 int crtc_clock, max_dotclk; 13020 int crtc_clock, max_dotclk, tmpclk1, tmpclk2;
12830 13021
12831 if (!intel_crtc || !crtc_state->base.enable) 13022 if (!intel_crtc || !crtc_state->base.enable)
12832 return DRM_PLANE_HELPER_NO_SCALING; 13023 return DRM_PLANE_HELPER_NO_SCALING;
@@ -12848,8 +13039,10 @@ skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state
12848 * or 13039 * or
12849 * cdclk/crtc_clock 13040 * cdclk/crtc_clock
12850 */ 13041 */
12851 max_scale = min((1 << 16) * 3 - 1, 13042 mult = pixel_format == DRM_FORMAT_NV12 ? 2 : 3;
12852 (1 << 8) * ((max_dotclk << 8) / crtc_clock)); 13043 tmpclk1 = (1 << 16) * mult - 1;
13044 tmpclk2 = (1 << 8) * ((max_dotclk << 8) / crtc_clock);
13045 max_scale = min(tmpclk1, tmpclk2);
12853 13046
12854 return max_scale; 13047 return max_scale;
12855} 13048}
@@ -12865,12 +13058,16 @@ intel_check_primary_plane(struct intel_plane *plane,
12865 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 13058 int max_scale = DRM_PLANE_HELPER_NO_SCALING;
12866 bool can_position = false; 13059 bool can_position = false;
12867 int ret; 13060 int ret;
13061 uint32_t pixel_format = 0;
12868 13062
12869 if (INTEL_GEN(dev_priv) >= 9) { 13063 if (INTEL_GEN(dev_priv) >= 9) {
12870 /* use scaler when colorkey is not required */ 13064 /* use scaler when colorkey is not required */
12871 if (!state->ckey.flags) { 13065 if (!state->ckey.flags) {
12872 min_scale = 1; 13066 min_scale = 1;
12873 max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state); 13067 if (state->base.fb)
13068 pixel_format = state->base.fb->format->format;
13069 max_scale = skl_max_scale(to_intel_crtc(crtc),
13070 crtc_state, pixel_format);
12874 } 13071 }
12875 can_position = true; 13072 can_position = true;
12876 } 13073 }
@@ -12943,10 +13140,25 @@ out:
12943 intel_cstate); 13140 intel_cstate);
12944} 13141}
12945 13142
13143void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
13144 struct intel_crtc_state *crtc_state)
13145{
13146 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
13147
13148 if (!IS_GEN2(dev_priv))
13149 intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
13150
13151 if (crtc_state->has_pch_encoder) {
13152 enum pipe pch_transcoder =
13153 intel_crtc_pch_transcoder(crtc);
13154
13155 intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
13156 }
13157}
13158
12946static void intel_finish_crtc_commit(struct drm_crtc *crtc, 13159static void intel_finish_crtc_commit(struct drm_crtc *crtc,
12947 struct drm_crtc_state *old_crtc_state) 13160 struct drm_crtc_state *old_crtc_state)
12948{ 13161{
12949 struct drm_i915_private *dev_priv = to_i915(crtc->dev);
12950 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 13162 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
12951 struct intel_atomic_state *old_intel_state = 13163 struct intel_atomic_state *old_intel_state =
12952 to_intel_atomic_state(old_crtc_state->state); 13164 to_intel_atomic_state(old_crtc_state->state);
@@ -12957,17 +13169,8 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc,
12957 13169
12958 if (new_crtc_state->update_pipe && 13170 if (new_crtc_state->update_pipe &&
12959 !needs_modeset(&new_crtc_state->base) && 13171 !needs_modeset(&new_crtc_state->base) &&
12960 old_crtc_state->mode.private_flags & I915_MODE_FLAG_INHERITED) { 13172 old_crtc_state->mode.private_flags & I915_MODE_FLAG_INHERITED)
12961 if (!IS_GEN2(dev_priv)) 13173 intel_crtc_arm_fifo_underrun(intel_crtc, new_crtc_state);
12962 intel_set_cpu_fifo_underrun_reporting(dev_priv, intel_crtc->pipe, true);
12963
12964 if (new_crtc_state->has_pch_encoder) {
12965 enum pipe pch_transcoder =
12966 intel_crtc_pch_transcoder(intel_crtc);
12967
12968 intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
12969 }
12970 }
12971} 13174}
12972 13175
12973/** 13176/**
@@ -13031,6 +13234,7 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier)
13031 case DRM_FORMAT_YVYU: 13234 case DRM_FORMAT_YVYU:
13032 case DRM_FORMAT_UYVY: 13235 case DRM_FORMAT_UYVY:
13033 case DRM_FORMAT_VYUY: 13236 case DRM_FORMAT_VYUY:
13237 case DRM_FORMAT_NV12:
13034 if (modifier == I915_FORMAT_MOD_Yf_TILED) 13238 if (modifier == I915_FORMAT_MOD_Yf_TILED)
13035 return true; 13239 return true;
13036 /* fall through */ 13240 /* fall through */
@@ -13165,8 +13369,9 @@ intel_legacy_cursor_update(struct drm_plane *plane,
13165 if (ret) 13369 if (ret)
13166 goto out_unlock; 13370 goto out_unlock;
13167 13371
13168 old_fb = old_plane_state->fb; 13372 intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_FLIP);
13169 13373
13374 old_fb = old_plane_state->fb;
13170 i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb), 13375 i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb),
13171 intel_plane->frontbuffer_bit); 13376 intel_plane->frontbuffer_bit);
13172 13377
@@ -13237,6 +13442,30 @@ static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
13237 return pipe == PIPE_A && plane_id == PLANE_PRIMARY; 13442 return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
13238} 13443}
13239 13444
13445bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
13446 enum pipe pipe, enum plane_id plane_id)
13447{
13448 if (plane_id == PLANE_PRIMARY) {
13449 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
13450 return false;
13451 else if ((INTEL_GEN(dev_priv) == 9 && pipe == PIPE_C) &&
13452 !IS_GEMINILAKE(dev_priv))
13453 return false;
13454 } else if (plane_id >= PLANE_SPRITE0) {
13455 if (plane_id == PLANE_CURSOR)
13456 return false;
13457 if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) == 10) {
13458 if (plane_id != PLANE_SPRITE0)
13459 return false;
13460 } else {
13461 if (plane_id != PLANE_SPRITE0 || pipe == PIPE_C ||
13462 IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
13463 return false;
13464 }
13465 }
13466 return true;
13467}
13468
13240static struct intel_plane * 13469static struct intel_plane *
13241intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) 13470intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13242{ 13471{
@@ -13297,8 +13526,13 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13297 primary->check_plane = intel_check_primary_plane; 13526 primary->check_plane = intel_check_primary_plane;
13298 13527
13299 if (INTEL_GEN(dev_priv) >= 9) { 13528 if (INTEL_GEN(dev_priv) >= 9) {
13300 intel_primary_formats = skl_primary_formats; 13529 if (skl_plane_has_planar(dev_priv, pipe, PLANE_PRIMARY)) {
13301 num_formats = ARRAY_SIZE(skl_primary_formats); 13530 intel_primary_formats = skl_pri_planar_formats;
13531 num_formats = ARRAY_SIZE(skl_pri_planar_formats);
13532 } else {
13533 intel_primary_formats = skl_primary_formats;
13534 num_formats = ARRAY_SIZE(skl_primary_formats);
13535 }
13302 13536
13303 if (skl_plane_has_ccs(dev_priv, pipe, PLANE_PRIMARY)) 13537 if (skl_plane_has_ccs(dev_priv, pipe, PLANE_PRIMARY))
13304 modifiers = skl_format_modifiers_ccs; 13538 modifiers = skl_format_modifiers_ccs;
@@ -13553,10 +13787,17 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
13553 /* initialize shared scalers */ 13787 /* initialize shared scalers */
13554 intel_crtc_init_scalers(intel_crtc, crtc_state); 13788 intel_crtc_init_scalers(intel_crtc, crtc_state);
13555 13789
13556 BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || 13790 BUG_ON(pipe >= ARRAY_SIZE(dev_priv->pipe_to_crtc_mapping) ||
13557 dev_priv->plane_to_crtc_mapping[primary->i9xx_plane] != NULL); 13791 dev_priv->pipe_to_crtc_mapping[pipe] != NULL);
13558 dev_priv->plane_to_crtc_mapping[primary->i9xx_plane] = intel_crtc; 13792 dev_priv->pipe_to_crtc_mapping[pipe] = intel_crtc;
13559 dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = intel_crtc; 13793
13794 if (INTEL_GEN(dev_priv) < 9) {
13795 enum i9xx_plane_id i9xx_plane = primary->i9xx_plane;
13796
13797 BUG_ON(i9xx_plane >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
13798 dev_priv->plane_to_crtc_mapping[i9xx_plane] != NULL);
13799 dev_priv->plane_to_crtc_mapping[i9xx_plane] = intel_crtc;
13800 }
13560 13801
13561 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); 13802 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
13562 13803
@@ -14112,6 +14353,20 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
14112 goto err; 14353 goto err;
14113 } 14354 }
14114 break; 14355 break;
14356 case DRM_FORMAT_NV12:
14357 if (mode_cmd->modifier[0] == I915_FORMAT_MOD_Y_TILED_CCS ||
14358 mode_cmd->modifier[0] == I915_FORMAT_MOD_Yf_TILED_CCS) {
14359 DRM_DEBUG_KMS("RC not to be enabled with NV12\n");
14360 goto err;
14361 }
14362 if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) ||
14363 IS_BROXTON(dev_priv)) {
14364 DRM_DEBUG_KMS("unsupported pixel format: %s\n",
14365 drm_get_format_name(mode_cmd->pixel_format,
14366 &format_name));
14367 goto err;
14368 }
14369 break;
14115 default: 14370 default:
14116 DRM_DEBUG_KMS("unsupported pixel format: %s\n", 14371 DRM_DEBUG_KMS("unsupported pixel format: %s\n",
14117 drm_get_format_name(mode_cmd->pixel_format, &format_name)); 14372 drm_get_format_name(mode_cmd->pixel_format, &format_name));
@@ -14124,6 +14379,14 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
14124 14379
14125 drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd); 14380 drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
14126 14381
14382 if (fb->format->format == DRM_FORMAT_NV12 &&
14383 (fb->width < SKL_MIN_YUV_420_SRC_W ||
14384 fb->height < SKL_MIN_YUV_420_SRC_H ||
14385 (fb->width % 4) != 0 || (fb->height % 4) != 0)) {
14386 DRM_DEBUG_KMS("src dimensions not correct for NV12\n");
14387 return -EINVAL;
14388 }
14389
14127 for (i = 0; i < fb->format->num_planes; i++) { 14390 for (i = 0; i < fb->format->num_planes; i++) {
14128 u32 stride_alignment; 14391 u32 stride_alignment;
14129 14392
@@ -15101,8 +15364,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
15101 for (i = 0; i < dev_priv->num_shared_dpll; i++) { 15364 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
15102 struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; 15365 struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
15103 15366
15104 pll->on = pll->funcs.get_hw_state(dev_priv, pll, 15367 pll->on = pll->info->funcs->get_hw_state(dev_priv, pll,
15105 &pll->state.hw_state); 15368 &pll->state.hw_state);
15106 pll->state.crtc_mask = 0; 15369 pll->state.crtc_mask = 0;
15107 for_each_intel_crtc(dev, crtc) { 15370 for_each_intel_crtc(dev, crtc) {
15108 struct intel_crtc_state *crtc_state = 15371 struct intel_crtc_state *crtc_state =
@@ -15115,7 +15378,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
15115 pll->active_mask = pll->state.crtc_mask; 15378 pll->active_mask = pll->state.crtc_mask;
15116 15379
15117 DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n", 15380 DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n",
15118 pll->name, pll->state.crtc_mask, pll->on); 15381 pll->info->name, pll->state.crtc_mask, pll->on);
15119 } 15382 }
15120 15383
15121 for_each_intel_encoder(dev, encoder) { 15384 for_each_intel_encoder(dev, encoder) {
@@ -15291,9 +15554,10 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
15291 if (!pll->on || pll->active_mask) 15554 if (!pll->on || pll->active_mask)
15292 continue; 15555 continue;
15293 15556
15294 DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name); 15557 DRM_DEBUG_KMS("%s enabled but not in use, disabling\n",
15558 pll->info->name);
15295 15559
15296 pll->funcs.disable(dev_priv, pll); 15560 pll->info->funcs->disable(dev_priv, pll);
15297 pll->on = false; 15561 pll->on = false;
15298 } 15562 }
15299 15563
diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
index 4e7418b345bc..2ef31617614a 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -218,6 +218,10 @@ struct intel_link_m_n {
218 for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++) \ 218 for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++) \
219 for_each_if((__mask) & BIT(__p)) 219 for_each_if((__mask) & BIT(__p))
220 220
221#define for_each_cpu_transcoder_masked(__dev_priv, __t, __mask) \
222 for ((__t) = 0; (__t) < I915_MAX_TRANSCODERS; (__t)++) \
223 for_each_if ((__mask) & (1 << (__t)))
224
221#define for_each_universal_plane(__dev_priv, __pipe, __p) \ 225#define for_each_universal_plane(__dev_priv, __pipe, __p) \
222 for ((__p) = 0; \ 226 for ((__p) = 0; \
223 (__p) < INTEL_INFO(__dev_priv)->num_sprites[(__pipe)] + 1; \ 227 (__p) < INTEL_INFO(__dev_priv)->num_sprites[(__pipe)] + 1; \
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index b7b4cfdeb974..dde92e4af5d3 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -43,7 +43,6 @@
43#include <drm/i915_drm.h> 43#include <drm/i915_drm.h>
44#include "i915_drv.h" 44#include "i915_drv.h"
45 45
46#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
47#define DP_DPRX_ESI_LEN 14 46#define DP_DPRX_ESI_LEN 14
48 47
49/* Compliance test status bits */ 48/* Compliance test status bits */
@@ -92,8 +91,6 @@ static const struct dp_link_dpll chv_dpll[] = {
92 { .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a } }, 91 { .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a } },
93 { 270000, /* m2_int = 27, m2_fraction = 0 */ 92 { 270000, /* m2_int = 27, m2_fraction = 0 */
94 { .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 } }, 93 { .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 } },
95 { 540000, /* m2_int = 27, m2_fraction = 0 */
96 { .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 } }
97}; 94};
98 95
99/** 96/**
@@ -1650,9 +1647,17 @@ void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
1650 } 1647 }
1651} 1648}
1652 1649
1650struct link_config_limits {
1651 int min_clock, max_clock;
1652 int min_lane_count, max_lane_count;
1653 int min_bpp, max_bpp;
1654};
1655
1653static int intel_dp_compute_bpp(struct intel_dp *intel_dp, 1656static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
1654 struct intel_crtc_state *pipe_config) 1657 struct intel_crtc_state *pipe_config)
1655{ 1658{
1659 struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
1660 struct intel_connector *intel_connector = intel_dp->attached_connector;
1656 int bpp, bpc; 1661 int bpp, bpc;
1657 1662
1658 bpp = pipe_config->pipe_bpp; 1663 bpp = pipe_config->pipe_bpp;
@@ -1661,13 +1666,16 @@ static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
1661 if (bpc > 0) 1666 if (bpc > 0)
1662 bpp = min(bpp, 3*bpc); 1667 bpp = min(bpp, 3*bpc);
1663 1668
1664 /* For DP Compliance we override the computed bpp for the pipe */ 1669 if (intel_dp_is_edp(intel_dp)) {
1665 if (intel_dp->compliance.test_data.bpc != 0) { 1670 /* Get bpp from vbt only for panels that dont have bpp in edid */
1666 pipe_config->pipe_bpp = 3*intel_dp->compliance.test_data.bpc; 1671 if (intel_connector->base.display_info.bpc == 0 &&
1667 pipe_config->dither_force_disable = pipe_config->pipe_bpp == 6*3; 1672 dev_priv->vbt.edp.bpp && dev_priv->vbt.edp.bpp < bpp) {
1668 DRM_DEBUG_KMS("Setting pipe_bpp to %d\n", 1673 DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n",
1669 pipe_config->pipe_bpp); 1674 dev_priv->vbt.edp.bpp);
1675 bpp = dev_priv->vbt.edp.bpp;
1676 }
1670 } 1677 }
1678
1671 return bpp; 1679 return bpp;
1672} 1680}
1673 1681
@@ -1688,6 +1696,142 @@ static bool intel_edp_compare_alt_mode(struct drm_display_mode *m1,
1688 return bres; 1696 return bres;
1689} 1697}
1690 1698
1699/* Adjust link config limits based on compliance test requests. */
1700static void
1701intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
1702 struct intel_crtc_state *pipe_config,
1703 struct link_config_limits *limits)
1704{
1705 /* For DP Compliance we override the computed bpp for the pipe */
1706 if (intel_dp->compliance.test_data.bpc != 0) {
1707 int bpp = 3 * intel_dp->compliance.test_data.bpc;
1708
1709 limits->min_bpp = limits->max_bpp = bpp;
1710 pipe_config->dither_force_disable = bpp == 6 * 3;
1711
1712 DRM_DEBUG_KMS("Setting pipe_bpp to %d\n", bpp);
1713 }
1714
1715 /* Use values requested by Compliance Test Request */
1716 if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
1717 int index;
1718
1719 /* Validate the compliance test data since max values
1720 * might have changed due to link train fallback.
1721 */
1722 if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate,
1723 intel_dp->compliance.test_lane_count)) {
1724 index = intel_dp_rate_index(intel_dp->common_rates,
1725 intel_dp->num_common_rates,
1726 intel_dp->compliance.test_link_rate);
1727 if (index >= 0)
1728 limits->min_clock = limits->max_clock = index;
1729 limits->min_lane_count = limits->max_lane_count =
1730 intel_dp->compliance.test_lane_count;
1731 }
1732 }
1733}
1734
1735/* Optimize link config in order: max bpp, min clock, min lanes */
1736static bool
1737intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
1738 struct intel_crtc_state *pipe_config,
1739 const struct link_config_limits *limits)
1740{
1741 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
1742 int bpp, clock, lane_count;
1743 int mode_rate, link_clock, link_avail;
1744
1745 for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) {
1746 mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
1747 bpp);
1748
1749 for (clock = limits->min_clock; clock <= limits->max_clock; clock++) {
1750 for (lane_count = limits->min_lane_count;
1751 lane_count <= limits->max_lane_count;
1752 lane_count <<= 1) {
1753 link_clock = intel_dp->common_rates[clock];
1754 link_avail = intel_dp_max_data_rate(link_clock,
1755 lane_count);
1756
1757 if (mode_rate <= link_avail) {
1758 pipe_config->lane_count = lane_count;
1759 pipe_config->pipe_bpp = bpp;
1760 pipe_config->port_clock = link_clock;
1761
1762 return true;
1763 }
1764 }
1765 }
1766 }
1767
1768 return false;
1769}
1770
1771static bool
1772intel_dp_compute_link_config(struct intel_encoder *encoder,
1773 struct intel_crtc_state *pipe_config)
1774{
1775 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
1776 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
1777 struct link_config_limits limits;
1778 int common_len;
1779
1780 common_len = intel_dp_common_len_rate_limit(intel_dp,
1781 intel_dp->max_link_rate);
1782
1783 /* No common link rates between source and sink */
1784 WARN_ON(common_len <= 0);
1785
1786 limits.min_clock = 0;
1787 limits.max_clock = common_len - 1;
1788
1789 limits.min_lane_count = 1;
1790 limits.max_lane_count = intel_dp_max_lane_count(intel_dp);
1791
1792 limits.min_bpp = 6 * 3;
1793 limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config);
1794
1795 if (intel_dp_is_edp(intel_dp)) {
1796 /*
1797 * Use the maximum clock and number of lanes the eDP panel
1798 * advertizes being capable of. The panels are generally
1799 * designed to support only a single clock and lane
1800 * configuration, and typically these values correspond to the
1801 * native resolution of the panel.
1802 */
1803 limits.min_lane_count = limits.max_lane_count;
1804 limits.min_clock = limits.max_clock;
1805 }
1806
1807 intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);
1808
1809 DRM_DEBUG_KMS("DP link computation with max lane count %i "
1810 "max rate %d max bpp %d pixel clock %iKHz\n",
1811 limits.max_lane_count,
1812 intel_dp->common_rates[limits.max_clock],
1813 limits.max_bpp, adjusted_mode->crtc_clock);
1814
1815 /*
1816 * Optimize for slow and wide. This is the place to add alternative
1817 * optimization policy.
1818 */
1819 if (!intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits))
1820 return false;
1821
1822 DRM_DEBUG_KMS("DP lane count %d clock %d bpp %d\n",
1823 pipe_config->lane_count, pipe_config->port_clock,
1824 pipe_config->pipe_bpp);
1825
1826 DRM_DEBUG_KMS("DP link rate required %i available %i\n",
1827 intel_dp_link_required(adjusted_mode->crtc_clock,
1828 pipe_config->pipe_bpp),
1829 intel_dp_max_data_rate(pipe_config->port_clock,
1830 pipe_config->lane_count));
1831
1832 return true;
1833}
1834
1691bool 1835bool
1692intel_dp_compute_config(struct intel_encoder *encoder, 1836intel_dp_compute_config(struct intel_encoder *encoder,
1693 struct intel_crtc_state *pipe_config, 1837 struct intel_crtc_state *pipe_config,
@@ -1701,27 +1845,9 @@ intel_dp_compute_config(struct intel_encoder *encoder,
1701 struct intel_connector *intel_connector = intel_dp->attached_connector; 1845 struct intel_connector *intel_connector = intel_dp->attached_connector;
1702 struct intel_digital_connector_state *intel_conn_state = 1846 struct intel_digital_connector_state *intel_conn_state =
1703 to_intel_digital_connector_state(conn_state); 1847 to_intel_digital_connector_state(conn_state);
1704 int lane_count, clock;
1705 int min_lane_count = 1;
1706 int max_lane_count = intel_dp_max_lane_count(intel_dp);
1707 /* Conveniently, the link BW constants become indices with a shift...*/
1708 int min_clock = 0;
1709 int max_clock;
1710 int bpp, mode_rate;
1711 int link_avail, link_clock;
1712 int common_len;
1713 uint8_t link_bw, rate_select;
1714 bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc, 1848 bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
1715 DP_DPCD_QUIRK_LIMITED_M_N); 1849 DP_DPCD_QUIRK_LIMITED_M_N);
1716 1850
1717 common_len = intel_dp_common_len_rate_limit(intel_dp,
1718 intel_dp->max_link_rate);
1719
1720 /* No common link rates between source and sink */
1721 WARN_ON(common_len <= 0);
1722
1723 max_clock = common_len - 1;
1724
1725 if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A) 1851 if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A)
1726 pipe_config->has_pch_encoder = true; 1852 pipe_config->has_pch_encoder = true;
1727 1853
@@ -1747,6 +1873,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
1747 1873
1748 if (INTEL_GEN(dev_priv) >= 9) { 1874 if (INTEL_GEN(dev_priv) >= 9) {
1749 int ret; 1875 int ret;
1876
1750 ret = skl_update_scaler_crtc(pipe_config); 1877 ret = skl_update_scaler_crtc(pipe_config);
1751 if (ret) 1878 if (ret)
1752 return ret; 1879 return ret;
@@ -1767,75 +1894,9 @@ intel_dp_compute_config(struct intel_encoder *encoder,
1767 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) 1894 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
1768 return false; 1895 return false;
1769 1896
1770 /* Use values requested by Compliance Test Request */ 1897 if (!intel_dp_compute_link_config(encoder, pipe_config))
1771 if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { 1898 return false;
1772 int index;
1773
1774 /* Validate the compliance test data since max values
1775 * might have changed due to link train fallback.
1776 */
1777 if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate,
1778 intel_dp->compliance.test_lane_count)) {
1779 index = intel_dp_rate_index(intel_dp->common_rates,
1780 intel_dp->num_common_rates,
1781 intel_dp->compliance.test_link_rate);
1782 if (index >= 0)
1783 min_clock = max_clock = index;
1784 min_lane_count = max_lane_count = intel_dp->compliance.test_lane_count;
1785 }
1786 }
1787 DRM_DEBUG_KMS("DP link computation with max lane count %i "
1788 "max bw %d pixel clock %iKHz\n",
1789 max_lane_count, intel_dp->common_rates[max_clock],
1790 adjusted_mode->crtc_clock);
1791
1792 /* Walk through all bpp values. Luckily they're all nicely spaced with 2
1793 * bpc in between. */
1794 bpp = intel_dp_compute_bpp(intel_dp, pipe_config);
1795 if (intel_dp_is_edp(intel_dp)) {
1796
1797 /* Get bpp from vbt only for panels that dont have bpp in edid */
1798 if (intel_connector->base.display_info.bpc == 0 &&
1799 (dev_priv->vbt.edp.bpp && dev_priv->vbt.edp.bpp < bpp)) {
1800 DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n",
1801 dev_priv->vbt.edp.bpp);
1802 bpp = dev_priv->vbt.edp.bpp;
1803 }
1804
1805 /*
1806 * Use the maximum clock and number of lanes the eDP panel
1807 * advertizes being capable of. The panels are generally
1808 * designed to support only a single clock and lane
1809 * configuration, and typically these values correspond to the
1810 * native resolution of the panel.
1811 */
1812 min_lane_count = max_lane_count;
1813 min_clock = max_clock;
1814 }
1815
1816 for (; bpp >= 6*3; bpp -= 2*3) {
1817 mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
1818 bpp);
1819
1820 for (clock = min_clock; clock <= max_clock; clock++) {
1821 for (lane_count = min_lane_count;
1822 lane_count <= max_lane_count;
1823 lane_count <<= 1) {
1824
1825 link_clock = intel_dp->common_rates[clock];
1826 link_avail = intel_dp_max_data_rate(link_clock,
1827 lane_count);
1828
1829 if (mode_rate <= link_avail) {
1830 goto found;
1831 }
1832 }
1833 }
1834 }
1835
1836 return false;
1837 1899
1838found:
1839 if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) { 1900 if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) {
1840 /* 1901 /*
1841 * See: 1902 * See:
@@ -1843,7 +1904,7 @@ found:
1843 * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry 1904 * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry
1844 */ 1905 */
1845 pipe_config->limited_color_range = 1906 pipe_config->limited_color_range =
1846 bpp != 18 && 1907 pipe_config->pipe_bpp != 18 &&
1847 drm_default_rgb_quant_range(adjusted_mode) == 1908 drm_default_rgb_quant_range(adjusted_mode) ==
1848 HDMI_QUANTIZATION_RANGE_LIMITED; 1909 HDMI_QUANTIZATION_RANGE_LIMITED;
1849 } else { 1910 } else {
@@ -1851,21 +1912,7 @@ found:
1851 intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_LIMITED; 1912 intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_LIMITED;
1852 } 1913 }
1853 1914
1854 pipe_config->lane_count = lane_count; 1915 intel_link_compute_m_n(pipe_config->pipe_bpp, pipe_config->lane_count,
1855
1856 pipe_config->pipe_bpp = bpp;
1857 pipe_config->port_clock = intel_dp->common_rates[clock];
1858
1859 intel_dp_compute_rate(intel_dp, pipe_config->port_clock,
1860 &link_bw, &rate_select);
1861
1862 DRM_DEBUG_KMS("DP link bw %02x rate select %02x lane count %d clock %d bpp %d\n",
1863 link_bw, rate_select, pipe_config->lane_count,
1864 pipe_config->port_clock, bpp);
1865 DRM_DEBUG_KMS("DP link bw required %i available %i\n",
1866 mode_rate, link_avail);
1867
1868 intel_link_compute_m_n(bpp, lane_count,
1869 adjusted_mode->crtc_clock, 1916 adjusted_mode->crtc_clock,
1870 pipe_config->port_clock, 1917 pipe_config->port_clock,
1871 &pipe_config->dp_m_n, 1918 &pipe_config->dp_m_n,
@@ -1874,11 +1921,12 @@ found:
1874 if (intel_connector->panel.downclock_mode != NULL && 1921 if (intel_connector->panel.downclock_mode != NULL &&
1875 dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) { 1922 dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
1876 pipe_config->has_drrs = true; 1923 pipe_config->has_drrs = true;
1877 intel_link_compute_m_n(bpp, lane_count, 1924 intel_link_compute_m_n(pipe_config->pipe_bpp,
1878 intel_connector->panel.downclock_mode->clock, 1925 pipe_config->lane_count,
1879 pipe_config->port_clock, 1926 intel_connector->panel.downclock_mode->clock,
1880 &pipe_config->dp_m2_n2, 1927 pipe_config->port_clock,
1881 reduce_m_n); 1928 &pipe_config->dp_m2_n2,
1929 reduce_m_n);
1882 } 1930 }
1883 1931
1884 if (!HAS_DDI(dev_priv)) 1932 if (!HAS_DDI(dev_priv))
@@ -2881,10 +2929,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
2881 } 2929 }
2882 2930
2883 } else { 2931 } else {
2884 if (IS_CHERRYVIEW(dev_priv)) 2932 *DP &= ~DP_LINK_TRAIN_MASK;
2885 *DP &= ~DP_LINK_TRAIN_MASK_CHV;
2886 else
2887 *DP &= ~DP_LINK_TRAIN_MASK;
2888 2933
2889 switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { 2934 switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
2890 case DP_TRAINING_PATTERN_DISABLE: 2935 case DP_TRAINING_PATTERN_DISABLE:
@@ -2897,12 +2942,8 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
2897 *DP |= DP_LINK_TRAIN_PAT_2; 2942 *DP |= DP_LINK_TRAIN_PAT_2;
2898 break; 2943 break;
2899 case DP_TRAINING_PATTERN_3: 2944 case DP_TRAINING_PATTERN_3:
2900 if (IS_CHERRYVIEW(dev_priv)) { 2945 DRM_DEBUG_KMS("TPS3 not supported, using TPS2 instead\n");
2901 *DP |= DP_LINK_TRAIN_PAT_3_CHV; 2946 *DP |= DP_LINK_TRAIN_PAT_2;
2902 } else {
2903 DRM_DEBUG_KMS("TPS3 not supported, using TPS2 instead\n");
2904 *DP |= DP_LINK_TRAIN_PAT_2;
2905 }
2906 break; 2947 break;
2907 } 2948 }
2908 } 2949 }
@@ -3641,10 +3682,7 @@ intel_dp_link_down(struct intel_encoder *encoder,
3641 DP &= ~DP_LINK_TRAIN_MASK_CPT; 3682 DP &= ~DP_LINK_TRAIN_MASK_CPT;
3642 DP |= DP_LINK_TRAIN_PAT_IDLE_CPT; 3683 DP |= DP_LINK_TRAIN_PAT_IDLE_CPT;
3643 } else { 3684 } else {
3644 if (IS_CHERRYVIEW(dev_priv)) 3685 DP &= ~DP_LINK_TRAIN_MASK;
3645 DP &= ~DP_LINK_TRAIN_MASK_CHV;
3646 else
3647 DP &= ~DP_LINK_TRAIN_MASK;
3648 DP |= DP_LINK_TRAIN_PAT_IDLE; 3686 DP |= DP_LINK_TRAIN_PAT_IDLE;
3649 } 3687 }
3650 I915_WRITE(intel_dp->output_reg, DP); 3688 I915_WRITE(intel_dp->output_reg, DP);
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index f59b59bb0a21..3fcaa98b9055 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -139,6 +139,11 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
139 intel_dp_compute_rate(intel_dp, intel_dp->link_rate, 139 intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
140 &link_bw, &rate_select); 140 &link_bw, &rate_select);
141 141
142 if (link_bw)
143 DRM_DEBUG_KMS("Using LINK_BW_SET value %02x\n", link_bw);
144 else
145 DRM_DEBUG_KMS("Using LINK_RATE_SET value %02x\n", rate_select);
146
142 /* Write the link configuration data */ 147 /* Write the link configuration data */
143 link_config[0] = link_bw; 148 link_config[0] = link_bw;
144 link_config[1] = intel_dp->lane_count; 149 link_config[1] = intel_dp->lane_count;
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index c3de0918ee13..9e6956c08688 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -180,9 +180,11 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
180 intel_dp->active_mst_links--; 180 intel_dp->active_mst_links--;
181 181
182 intel_mst->connector = NULL; 182 intel_mst->connector = NULL;
183 if (intel_dp->active_mst_links == 0) 183 if (intel_dp->active_mst_links == 0) {
184 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
184 intel_dig_port->base.post_disable(&intel_dig_port->base, 185 intel_dig_port->base.post_disable(&intel_dig_port->base,
185 old_crtc_state, NULL); 186 old_crtc_state, NULL);
187 }
186 188
187 DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); 189 DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
188} 190}
@@ -223,7 +225,11 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
223 225
224 DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); 226 DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
225 227
228 if (intel_dp->active_mst_links == 0)
229 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
230
226 drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true); 231 drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
232
227 if (intel_dp->active_mst_links == 0) 233 if (intel_dp->active_mst_links == 0)
228 intel_dig_port->base.pre_enable(&intel_dig_port->base, 234 intel_dig_port->base.pre_enable(&intel_dig_port->base,
229 pipe_config, NULL); 235 pipe_config, NULL);
diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c
index c8e9e44e5981..00b3ab656b06 100644
--- a/drivers/gpu/drm/i915/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/intel_dpio_phy.c
@@ -380,13 +380,14 @@ static void _bxt_ddi_phy_init(struct drm_i915_private *dev_priv,
380 * all 1s. Eventually they become accessible as they power up, then 380 * all 1s. Eventually they become accessible as they power up, then
381 * the reserved bit will give the default 0. Poll on the reserved bit 381 * the reserved bit will give the default 0. Poll on the reserved bit
382 * becoming 0 to find when the PHY is accessible. 382 * becoming 0 to find when the PHY is accessible.
383 * HW team confirmed that the time to reach phypowergood status is 383 * The flag should get set in 100us according to the HW team, but
384 * anywhere between 50 us and 100us. 384 * use 1ms due to occasional timeouts observed with that.
385 */ 385 */
386 if (wait_for_us(((I915_READ(BXT_PORT_CL1CM_DW0(phy)) & 386 if (intel_wait_for_register_fw(dev_priv, BXT_PORT_CL1CM_DW0(phy),
387 (PHY_RESERVED | PHY_POWER_GOOD)) == PHY_POWER_GOOD), 100)) { 387 PHY_RESERVED | PHY_POWER_GOOD,
388 PHY_POWER_GOOD,
389 1))
388 DRM_ERROR("timeout during PHY%d power on\n", phy); 390 DRM_ERROR("timeout during PHY%d power on\n", phy);
389 }
390 391
391 /* Program PLL Rcomp code offset */ 392 /* Program PLL Rcomp code offset */
392 val = I915_READ(BXT_PORT_CL1CM_DW9(phy)); 393 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 51c5ae4e9116..383fbc15113d 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -118,10 +118,10 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
118 if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state))) 118 if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
119 return; 119 return;
120 120
121 cur_state = pll->funcs.get_hw_state(dev_priv, pll, &hw_state); 121 cur_state = pll->info->funcs->get_hw_state(dev_priv, pll, &hw_state);
122 I915_STATE_WARN(cur_state != state, 122 I915_STATE_WARN(cur_state != state,
123 "%s assertion failure (expected %s, current %s)\n", 123 "%s assertion failure (expected %s, current %s)\n",
124 pll->name, onoff(state), onoff(cur_state)); 124 pll->info->name, onoff(state), onoff(cur_state));
125} 125}
126 126
127/** 127/**
@@ -143,11 +143,11 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc)
143 mutex_lock(&dev_priv->dpll_lock); 143 mutex_lock(&dev_priv->dpll_lock);
144 WARN_ON(!pll->state.crtc_mask); 144 WARN_ON(!pll->state.crtc_mask);
145 if (!pll->active_mask) { 145 if (!pll->active_mask) {
146 DRM_DEBUG_DRIVER("setting up %s\n", pll->name); 146 DRM_DEBUG_DRIVER("setting up %s\n", pll->info->name);
147 WARN_ON(pll->on); 147 WARN_ON(pll->on);
148 assert_shared_dpll_disabled(dev_priv, pll); 148 assert_shared_dpll_disabled(dev_priv, pll);
149 149
150 pll->funcs.prepare(dev_priv, pll); 150 pll->info->funcs->prepare(dev_priv, pll);
151 } 151 }
152 mutex_unlock(&dev_priv->dpll_lock); 152 mutex_unlock(&dev_priv->dpll_lock);
153} 153}
@@ -179,7 +179,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc)
179 pll->active_mask |= crtc_mask; 179 pll->active_mask |= crtc_mask;
180 180
181 DRM_DEBUG_KMS("enable %s (active %x, on? %d) for crtc %d\n", 181 DRM_DEBUG_KMS("enable %s (active %x, on? %d) for crtc %d\n",
182 pll->name, pll->active_mask, pll->on, 182 pll->info->name, pll->active_mask, pll->on,
183 crtc->base.base.id); 183 crtc->base.base.id);
184 184
185 if (old_mask) { 185 if (old_mask) {
@@ -189,8 +189,8 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc)
189 } 189 }
190 WARN_ON(pll->on); 190 WARN_ON(pll->on);
191 191
192 DRM_DEBUG_KMS("enabling %s\n", pll->name); 192 DRM_DEBUG_KMS("enabling %s\n", pll->info->name);
193 pll->funcs.enable(dev_priv, pll); 193 pll->info->funcs->enable(dev_priv, pll);
194 pll->on = true; 194 pll->on = true;
195 195
196out: 196out:
@@ -221,7 +221,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
221 goto out; 221 goto out;
222 222
223 DRM_DEBUG_KMS("disable %s (active %x, on? %d) for crtc %d\n", 223 DRM_DEBUG_KMS("disable %s (active %x, on? %d) for crtc %d\n",
224 pll->name, pll->active_mask, pll->on, 224 pll->info->name, pll->active_mask, pll->on,
225 crtc->base.base.id); 225 crtc->base.base.id);
226 226
227 assert_shared_dpll_enabled(dev_priv, pll); 227 assert_shared_dpll_enabled(dev_priv, pll);
@@ -231,8 +231,8 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
231 if (pll->active_mask) 231 if (pll->active_mask)
232 goto out; 232 goto out;
233 233
234 DRM_DEBUG_KMS("disabling %s\n", pll->name); 234 DRM_DEBUG_KMS("disabling %s\n", pll->info->name);
235 pll->funcs.disable(dev_priv, pll); 235 pll->info->funcs->disable(dev_priv, pll);
236 pll->on = false; 236 pll->on = false;
237 237
238out: 238out:
@@ -263,7 +263,8 @@ intel_find_shared_dpll(struct intel_crtc *crtc,
263 &shared_dpll[i].hw_state, 263 &shared_dpll[i].hw_state,
264 sizeof(crtc_state->dpll_hw_state)) == 0) { 264 sizeof(crtc_state->dpll_hw_state)) == 0) {
265 DRM_DEBUG_KMS("[CRTC:%d:%s] sharing existing %s (crtc mask 0x%08x, active %x)\n", 265 DRM_DEBUG_KMS("[CRTC:%d:%s] sharing existing %s (crtc mask 0x%08x, active %x)\n",
266 crtc->base.base.id, crtc->base.name, pll->name, 266 crtc->base.base.id, crtc->base.name,
267 pll->info->name,
267 shared_dpll[i].crtc_mask, 268 shared_dpll[i].crtc_mask,
268 pll->active_mask); 269 pll->active_mask);
269 return pll; 270 return pll;
@@ -275,7 +276,8 @@ intel_find_shared_dpll(struct intel_crtc *crtc,
275 pll = &dev_priv->shared_dplls[i]; 276 pll = &dev_priv->shared_dplls[i];
276 if (shared_dpll[i].crtc_mask == 0) { 277 if (shared_dpll[i].crtc_mask == 0) {
277 DRM_DEBUG_KMS("[CRTC:%d:%s] allocated %s\n", 278 DRM_DEBUG_KMS("[CRTC:%d:%s] allocated %s\n",
278 crtc->base.base.id, crtc->base.name, pll->name); 279 crtc->base.base.id, crtc->base.name,
280 pll->info->name);
279 return pll; 281 return pll;
280 } 282 }
281 } 283 }
@@ -289,19 +291,19 @@ intel_reference_shared_dpll(struct intel_shared_dpll *pll,
289{ 291{
290 struct intel_shared_dpll_state *shared_dpll; 292 struct intel_shared_dpll_state *shared_dpll;
291 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); 293 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
292 enum intel_dpll_id i = pll->id; 294 const enum intel_dpll_id id = pll->info->id;
293 295
294 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state); 296 shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
295 297
296 if (shared_dpll[i].crtc_mask == 0) 298 if (shared_dpll[id].crtc_mask == 0)
297 shared_dpll[i].hw_state = 299 shared_dpll[id].hw_state =
298 crtc_state->dpll_hw_state; 300 crtc_state->dpll_hw_state;
299 301
300 crtc_state->shared_dpll = pll; 302 crtc_state->shared_dpll = pll;
301 DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, 303 DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->info->name,
302 pipe_name(crtc->pipe)); 304 pipe_name(crtc->pipe));
303 305
304 shared_dpll[pll->id].crtc_mask |= 1 << crtc->pipe; 306 shared_dpll[id].crtc_mask |= 1 << crtc->pipe;
305} 307}
306 308
307/** 309/**
@@ -341,15 +343,16 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
341 struct intel_shared_dpll *pll, 343 struct intel_shared_dpll *pll,
342 struct intel_dpll_hw_state *hw_state) 344 struct intel_dpll_hw_state *hw_state)
343{ 345{
346 const enum intel_dpll_id id = pll->info->id;
344 uint32_t val; 347 uint32_t val;
345 348
346 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) 349 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
347 return false; 350 return false;
348 351
349 val = I915_READ(PCH_DPLL(pll->id)); 352 val = I915_READ(PCH_DPLL(id));
350 hw_state->dpll = val; 353 hw_state->dpll = val;
351 hw_state->fp0 = I915_READ(PCH_FP0(pll->id)); 354 hw_state->fp0 = I915_READ(PCH_FP0(id));
352 hw_state->fp1 = I915_READ(PCH_FP1(pll->id)); 355 hw_state->fp1 = I915_READ(PCH_FP1(id));
353 356
354 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); 357 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
355 358
@@ -359,8 +362,10 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
359static void ibx_pch_dpll_prepare(struct drm_i915_private *dev_priv, 362static void ibx_pch_dpll_prepare(struct drm_i915_private *dev_priv,
360 struct intel_shared_dpll *pll) 363 struct intel_shared_dpll *pll)
361{ 364{
362 I915_WRITE(PCH_FP0(pll->id), pll->state.hw_state.fp0); 365 const enum intel_dpll_id id = pll->info->id;
363 I915_WRITE(PCH_FP1(pll->id), pll->state.hw_state.fp1); 366
367 I915_WRITE(PCH_FP0(id), pll->state.hw_state.fp0);
368 I915_WRITE(PCH_FP1(id), pll->state.hw_state.fp1);
364} 369}
365 370
366static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) 371static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
@@ -379,13 +384,15 @@ static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
379static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, 384static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
380 struct intel_shared_dpll *pll) 385 struct intel_shared_dpll *pll)
381{ 386{
387 const enum intel_dpll_id id = pll->info->id;
388
382 /* PCH refclock must be enabled first */ 389 /* PCH refclock must be enabled first */
383 ibx_assert_pch_refclk_enabled(dev_priv); 390 ibx_assert_pch_refclk_enabled(dev_priv);
384 391
385 I915_WRITE(PCH_DPLL(pll->id), pll->state.hw_state.dpll); 392 I915_WRITE(PCH_DPLL(id), pll->state.hw_state.dpll);
386 393
387 /* Wait for the clocks to stabilize. */ 394 /* Wait for the clocks to stabilize. */
388 POSTING_READ(PCH_DPLL(pll->id)); 395 POSTING_READ(PCH_DPLL(id));
389 udelay(150); 396 udelay(150);
390 397
391 /* The pixel multiplier can only be updated once the 398 /* The pixel multiplier can only be updated once the
@@ -393,14 +400,15 @@ static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
393 * 400 *
394 * So write it again. 401 * So write it again.
395 */ 402 */
396 I915_WRITE(PCH_DPLL(pll->id), pll->state.hw_state.dpll); 403 I915_WRITE(PCH_DPLL(id), pll->state.hw_state.dpll);
397 POSTING_READ(PCH_DPLL(pll->id)); 404 POSTING_READ(PCH_DPLL(id));
398 udelay(200); 405 udelay(200);
399} 406}
400 407
401static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, 408static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
402 struct intel_shared_dpll *pll) 409 struct intel_shared_dpll *pll)
403{ 410{
411 const enum intel_dpll_id id = pll->info->id;
404 struct drm_device *dev = &dev_priv->drm; 412 struct drm_device *dev = &dev_priv->drm;
405 struct intel_crtc *crtc; 413 struct intel_crtc *crtc;
406 414
@@ -410,8 +418,8 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
410 assert_pch_transcoder_disabled(dev_priv, crtc->pipe); 418 assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
411 } 419 }
412 420
413 I915_WRITE(PCH_DPLL(pll->id), 0); 421 I915_WRITE(PCH_DPLL(id), 0);
414 POSTING_READ(PCH_DPLL(pll->id)); 422 POSTING_READ(PCH_DPLL(id));
415 udelay(200); 423 udelay(200);
416} 424}
417 425
@@ -429,7 +437,8 @@ ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
429 pll = &dev_priv->shared_dplls[i]; 437 pll = &dev_priv->shared_dplls[i];
430 438
431 DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n", 439 DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n",
432 crtc->base.base.id, crtc->base.name, pll->name); 440 crtc->base.base.id, crtc->base.name,
441 pll->info->name);
433 } else { 442 } else {
434 pll = intel_find_shared_dpll(crtc, crtc_state, 443 pll = intel_find_shared_dpll(crtc, crtc_state,
435 DPLL_ID_PCH_PLL_A, 444 DPLL_ID_PCH_PLL_A,
@@ -466,8 +475,10 @@ static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
466static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv, 475static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
467 struct intel_shared_dpll *pll) 476 struct intel_shared_dpll *pll)
468{ 477{
469 I915_WRITE(WRPLL_CTL(pll->id), pll->state.hw_state.wrpll); 478 const enum intel_dpll_id id = pll->info->id;
470 POSTING_READ(WRPLL_CTL(pll->id)); 479
480 I915_WRITE(WRPLL_CTL(id), pll->state.hw_state.wrpll);
481 POSTING_READ(WRPLL_CTL(id));
471 udelay(20); 482 udelay(20);
472} 483}
473 484
@@ -482,11 +493,12 @@ static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
482static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv, 493static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
483 struct intel_shared_dpll *pll) 494 struct intel_shared_dpll *pll)
484{ 495{
496 const enum intel_dpll_id id = pll->info->id;
485 uint32_t val; 497 uint32_t val;
486 498
487 val = I915_READ(WRPLL_CTL(pll->id)); 499 val = I915_READ(WRPLL_CTL(id));
488 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE); 500 I915_WRITE(WRPLL_CTL(id), val & ~WRPLL_PLL_ENABLE);
489 POSTING_READ(WRPLL_CTL(pll->id)); 501 POSTING_READ(WRPLL_CTL(id));
490} 502}
491 503
492static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv, 504static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
@@ -503,12 +515,13 @@ static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
503 struct intel_shared_dpll *pll, 515 struct intel_shared_dpll *pll,
504 struct intel_dpll_hw_state *hw_state) 516 struct intel_dpll_hw_state *hw_state)
505{ 517{
518 const enum intel_dpll_id id = pll->info->id;
506 uint32_t val; 519 uint32_t val;
507 520
508 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) 521 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
509 return false; 522 return false;
510 523
511 val = I915_READ(WRPLL_CTL(pll->id)); 524 val = I915_READ(WRPLL_CTL(id));
512 hw_state->wrpll = val; 525 hw_state->wrpll = val;
513 526
514 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); 527 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
@@ -914,13 +927,15 @@ static const struct skl_dpll_regs skl_dpll_regs[4] = {
914static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv, 927static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
915 struct intel_shared_dpll *pll) 928 struct intel_shared_dpll *pll)
916{ 929{
930 const enum intel_dpll_id id = pll->info->id;
917 uint32_t val; 931 uint32_t val;
918 932
919 val = I915_READ(DPLL_CTRL1); 933 val = I915_READ(DPLL_CTRL1);
920 934
921 val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) | 935 val &= ~(DPLL_CTRL1_HDMI_MODE(id) |
922 DPLL_CTRL1_LINK_RATE_MASK(pll->id)); 936 DPLL_CTRL1_SSC(id) |
923 val |= pll->state.hw_state.ctrl1 << (pll->id * 6); 937 DPLL_CTRL1_LINK_RATE_MASK(id));
938 val |= pll->state.hw_state.ctrl1 << (id * 6);
924 939
925 I915_WRITE(DPLL_CTRL1, val); 940 I915_WRITE(DPLL_CTRL1, val);
926 POSTING_READ(DPLL_CTRL1); 941 POSTING_READ(DPLL_CTRL1);
@@ -930,24 +945,25 @@ static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
930 struct intel_shared_dpll *pll) 945 struct intel_shared_dpll *pll)
931{ 946{
932 const struct skl_dpll_regs *regs = skl_dpll_regs; 947 const struct skl_dpll_regs *regs = skl_dpll_regs;
948 const enum intel_dpll_id id = pll->info->id;
933 949
934 skl_ddi_pll_write_ctrl1(dev_priv, pll); 950 skl_ddi_pll_write_ctrl1(dev_priv, pll);
935 951
936 I915_WRITE(regs[pll->id].cfgcr1, pll->state.hw_state.cfgcr1); 952 I915_WRITE(regs[id].cfgcr1, pll->state.hw_state.cfgcr1);
937 I915_WRITE(regs[pll->id].cfgcr2, pll->state.hw_state.cfgcr2); 953 I915_WRITE(regs[id].cfgcr2, pll->state.hw_state.cfgcr2);
938 POSTING_READ(regs[pll->id].cfgcr1); 954 POSTING_READ(regs[id].cfgcr1);
939 POSTING_READ(regs[pll->id].cfgcr2); 955 POSTING_READ(regs[id].cfgcr2);
940 956
941 /* the enable bit is always bit 31 */ 957 /* the enable bit is always bit 31 */
942 I915_WRITE(regs[pll->id].ctl, 958 I915_WRITE(regs[id].ctl,
943 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE); 959 I915_READ(regs[id].ctl) | LCPLL_PLL_ENABLE);
944 960
945 if (intel_wait_for_register(dev_priv, 961 if (intel_wait_for_register(dev_priv,
946 DPLL_STATUS, 962 DPLL_STATUS,
947 DPLL_LOCK(pll->id), 963 DPLL_LOCK(id),
948 DPLL_LOCK(pll->id), 964 DPLL_LOCK(id),
949 5)) 965 5))
950 DRM_ERROR("DPLL %d not locked\n", pll->id); 966 DRM_ERROR("DPLL %d not locked\n", id);
951} 967}
952 968
953static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv, 969static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
@@ -960,11 +976,12 @@ static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
960 struct intel_shared_dpll *pll) 976 struct intel_shared_dpll *pll)
961{ 977{
962 const struct skl_dpll_regs *regs = skl_dpll_regs; 978 const struct skl_dpll_regs *regs = skl_dpll_regs;
979 const enum intel_dpll_id id = pll->info->id;
963 980
964 /* the enable bit is always bit 31 */ 981 /* the enable bit is always bit 31 */
965 I915_WRITE(regs[pll->id].ctl, 982 I915_WRITE(regs[id].ctl,
966 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE); 983 I915_READ(regs[id].ctl) & ~LCPLL_PLL_ENABLE);
967 POSTING_READ(regs[pll->id].ctl); 984 POSTING_READ(regs[id].ctl);
968} 985}
969 986
970static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv, 987static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
@@ -978,6 +995,7 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
978{ 995{
979 uint32_t val; 996 uint32_t val;
980 const struct skl_dpll_regs *regs = skl_dpll_regs; 997 const struct skl_dpll_regs *regs = skl_dpll_regs;
998 const enum intel_dpll_id id = pll->info->id;
981 bool ret; 999 bool ret;
982 1000
983 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) 1001 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
@@ -985,17 +1003,17 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
985 1003
986 ret = false; 1004 ret = false;
987 1005
988 val = I915_READ(regs[pll->id].ctl); 1006 val = I915_READ(regs[id].ctl);
989 if (!(val & LCPLL_PLL_ENABLE)) 1007 if (!(val & LCPLL_PLL_ENABLE))
990 goto out; 1008 goto out;
991 1009
992 val = I915_READ(DPLL_CTRL1); 1010 val = I915_READ(DPLL_CTRL1);
993 hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f; 1011 hw_state->ctrl1 = (val >> (id * 6)) & 0x3f;
994 1012
995 /* avoid reading back stale values if HDMI mode is not enabled */ 1013 /* avoid reading back stale values if HDMI mode is not enabled */
996 if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) { 1014 if (val & DPLL_CTRL1_HDMI_MODE(id)) {
997 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1); 1015 hw_state->cfgcr1 = I915_READ(regs[id].cfgcr1);
998 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2); 1016 hw_state->cfgcr2 = I915_READ(regs[id].cfgcr2);
999 } 1017 }
1000 ret = true; 1018 ret = true;
1001 1019
@@ -1011,6 +1029,7 @@ static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
1011{ 1029{
1012 uint32_t val; 1030 uint32_t val;
1013 const struct skl_dpll_regs *regs = skl_dpll_regs; 1031 const struct skl_dpll_regs *regs = skl_dpll_regs;
1032 const enum intel_dpll_id id = pll->info->id;
1014 bool ret; 1033 bool ret;
1015 1034
1016 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) 1035 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
@@ -1019,12 +1038,12 @@ static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
1019 ret = false; 1038 ret = false;
1020 1039
1021 /* DPLL0 is always enabled since it drives CDCLK */ 1040 /* DPLL0 is always enabled since it drives CDCLK */
1022 val = I915_READ(regs[pll->id].ctl); 1041 val = I915_READ(regs[id].ctl);
1023 if (WARN_ON(!(val & LCPLL_PLL_ENABLE))) 1042 if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
1024 goto out; 1043 goto out;
1025 1044
1026 val = I915_READ(DPLL_CTRL1); 1045 val = I915_READ(DPLL_CTRL1);
1027 hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f; 1046 hw_state->ctrl1 = (val >> (id * 6)) & 0x3f;
1028 1047
1029 ret = true; 1048 ret = true;
1030 1049
@@ -1424,7 +1443,7 @@ static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
1424 struct intel_shared_dpll *pll) 1443 struct intel_shared_dpll *pll)
1425{ 1444{
1426 uint32_t temp; 1445 uint32_t temp;
1427 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ 1446 enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
1428 enum dpio_phy phy; 1447 enum dpio_phy phy;
1429 enum dpio_channel ch; 1448 enum dpio_channel ch;
1430 1449
@@ -1543,7 +1562,7 @@ static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
1543static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv, 1562static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
1544 struct intel_shared_dpll *pll) 1563 struct intel_shared_dpll *pll)
1545{ 1564{
1546 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ 1565 enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
1547 uint32_t temp; 1566 uint32_t temp;
1548 1567
1549 temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); 1568 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
@@ -1566,7 +1585,7 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
1566 struct intel_shared_dpll *pll, 1585 struct intel_shared_dpll *pll,
1567 struct intel_dpll_hw_state *hw_state) 1586 struct intel_dpll_hw_state *hw_state)
1568{ 1587{
1569 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ 1588 enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
1570 uint32_t val; 1589 uint32_t val;
1571 bool ret; 1590 bool ret;
1572 enum dpio_phy phy; 1591 enum dpio_phy phy;
@@ -1824,7 +1843,7 @@ bxt_get_dpll(struct intel_crtc *crtc,
1824 pll = intel_get_shared_dpll_by_id(dev_priv, i); 1843 pll = intel_get_shared_dpll_by_id(dev_priv, i);
1825 1844
1826 DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n", 1845 DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n",
1827 crtc->base.base.id, crtc->base.name, pll->name); 1846 crtc->base.base.id, crtc->base.name, pll->info->name);
1828 1847
1829 intel_reference_shared_dpll(pll, crtc_state); 1848 intel_reference_shared_dpll(pll, crtc_state);
1830 1849
@@ -1877,13 +1896,6 @@ static void intel_ddi_pll_init(struct drm_device *dev)
1877 } 1896 }
1878} 1897}
1879 1898
1880struct dpll_info {
1881 const char *name;
1882 const int id;
1883 const struct intel_shared_dpll_funcs *funcs;
1884 uint32_t flags;
1885};
1886
1887struct intel_dpll_mgr { 1899struct intel_dpll_mgr {
1888 const struct dpll_info *dpll_info; 1900 const struct dpll_info *dpll_info;
1889 1901
@@ -1896,9 +1908,9 @@ struct intel_dpll_mgr {
1896}; 1908};
1897 1909
1898static const struct dpll_info pch_plls[] = { 1910static const struct dpll_info pch_plls[] = {
1899 { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs, 0 }, 1911 { "PCH DPLL A", &ibx_pch_dpll_funcs, DPLL_ID_PCH_PLL_A, 0 },
1900 { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs, 0 }, 1912 { "PCH DPLL B", &ibx_pch_dpll_funcs, DPLL_ID_PCH_PLL_B, 0 },
1901 { NULL, -1, NULL, 0 }, 1913 { },
1902}; 1914};
1903 1915
1904static const struct intel_dpll_mgr pch_pll_mgr = { 1916static const struct intel_dpll_mgr pch_pll_mgr = {
@@ -1908,13 +1920,13 @@ static const struct intel_dpll_mgr pch_pll_mgr = {
1908}; 1920};
1909 1921
1910static const struct dpll_info hsw_plls[] = { 1922static const struct dpll_info hsw_plls[] = {
1911 { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs, 0 }, 1923 { "WRPLL 1", &hsw_ddi_wrpll_funcs, DPLL_ID_WRPLL1, 0 },
1912 { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs, 0 }, 1924 { "WRPLL 2", &hsw_ddi_wrpll_funcs, DPLL_ID_WRPLL2, 0 },
1913 { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs, 0 }, 1925 { "SPLL", &hsw_ddi_spll_funcs, DPLL_ID_SPLL, 0 },
1914 { "LCPLL 810", DPLL_ID_LCPLL_810, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON }, 1926 { "LCPLL 810", &hsw_ddi_lcpll_funcs, DPLL_ID_LCPLL_810, INTEL_DPLL_ALWAYS_ON },
1915 { "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON }, 1927 { "LCPLL 1350", &hsw_ddi_lcpll_funcs, DPLL_ID_LCPLL_1350, INTEL_DPLL_ALWAYS_ON },
1916 { "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON }, 1928 { "LCPLL 2700", &hsw_ddi_lcpll_funcs, DPLL_ID_LCPLL_2700, INTEL_DPLL_ALWAYS_ON },
1917 { NULL, -1, NULL, }, 1929 { },
1918}; 1930};
1919 1931
1920static const struct intel_dpll_mgr hsw_pll_mgr = { 1932static const struct intel_dpll_mgr hsw_pll_mgr = {
@@ -1924,11 +1936,11 @@ static const struct intel_dpll_mgr hsw_pll_mgr = {
1924}; 1936};
1925 1937
1926static const struct dpll_info skl_plls[] = { 1938static const struct dpll_info skl_plls[] = {
1927 { "DPLL 0", DPLL_ID_SKL_DPLL0, &skl_ddi_dpll0_funcs, INTEL_DPLL_ALWAYS_ON }, 1939 { "DPLL 0", &skl_ddi_dpll0_funcs, DPLL_ID_SKL_DPLL0, INTEL_DPLL_ALWAYS_ON },
1928 { "DPLL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs, 0 }, 1940 { "DPLL 1", &skl_ddi_pll_funcs, DPLL_ID_SKL_DPLL1, 0 },
1929 { "DPLL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 }, 1941 { "DPLL 2", &skl_ddi_pll_funcs, DPLL_ID_SKL_DPLL2, 0 },
1930 { "DPLL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 }, 1942 { "DPLL 3", &skl_ddi_pll_funcs, DPLL_ID_SKL_DPLL3, 0 },
1931 { NULL, -1, NULL, }, 1943 { },
1932}; 1944};
1933 1945
1934static const struct intel_dpll_mgr skl_pll_mgr = { 1946static const struct intel_dpll_mgr skl_pll_mgr = {
@@ -1938,10 +1950,10 @@ static const struct intel_dpll_mgr skl_pll_mgr = {
1938}; 1950};
1939 1951
1940static const struct dpll_info bxt_plls[] = { 1952static const struct dpll_info bxt_plls[] = {
1941 { "PORT PLL A", DPLL_ID_SKL_DPLL0, &bxt_ddi_pll_funcs, 0 }, 1953 { "PORT PLL A", &bxt_ddi_pll_funcs, DPLL_ID_SKL_DPLL0, 0 },
1942 { "PORT PLL B", DPLL_ID_SKL_DPLL1, &bxt_ddi_pll_funcs, 0 }, 1954 { "PORT PLL B", &bxt_ddi_pll_funcs, DPLL_ID_SKL_DPLL1, 0 },
1943 { "PORT PLL C", DPLL_ID_SKL_DPLL2, &bxt_ddi_pll_funcs, 0 }, 1955 { "PORT PLL C", &bxt_ddi_pll_funcs, DPLL_ID_SKL_DPLL2, 0 },
1944 { NULL, -1, NULL, }, 1956 { },
1945}; 1957};
1946 1958
1947static const struct intel_dpll_mgr bxt_pll_mgr = { 1959static const struct intel_dpll_mgr bxt_pll_mgr = {
@@ -1953,38 +1965,39 @@ static const struct intel_dpll_mgr bxt_pll_mgr = {
1953static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv, 1965static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
1954 struct intel_shared_dpll *pll) 1966 struct intel_shared_dpll *pll)
1955{ 1967{
1968 const enum intel_dpll_id id = pll->info->id;
1956 uint32_t val; 1969 uint32_t val;
1957 1970
1958 /* 1. Enable DPLL power in DPLL_ENABLE. */ 1971 /* 1. Enable DPLL power in DPLL_ENABLE. */
1959 val = I915_READ(CNL_DPLL_ENABLE(pll->id)); 1972 val = I915_READ(CNL_DPLL_ENABLE(id));
1960 val |= PLL_POWER_ENABLE; 1973 val |= PLL_POWER_ENABLE;
1961 I915_WRITE(CNL_DPLL_ENABLE(pll->id), val); 1974 I915_WRITE(CNL_DPLL_ENABLE(id), val);
1962 1975
1963 /* 2. Wait for DPLL power state enabled in DPLL_ENABLE. */ 1976 /* 2. Wait for DPLL power state enabled in DPLL_ENABLE. */
1964 if (intel_wait_for_register(dev_priv, 1977 if (intel_wait_for_register(dev_priv,
1965 CNL_DPLL_ENABLE(pll->id), 1978 CNL_DPLL_ENABLE(id),
1966 PLL_POWER_STATE, 1979 PLL_POWER_STATE,
1967 PLL_POWER_STATE, 1980 PLL_POWER_STATE,
1968 5)) 1981 5))
1969 DRM_ERROR("PLL %d Power not enabled\n", pll->id); 1982 DRM_ERROR("PLL %d Power not enabled\n", id);
1970 1983
1971 /* 1984 /*
1972 * 3. Configure DPLL_CFGCR0 to set SSC enable/disable, 1985 * 3. Configure DPLL_CFGCR0 to set SSC enable/disable,
1973 * select DP mode, and set DP link rate. 1986 * select DP mode, and set DP link rate.
1974 */ 1987 */
1975 val = pll->state.hw_state.cfgcr0; 1988 val = pll->state.hw_state.cfgcr0;
1976 I915_WRITE(CNL_DPLL_CFGCR0(pll->id), val); 1989 I915_WRITE(CNL_DPLL_CFGCR0(id), val);
1977 1990
1978 /* 4. Reab back to ensure writes completed */ 1991 /* 4. Reab back to ensure writes completed */
1979 POSTING_READ(CNL_DPLL_CFGCR0(pll->id)); 1992 POSTING_READ(CNL_DPLL_CFGCR0(id));
1980 1993
1981 /* 3. Configure DPLL_CFGCR0 */ 1994 /* 3. Configure DPLL_CFGCR0 */
1982 /* Avoid touch CFGCR1 if HDMI mode is not enabled */ 1995 /* Avoid touch CFGCR1 if HDMI mode is not enabled */
1983 if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) { 1996 if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
1984 val = pll->state.hw_state.cfgcr1; 1997 val = pll->state.hw_state.cfgcr1;
1985 I915_WRITE(CNL_DPLL_CFGCR1(pll->id), val); 1998 I915_WRITE(CNL_DPLL_CFGCR1(id), val);
1986 /* 4. Reab back to ensure writes completed */ 1999 /* 4. Reab back to ensure writes completed */
1987 POSTING_READ(CNL_DPLL_CFGCR1(pll->id)); 2000 POSTING_READ(CNL_DPLL_CFGCR1(id));
1988 } 2001 }
1989 2002
1990 /* 2003 /*
@@ -1997,17 +2010,17 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
1997 */ 2010 */
1998 2011
1999 /* 6. Enable DPLL in DPLL_ENABLE. */ 2012 /* 6. Enable DPLL in DPLL_ENABLE. */
2000 val = I915_READ(CNL_DPLL_ENABLE(pll->id)); 2013 val = I915_READ(CNL_DPLL_ENABLE(id));
2001 val |= PLL_ENABLE; 2014 val |= PLL_ENABLE;
2002 I915_WRITE(CNL_DPLL_ENABLE(pll->id), val); 2015 I915_WRITE(CNL_DPLL_ENABLE(id), val);
2003 2016
2004 /* 7. Wait for PLL lock status in DPLL_ENABLE. */ 2017 /* 7. Wait for PLL lock status in DPLL_ENABLE. */
2005 if (intel_wait_for_register(dev_priv, 2018 if (intel_wait_for_register(dev_priv,
2006 CNL_DPLL_ENABLE(pll->id), 2019 CNL_DPLL_ENABLE(id),
2007 PLL_LOCK, 2020 PLL_LOCK,
2008 PLL_LOCK, 2021 PLL_LOCK,
2009 5)) 2022 5))
2010 DRM_ERROR("PLL %d not locked\n", pll->id); 2023 DRM_ERROR("PLL %d not locked\n", id);
2011 2024
2012 /* 2025 /*
2013 * 8. If the frequency will result in a change to the voltage 2026 * 8. If the frequency will result in a change to the voltage
@@ -2027,6 +2040,7 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2027static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv, 2040static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2028 struct intel_shared_dpll *pll) 2041 struct intel_shared_dpll *pll)
2029{ 2042{
2043 const enum intel_dpll_id id = pll->info->id;
2030 uint32_t val; 2044 uint32_t val;
2031 2045
2032 /* 2046 /*
@@ -2044,17 +2058,17 @@ static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2044 */ 2058 */
2045 2059
2046 /* 3. Disable DPLL through DPLL_ENABLE. */ 2060 /* 3. Disable DPLL through DPLL_ENABLE. */
2047 val = I915_READ(CNL_DPLL_ENABLE(pll->id)); 2061 val = I915_READ(CNL_DPLL_ENABLE(id));
2048 val &= ~PLL_ENABLE; 2062 val &= ~PLL_ENABLE;
2049 I915_WRITE(CNL_DPLL_ENABLE(pll->id), val); 2063 I915_WRITE(CNL_DPLL_ENABLE(id), val);
2050 2064
2051 /* 4. Wait for PLL not locked status in DPLL_ENABLE. */ 2065 /* 4. Wait for PLL not locked status in DPLL_ENABLE. */
2052 if (intel_wait_for_register(dev_priv, 2066 if (intel_wait_for_register(dev_priv,
2053 CNL_DPLL_ENABLE(pll->id), 2067 CNL_DPLL_ENABLE(id),
2054 PLL_LOCK, 2068 PLL_LOCK,
2055 0, 2069 0,
2056 5)) 2070 5))
2057 DRM_ERROR("PLL %d locked\n", pll->id); 2071 DRM_ERROR("PLL %d locked\n", id);
2058 2072
2059 /* 2073 /*
2060 * 5. If the frequency will result in a change to the voltage 2074 * 5. If the frequency will result in a change to the voltage
@@ -2066,23 +2080,24 @@ static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2066 */ 2080 */
2067 2081
2068 /* 6. Disable DPLL power in DPLL_ENABLE. */ 2082 /* 6. Disable DPLL power in DPLL_ENABLE. */
2069 val = I915_READ(CNL_DPLL_ENABLE(pll->id)); 2083 val = I915_READ(CNL_DPLL_ENABLE(id));
2070 val &= ~PLL_POWER_ENABLE; 2084 val &= ~PLL_POWER_ENABLE;
2071 I915_WRITE(CNL_DPLL_ENABLE(pll->id), val); 2085 I915_WRITE(CNL_DPLL_ENABLE(id), val);
2072 2086
2073 /* 7. Wait for DPLL power state disabled in DPLL_ENABLE. */ 2087 /* 7. Wait for DPLL power state disabled in DPLL_ENABLE. */
2074 if (intel_wait_for_register(dev_priv, 2088 if (intel_wait_for_register(dev_priv,
2075 CNL_DPLL_ENABLE(pll->id), 2089 CNL_DPLL_ENABLE(id),
2076 PLL_POWER_STATE, 2090 PLL_POWER_STATE,
2077 0, 2091 0,
2078 5)) 2092 5))
2079 DRM_ERROR("PLL %d Power not disabled\n", pll->id); 2093 DRM_ERROR("PLL %d Power not disabled\n", id);
2080} 2094}
2081 2095
2082static bool cnl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, 2096static bool cnl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2083 struct intel_shared_dpll *pll, 2097 struct intel_shared_dpll *pll,
2084 struct intel_dpll_hw_state *hw_state) 2098 struct intel_dpll_hw_state *hw_state)
2085{ 2099{
2100 const enum intel_dpll_id id = pll->info->id;
2086 uint32_t val; 2101 uint32_t val;
2087 bool ret; 2102 bool ret;
2088 2103
@@ -2091,16 +2106,16 @@ static bool cnl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2091 2106
2092 ret = false; 2107 ret = false;
2093 2108
2094 val = I915_READ(CNL_DPLL_ENABLE(pll->id)); 2109 val = I915_READ(CNL_DPLL_ENABLE(id));
2095 if (!(val & PLL_ENABLE)) 2110 if (!(val & PLL_ENABLE))
2096 goto out; 2111 goto out;
2097 2112
2098 val = I915_READ(CNL_DPLL_CFGCR0(pll->id)); 2113 val = I915_READ(CNL_DPLL_CFGCR0(id));
2099 hw_state->cfgcr0 = val; 2114 hw_state->cfgcr0 = val;
2100 2115
2101 /* avoid reading back stale values if HDMI mode is not enabled */ 2116 /* avoid reading back stale values if HDMI mode is not enabled */
2102 if (val & DPLL_CFGCR0_HDMI_MODE) { 2117 if (val & DPLL_CFGCR0_HDMI_MODE) {
2103 hw_state->cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll->id)); 2118 hw_state->cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(id));
2104 } 2119 }
2105 ret = true; 2120 ret = true;
2106 2121
@@ -2203,6 +2218,7 @@ cnl_ddi_calculate_wrpll(int clock,
2203 struct skl_wrpll_params *wrpll_params) 2218 struct skl_wrpll_params *wrpll_params)
2204{ 2219{
2205 u32 afe_clock = clock * 5; 2220 u32 afe_clock = clock * 5;
2221 uint32_t ref_clock;
2206 u32 dco_min = 7998000; 2222 u32 dco_min = 7998000;
2207 u32 dco_max = 10000000; 2223 u32 dco_max = 10000000;
2208 u32 dco_mid = (dco_min + dco_max) / 2; 2224 u32 dco_mid = (dco_min + dco_max) / 2;
@@ -2235,8 +2251,17 @@ cnl_ddi_calculate_wrpll(int clock,
2235 2251
2236 cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv); 2252 cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
2237 2253
2238 cnl_wrpll_params_populate(wrpll_params, best_dco, 2254 ref_clock = dev_priv->cdclk.hw.ref;
2239 dev_priv->cdclk.hw.ref, pdiv, qdiv, kdiv); 2255
2256 /*
2257 * For ICL, the spec states: if reference frequency is 38.4, use 19.2
2258 * because the DPLL automatically divides that by 2.
2259 */
2260 if (IS_ICELAKE(dev_priv) && ref_clock == 38400)
2261 ref_clock = 19200;
2262
2263 cnl_wrpll_params_populate(wrpll_params, best_dco, ref_clock, pdiv, qdiv,
2264 kdiv);
2240 2265
2241 return true; 2266 return true;
2242} 2267}
@@ -2372,10 +2397,10 @@ static const struct intel_shared_dpll_funcs cnl_ddi_pll_funcs = {
2372}; 2397};
2373 2398
2374static const struct dpll_info cnl_plls[] = { 2399static const struct dpll_info cnl_plls[] = {
2375 { "DPLL 0", DPLL_ID_SKL_DPLL0, &cnl_ddi_pll_funcs, 0 }, 2400 { "DPLL 0", &cnl_ddi_pll_funcs, DPLL_ID_SKL_DPLL0, 0 },
2376 { "DPLL 1", DPLL_ID_SKL_DPLL1, &cnl_ddi_pll_funcs, 0 }, 2401 { "DPLL 1", &cnl_ddi_pll_funcs, DPLL_ID_SKL_DPLL1, 0 },
2377 { "DPLL 2", DPLL_ID_SKL_DPLL2, &cnl_ddi_pll_funcs, 0 }, 2402 { "DPLL 2", &cnl_ddi_pll_funcs, DPLL_ID_SKL_DPLL2, 0 },
2378 { NULL, -1, NULL, }, 2403 { },
2379}; 2404};
2380 2405
2381static const struct intel_dpll_mgr cnl_pll_mgr = { 2406static const struct intel_dpll_mgr cnl_pll_mgr = {
@@ -2384,6 +2409,644 @@ static const struct intel_dpll_mgr cnl_pll_mgr = {
2384 .dump_hw_state = cnl_dump_hw_state, 2409 .dump_hw_state = cnl_dump_hw_state,
2385}; 2410};
2386 2411
2412/*
2413 * These values alrea already adjusted: they're the bits we write to the
2414 * registers, not the logical values.
2415 */
2416static const struct skl_wrpll_params icl_dp_combo_pll_24MHz_values[] = {
2417 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [0]: 5.4 */
2418 .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
2419 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [1]: 2.7 */
2420 .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
2421 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [2]: 1.62 */
2422 .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
2423 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [3]: 3.24 */
2424 .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
2425 { .dco_integer = 0x168, .dco_fraction = 0x0000, /* [4]: 2.16 */
2426 .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2},
2427 { .dco_integer = 0x168, .dco_fraction = 0x0000, /* [5]: 4.32 */
2428 .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
2429 { .dco_integer = 0x195, .dco_fraction = 0x0000, /* [6]: 6.48 */
2430 .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
2431 { .dco_integer = 0x151, .dco_fraction = 0x4000, /* [7]: 8.1 */
2432 .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
2433};
2434
2435/* Also used for 38.4 MHz values. */
2436static const struct skl_wrpll_params icl_dp_combo_pll_19_2MHz_values[] = {
2437 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [0]: 5.4 */
2438 .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
2439 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [1]: 2.7 */
2440 .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
2441 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [2]: 1.62 */
2442 .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
2443 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [3]: 3.24 */
2444 .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
2445 { .dco_integer = 0x1C2, .dco_fraction = 0x0000, /* [4]: 2.16 */
2446 .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2},
2447 { .dco_integer = 0x1C2, .dco_fraction = 0x0000, /* [5]: 4.32 */
2448 .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
2449 { .dco_integer = 0x1FA, .dco_fraction = 0x2000, /* [6]: 6.48 */
2450 .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
2451 { .dco_integer = 0x1A5, .dco_fraction = 0x7000, /* [7]: 8.1 */
2452 .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
2453};
2454
2455static bool icl_calc_dp_combo_pll(struct drm_i915_private *dev_priv, int clock,
2456 struct skl_wrpll_params *pll_params)
2457{
2458 const struct skl_wrpll_params *params;
2459
2460 params = dev_priv->cdclk.hw.ref == 24000 ?
2461 icl_dp_combo_pll_24MHz_values :
2462 icl_dp_combo_pll_19_2MHz_values;
2463
2464 switch (clock) {
2465 case 540000:
2466 *pll_params = params[0];
2467 break;
2468 case 270000:
2469 *pll_params = params[1];
2470 break;
2471 case 162000:
2472 *pll_params = params[2];
2473 break;
2474 case 324000:
2475 *pll_params = params[3];
2476 break;
2477 case 216000:
2478 *pll_params = params[4];
2479 break;
2480 case 432000:
2481 *pll_params = params[5];
2482 break;
2483 case 648000:
2484 *pll_params = params[6];
2485 break;
2486 case 810000:
2487 *pll_params = params[7];
2488 break;
2489 default:
2490 MISSING_CASE(clock);
2491 return false;
2492 }
2493
2494 return true;
2495}
2496
2497static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
2498 struct intel_encoder *encoder, int clock,
2499 struct intel_dpll_hw_state *pll_state)
2500{
2501 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2502 uint32_t cfgcr0, cfgcr1;
2503 struct skl_wrpll_params pll_params = { 0 };
2504 bool ret;
2505
2506 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
2507 ret = cnl_ddi_calculate_wrpll(clock, dev_priv, &pll_params);
2508 else
2509 ret = icl_calc_dp_combo_pll(dev_priv, clock, &pll_params);
2510
2511 if (!ret)
2512 return false;
2513
2514 cfgcr0 = DPLL_CFGCR0_DCO_FRACTION(pll_params.dco_fraction) |
2515 pll_params.dco_integer;
2516
2517 cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(pll_params.qdiv_ratio) |
2518 DPLL_CFGCR1_QDIV_MODE(pll_params.qdiv_mode) |
2519 DPLL_CFGCR1_KDIV(pll_params.kdiv) |
2520 DPLL_CFGCR1_PDIV(pll_params.pdiv) |
2521 DPLL_CFGCR1_CENTRAL_FREQ_8400;
2522
2523 pll_state->cfgcr0 = cfgcr0;
2524 pll_state->cfgcr1 = cfgcr1;
2525 return true;
2526}
2527
2528static enum port icl_mg_pll_id_to_port(enum intel_dpll_id id)
2529{
2530 return id - DPLL_ID_ICL_MGPLL1 + PORT_C;
2531}
2532
2533static enum intel_dpll_id icl_port_to_mg_pll_id(enum port port)
2534{
2535 return port - PORT_C + DPLL_ID_ICL_MGPLL1;
2536}
2537
2538static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
2539 uint32_t *target_dco_khz,
2540 struct intel_dpll_hw_state *state)
2541{
2542 uint32_t dco_min_freq, dco_max_freq;
2543 int div1_vals[] = {7, 5, 3, 2};
2544 unsigned int i;
2545 int div2;
2546
2547 dco_min_freq = is_dp ? 8100000 : use_ssc ? 8000000 : 7992000;
2548 dco_max_freq = is_dp ? 8100000 : 10000000;
2549
2550 for (i = 0; i < ARRAY_SIZE(div1_vals); i++) {
2551 int div1 = div1_vals[i];
2552
2553 for (div2 = 10; div2 > 0; div2--) {
2554 int dco = div1 * div2 * clock_khz * 5;
2555 int a_divratio, tlinedrv, inputsel, hsdiv;
2556
2557 if (dco < dco_min_freq || dco > dco_max_freq)
2558 continue;
2559
2560 if (div2 >= 2) {
2561 a_divratio = is_dp ? 10 : 5;
2562 tlinedrv = 2;
2563 } else {
2564 a_divratio = 5;
2565 tlinedrv = 0;
2566 }
2567 inputsel = is_dp ? 0 : 1;
2568
2569 switch (div1) {
2570 default:
2571 MISSING_CASE(div1);
2572 case 2:
2573 hsdiv = 0;
2574 break;
2575 case 3:
2576 hsdiv = 1;
2577 break;
2578 case 5:
2579 hsdiv = 2;
2580 break;
2581 case 7:
2582 hsdiv = 3;
2583 break;
2584 }
2585
2586 *target_dco_khz = dco;
2587
2588 state->mg_refclkin_ctl = MG_REFCLKIN_CTL_OD_2_MUX(1);
2589
2590 state->mg_clktop2_coreclkctl1 =
2591 MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(a_divratio);
2592
2593 state->mg_clktop2_hsclkctl =
2594 MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(tlinedrv) |
2595 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(inputsel) |
2596 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(hsdiv) |
2597 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(div2);
2598
2599 return true;
2600 }
2601 }
2602
2603 return false;
2604}
2605
2606/*
2607 * The specification for this function uses real numbers, so the math had to be
2608 * adapted to integer-only calculation, that's why it looks so different.
2609 */
2610static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
2611 struct intel_encoder *encoder, int clock,
2612 struct intel_dpll_hw_state *pll_state)
2613{
2614 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2615 int refclk_khz = dev_priv->cdclk.hw.ref;
2616 uint32_t dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;
2617 uint32_t iref_ndiv, iref_trim, iref_pulse_w;
2618 uint32_t prop_coeff, int_coeff;
2619 uint32_t tdc_targetcnt, feedfwgain;
2620 uint64_t ssc_stepsize, ssc_steplen, ssc_steplog;
2621 uint64_t tmp;
2622 bool use_ssc = false;
2623 bool is_dp = !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI);
2624
2625 if (!icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz,
2626 pll_state)) {
2627 DRM_DEBUG_KMS("Failed to find divisors for clock %d\n", clock);
2628 return false;
2629 }
2630
2631 m1div = 2;
2632 m2div_int = dco_khz / (refclk_khz * m1div);
2633 if (m2div_int > 255) {
2634 m1div = 4;
2635 m2div_int = dco_khz / (refclk_khz * m1div);
2636 if (m2div_int > 255) {
2637 DRM_DEBUG_KMS("Failed to find mdiv for clock %d\n",
2638 clock);
2639 return false;
2640 }
2641 }
2642 m2div_rem = dco_khz % (refclk_khz * m1div);
2643
2644 tmp = (uint64_t)m2div_rem * (1 << 22);
2645 do_div(tmp, refclk_khz * m1div);
2646 m2div_frac = tmp;
2647
2648 switch (refclk_khz) {
2649 case 19200:
2650 iref_ndiv = 1;
2651 iref_trim = 28;
2652 iref_pulse_w = 1;
2653 break;
2654 case 24000:
2655 iref_ndiv = 1;
2656 iref_trim = 25;
2657 iref_pulse_w = 2;
2658 break;
2659 case 38400:
2660 iref_ndiv = 2;
2661 iref_trim = 28;
2662 iref_pulse_w = 1;
2663 break;
2664 default:
2665 MISSING_CASE(refclk_khz);
2666 return false;
2667 }
2668
2669 /*
2670 * tdc_res = 0.000003
2671 * tdc_targetcnt = int(2 / (tdc_res * 8 * 50 * 1.1) / refclk_mhz + 0.5)
2672 *
2673 * The multiplication by 1000 is due to refclk MHz to KHz conversion. It
2674 * was supposed to be a division, but we rearranged the operations of
2675 * the formula to avoid early divisions so we don't multiply the
2676 * rounding errors.
2677 *
2678 * 0.000003 * 8 * 50 * 1.1 = 0.00132, also known as 132 / 100000, which
2679 * we also rearrange to work with integers.
2680 *
2681 * The 0.5 transformed to 5 results in a multiplication by 10 and the
2682 * last division by 10.
2683 */
2684 tdc_targetcnt = (2 * 1000 * 100000 * 10 / (132 * refclk_khz) + 5) / 10;
2685
2686 /*
2687 * Here we divide dco_khz by 10 in order to allow the dividend to fit in
2688 * 32 bits. That's not a problem since we round the division down
2689 * anyway.
2690 */
2691 feedfwgain = (use_ssc || m2div_rem > 0) ?
2692 m1div * 1000000 * 100 / (dco_khz * 3 / 10) : 0;
2693
2694 if (dco_khz >= 9000000) {
2695 prop_coeff = 5;
2696 int_coeff = 10;
2697 } else {
2698 prop_coeff = 4;
2699 int_coeff = 8;
2700 }
2701
2702 if (use_ssc) {
2703 tmp = (uint64_t)dco_khz * 47 * 32;
2704 do_div(tmp, refclk_khz * m1div * 10000);
2705 ssc_stepsize = tmp;
2706
2707 tmp = (uint64_t)dco_khz * 1000;
2708 ssc_steplen = DIV_ROUND_UP_ULL(tmp, 32 * 2 * 32);
2709 } else {
2710 ssc_stepsize = 0;
2711 ssc_steplen = 0;
2712 }
2713 ssc_steplog = 4;
2714
2715 pll_state->mg_pll_div0 = (m2div_rem > 0 ? MG_PLL_DIV0_FRACNEN_H : 0) |
2716 MG_PLL_DIV0_FBDIV_FRAC(m2div_frac) |
2717 MG_PLL_DIV0_FBDIV_INT(m2div_int);
2718
2719 pll_state->mg_pll_div1 = MG_PLL_DIV1_IREF_NDIVRATIO(iref_ndiv) |
2720 MG_PLL_DIV1_DITHER_DIV_2 |
2721 MG_PLL_DIV1_NDIVRATIO(1) |
2722 MG_PLL_DIV1_FBPREDIV(m1div);
2723
2724 pll_state->mg_pll_lf = MG_PLL_LF_TDCTARGETCNT(tdc_targetcnt) |
2725 MG_PLL_LF_AFCCNTSEL_512 |
2726 MG_PLL_LF_GAINCTRL(1) |
2727 MG_PLL_LF_INT_COEFF(int_coeff) |
2728 MG_PLL_LF_PROP_COEFF(prop_coeff);
2729
2730 pll_state->mg_pll_frac_lock = MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32 |
2731 MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32 |
2732 MG_PLL_FRAC_LOCK_LOCKTHRESH(10) |
2733 MG_PLL_FRAC_LOCK_DCODITHEREN |
2734 MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(feedfwgain);
2735 if (use_ssc || m2div_rem > 0)
2736 pll_state->mg_pll_frac_lock |= MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN;
2737
2738 pll_state->mg_pll_ssc = (use_ssc ? MG_PLL_SSC_EN : 0) |
2739 MG_PLL_SSC_TYPE(2) |
2740 MG_PLL_SSC_STEPLENGTH(ssc_steplen) |
2741 MG_PLL_SSC_STEPNUM(ssc_steplog) |
2742 MG_PLL_SSC_FLLEN |
2743 MG_PLL_SSC_STEPSIZE(ssc_stepsize);
2744
2745 pll_state->mg_pll_tdc_coldst_bias = MG_PLL_TDC_COLDST_COLDSTART;
2746
2747 if (refclk_khz != 38400) {
2748 pll_state->mg_pll_tdc_coldst_bias |=
2749 MG_PLL_TDC_COLDST_IREFINT_EN |
2750 MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) |
2751 MG_PLL_TDC_COLDST_COLDSTART |
2752 MG_PLL_TDC_TDCOVCCORR_EN |
2753 MG_PLL_TDC_TDCSEL(3);
2754
2755 pll_state->mg_pll_bias = MG_PLL_BIAS_BIAS_GB_SEL(3) |
2756 MG_PLL_BIAS_INIT_DCOAMP(0x3F) |
2757 MG_PLL_BIAS_BIAS_BONUS(10) |
2758 MG_PLL_BIAS_BIASCAL_EN |
2759 MG_PLL_BIAS_CTRIM(12) |
2760 MG_PLL_BIAS_VREF_RDAC(4) |
2761 MG_PLL_BIAS_IREFTRIM(iref_trim);
2762 }
2763
2764 return true;
2765}
2766
2767static struct intel_shared_dpll *
2768icl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
2769 struct intel_encoder *encoder)
2770{
2771 struct intel_shared_dpll *pll;
2772 struct intel_dpll_hw_state pll_state = {};
2773 enum port port = encoder->port;
2774 enum intel_dpll_id min, max;
2775 int clock = crtc_state->port_clock;
2776 bool ret;
2777
2778 switch (port) {
2779 case PORT_A:
2780 case PORT_B:
2781 min = DPLL_ID_ICL_DPLL0;
2782 max = DPLL_ID_ICL_DPLL1;
2783 ret = icl_calc_dpll_state(crtc_state, encoder, clock,
2784 &pll_state);
2785 break;
2786 case PORT_C:
2787 case PORT_D:
2788 case PORT_E:
2789 case PORT_F:
2790 min = icl_port_to_mg_pll_id(port);
2791 max = min;
2792 ret = icl_calc_mg_pll_state(crtc_state, encoder, clock,
2793 &pll_state);
2794 break;
2795 default:
2796 MISSING_CASE(port);
2797 return NULL;
2798 }
2799
2800 if (!ret) {
2801 DRM_DEBUG_KMS("Could not calculate PLL state.\n");
2802 return NULL;
2803 }
2804
2805 crtc_state->dpll_hw_state = pll_state;
2806
2807 pll = intel_find_shared_dpll(crtc, crtc_state, min, max);
2808 if (!pll) {
2809 DRM_DEBUG_KMS("No PLL selected\n");
2810 return NULL;
2811 }
2812
2813 intel_reference_shared_dpll(pll, crtc_state);
2814
2815 return pll;
2816}
2817
2818static i915_reg_t icl_pll_id_to_enable_reg(enum intel_dpll_id id)
2819{
2820 switch (id) {
2821 default:
2822 MISSING_CASE(id);
2823 case DPLL_ID_ICL_DPLL0:
2824 case DPLL_ID_ICL_DPLL1:
2825 return CNL_DPLL_ENABLE(id);
2826 case DPLL_ID_ICL_MGPLL1:
2827 case DPLL_ID_ICL_MGPLL2:
2828 case DPLL_ID_ICL_MGPLL3:
2829 case DPLL_ID_ICL_MGPLL4:
2830 return MG_PLL_ENABLE(icl_mg_pll_id_to_port(id));
2831 }
2832}
2833
2834static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
2835 struct intel_shared_dpll *pll,
2836 struct intel_dpll_hw_state *hw_state)
2837{
2838 const enum intel_dpll_id id = pll->info->id;
2839 uint32_t val;
2840 enum port port;
2841 bool ret = false;
2842
2843 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
2844 return false;
2845
2846 val = I915_READ(icl_pll_id_to_enable_reg(id));
2847 if (!(val & PLL_ENABLE))
2848 goto out;
2849
2850 switch (id) {
2851 case DPLL_ID_ICL_DPLL0:
2852 case DPLL_ID_ICL_DPLL1:
2853 hw_state->cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(id));
2854 hw_state->cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(id));
2855 break;
2856 case DPLL_ID_ICL_MGPLL1:
2857 case DPLL_ID_ICL_MGPLL2:
2858 case DPLL_ID_ICL_MGPLL3:
2859 case DPLL_ID_ICL_MGPLL4:
2860 port = icl_mg_pll_id_to_port(id);
2861 hw_state->mg_refclkin_ctl = I915_READ(MG_REFCLKIN_CTL(port));
2862 hw_state->mg_clktop2_coreclkctl1 =
2863 I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
2864 hw_state->mg_clktop2_hsclkctl =
2865 I915_READ(MG_CLKTOP2_HSCLKCTL(port));
2866 hw_state->mg_pll_div0 = I915_READ(MG_PLL_DIV0(port));
2867 hw_state->mg_pll_div1 = I915_READ(MG_PLL_DIV1(port));
2868 hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port));
2869 hw_state->mg_pll_frac_lock = I915_READ(MG_PLL_FRAC_LOCK(port));
2870 hw_state->mg_pll_ssc = I915_READ(MG_PLL_SSC(port));
2871 hw_state->mg_pll_bias = I915_READ(MG_PLL_BIAS(port));
2872 hw_state->mg_pll_tdc_coldst_bias =
2873 I915_READ(MG_PLL_TDC_COLDST_BIAS(port));
2874 break;
2875 default:
2876 MISSING_CASE(id);
2877 }
2878
2879 ret = true;
2880out:
2881 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
2882 return ret;
2883}
2884
2885static void icl_dpll_write(struct drm_i915_private *dev_priv,
2886 struct intel_shared_dpll *pll)
2887{
2888 struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
2889 const enum intel_dpll_id id = pll->info->id;
2890
2891 I915_WRITE(ICL_DPLL_CFGCR0(id), hw_state->cfgcr0);
2892 I915_WRITE(ICL_DPLL_CFGCR1(id), hw_state->cfgcr1);
2893 POSTING_READ(ICL_DPLL_CFGCR1(id));
2894}
2895
2896static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
2897 struct intel_shared_dpll *pll)
2898{
2899 struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
2900 enum port port = icl_mg_pll_id_to_port(pll->info->id);
2901
2902 I915_WRITE(MG_REFCLKIN_CTL(port), hw_state->mg_refclkin_ctl);
2903 I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port),
2904 hw_state->mg_clktop2_coreclkctl1);
2905 I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), hw_state->mg_clktop2_hsclkctl);
2906 I915_WRITE(MG_PLL_DIV0(port), hw_state->mg_pll_div0);
2907 I915_WRITE(MG_PLL_DIV1(port), hw_state->mg_pll_div1);
2908 I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf);
2909 I915_WRITE(MG_PLL_FRAC_LOCK(port), hw_state->mg_pll_frac_lock);
2910 I915_WRITE(MG_PLL_SSC(port), hw_state->mg_pll_ssc);
2911 I915_WRITE(MG_PLL_BIAS(port), hw_state->mg_pll_bias);
2912 I915_WRITE(MG_PLL_TDC_COLDST_BIAS(port),
2913 hw_state->mg_pll_tdc_coldst_bias);
2914 POSTING_READ(MG_PLL_TDC_COLDST_BIAS(port));
2915}
2916
2917static void icl_pll_enable(struct drm_i915_private *dev_priv,
2918 struct intel_shared_dpll *pll)
2919{
2920 const enum intel_dpll_id id = pll->info->id;
2921 i915_reg_t enable_reg = icl_pll_id_to_enable_reg(id);
2922 uint32_t val;
2923
2924 val = I915_READ(enable_reg);
2925 val |= PLL_POWER_ENABLE;
2926 I915_WRITE(enable_reg, val);
2927
2928 /*
2929 * The spec says we need to "wait" but it also says it should be
2930 * immediate.
2931 */
2932 if (intel_wait_for_register(dev_priv, enable_reg, PLL_POWER_STATE,
2933 PLL_POWER_STATE, 1))
2934 DRM_ERROR("PLL %d Power not enabled\n", id);
2935
2936 switch (id) {
2937 case DPLL_ID_ICL_DPLL0:
2938 case DPLL_ID_ICL_DPLL1:
2939 icl_dpll_write(dev_priv, pll);
2940 break;
2941 case DPLL_ID_ICL_MGPLL1:
2942 case DPLL_ID_ICL_MGPLL2:
2943 case DPLL_ID_ICL_MGPLL3:
2944 case DPLL_ID_ICL_MGPLL4:
2945 icl_mg_pll_write(dev_priv, pll);
2946 break;
2947 default:
2948 MISSING_CASE(id);
2949 }
2950
2951 /*
2952 * DVFS pre sequence would be here, but in our driver the cdclk code
2953 * paths should already be setting the appropriate voltage, hence we do
2954 * nothign here.
2955 */
2956
2957 val = I915_READ(enable_reg);
2958 val |= PLL_ENABLE;
2959 I915_WRITE(enable_reg, val);
2960
2961 if (intel_wait_for_register(dev_priv, enable_reg, PLL_LOCK, PLL_LOCK,
2962 1)) /* 600us actually. */
2963 DRM_ERROR("PLL %d not locked\n", id);
2964
2965 /* DVFS post sequence would be here. See the comment above. */
2966}
2967
2968static void icl_pll_disable(struct drm_i915_private *dev_priv,
2969 struct intel_shared_dpll *pll)
2970{
2971 const enum intel_dpll_id id = pll->info->id;
2972 i915_reg_t enable_reg = icl_pll_id_to_enable_reg(id);
2973 uint32_t val;
2974
2975 /* The first steps are done by intel_ddi_post_disable(). */
2976
2977 /*
2978 * DVFS pre sequence would be here, but in our driver the cdclk code
2979 * paths should already be setting the appropriate voltage, hence we do
2980 * nothign here.
2981 */
2982
2983 val = I915_READ(enable_reg);
2984 val &= ~PLL_ENABLE;
2985 I915_WRITE(enable_reg, val);
2986
2987 /* Timeout is actually 1us. */
2988 if (intel_wait_for_register(dev_priv, enable_reg, PLL_LOCK, 0, 1))
2989 DRM_ERROR("PLL %d locked\n", id);
2990
2991 /* DVFS post sequence would be here. See the comment above. */
2992
2993 val = I915_READ(enable_reg);
2994 val &= ~PLL_POWER_ENABLE;
2995 I915_WRITE(enable_reg, val);
2996
2997 /*
2998 * The spec says we need to "wait" but it also says it should be
2999 * immediate.
3000 */
3001 if (intel_wait_for_register(dev_priv, enable_reg, PLL_POWER_STATE, 0,
3002 1))
3003 DRM_ERROR("PLL %d Power not disabled\n", id);
3004}
3005
3006static void icl_dump_hw_state(struct drm_i915_private *dev_priv,
3007 struct intel_dpll_hw_state *hw_state)
3008{
3009 DRM_DEBUG_KMS("dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, "
3010 "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
3011 "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
3012 "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
3013 "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
3014 "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",
3015 hw_state->cfgcr0, hw_state->cfgcr1,
3016 hw_state->mg_refclkin_ctl,
3017 hw_state->mg_clktop2_coreclkctl1,
3018 hw_state->mg_clktop2_hsclkctl,
3019 hw_state->mg_pll_div0,
3020 hw_state->mg_pll_div1,
3021 hw_state->mg_pll_lf,
3022 hw_state->mg_pll_frac_lock,
3023 hw_state->mg_pll_ssc,
3024 hw_state->mg_pll_bias,
3025 hw_state->mg_pll_tdc_coldst_bias);
3026}
3027
3028static const struct intel_shared_dpll_funcs icl_pll_funcs = {
3029 .enable = icl_pll_enable,
3030 .disable = icl_pll_disable,
3031 .get_hw_state = icl_pll_get_hw_state,
3032};
3033
3034static const struct dpll_info icl_plls[] = {
3035 { "DPLL 0", &icl_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
3036 { "DPLL 1", &icl_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
3037 { "MG PLL 1", &icl_pll_funcs, DPLL_ID_ICL_MGPLL1, 0 },
3038 { "MG PLL 2", &icl_pll_funcs, DPLL_ID_ICL_MGPLL2, 0 },
3039 { "MG PLL 3", &icl_pll_funcs, DPLL_ID_ICL_MGPLL3, 0 },
3040 { "MG PLL 4", &icl_pll_funcs, DPLL_ID_ICL_MGPLL4, 0 },
3041 { },
3042};
3043
3044static const struct intel_dpll_mgr icl_pll_mgr = {
3045 .dpll_info = icl_plls,
3046 .get_dpll = icl_get_dpll,
3047 .dump_hw_state = icl_dump_hw_state,
3048};
3049
2387/** 3050/**
2388 * intel_shared_dpll_init - Initialize shared DPLLs 3051 * intel_shared_dpll_init - Initialize shared DPLLs
2389 * @dev: drm device 3052 * @dev: drm device
@@ -2397,7 +3060,9 @@ void intel_shared_dpll_init(struct drm_device *dev)
2397 const struct dpll_info *dpll_info; 3060 const struct dpll_info *dpll_info;
2398 int i; 3061 int i;
2399 3062
2400 if (IS_CANNONLAKE(dev_priv)) 3063 if (IS_ICELAKE(dev_priv))
3064 dpll_mgr = &icl_pll_mgr;
3065 else if (IS_CANNONLAKE(dev_priv))
2401 dpll_mgr = &cnl_pll_mgr; 3066 dpll_mgr = &cnl_pll_mgr;
2402 else if (IS_GEN9_BC(dev_priv)) 3067 else if (IS_GEN9_BC(dev_priv))
2403 dpll_mgr = &skl_pll_mgr; 3068 dpll_mgr = &skl_pll_mgr;
@@ -2415,13 +3080,9 @@ void intel_shared_dpll_init(struct drm_device *dev)
2415 3080
2416 dpll_info = dpll_mgr->dpll_info; 3081 dpll_info = dpll_mgr->dpll_info;
2417 3082
2418 for (i = 0; dpll_info[i].id >= 0; i++) { 3083 for (i = 0; dpll_info[i].name; i++) {
2419 WARN_ON(i != dpll_info[i].id); 3084 WARN_ON(i != dpll_info[i].id);
2420 3085 dev_priv->shared_dplls[i].info = &dpll_info[i];
2421 dev_priv->shared_dplls[i].id = dpll_info[i].id;
2422 dev_priv->shared_dplls[i].name = dpll_info[i].name;
2423 dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
2424 dev_priv->shared_dplls[i].flags = dpll_info[i].flags;
2425 } 3086 }
2426 3087
2427 dev_priv->dpll_mgr = dpll_mgr; 3088 dev_priv->dpll_mgr = dpll_mgr;
@@ -2481,7 +3142,7 @@ void intel_release_shared_dpll(struct intel_shared_dpll *dpll,
2481 struct intel_shared_dpll_state *shared_dpll_state; 3142 struct intel_shared_dpll_state *shared_dpll_state;
2482 3143
2483 shared_dpll_state = intel_atomic_get_shared_dpll_state(state); 3144 shared_dpll_state = intel_atomic_get_shared_dpll_state(state);
2484 shared_dpll_state[dpll->id].crtc_mask &= ~(1 << crtc->pipe); 3145 shared_dpll_state[dpll->info->id].crtc_mask &= ~(1 << crtc->pipe);
2485} 3146}
2486 3147
2487/** 3148/**
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index f24ccf443d25..7a0cd564a9ee 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -103,6 +103,32 @@ enum intel_dpll_id {
103 * @DPLL_ID_SKL_DPLL3: SKL and later DPLL3 103 * @DPLL_ID_SKL_DPLL3: SKL and later DPLL3
104 */ 104 */
105 DPLL_ID_SKL_DPLL3 = 3, 105 DPLL_ID_SKL_DPLL3 = 3,
106
107
108 /**
109 * @DPLL_ID_ICL_DPLL0: ICL combo PHY DPLL0
110 */
111 DPLL_ID_ICL_DPLL0 = 0,
112 /**
113 * @DPLL_ID_ICL_DPLL1: ICL combo PHY DPLL1
114 */
115 DPLL_ID_ICL_DPLL1 = 1,
116 /**
117 * @DPLL_ID_ICL_MGPLL1: ICL MG PLL 1 port 1 (C)
118 */
119 DPLL_ID_ICL_MGPLL1 = 2,
120 /**
121 * @DPLL_ID_ICL_MGPLL2: ICL MG PLL 1 port 2 (D)
122 */
123 DPLL_ID_ICL_MGPLL2 = 3,
124 /**
125 * @DPLL_ID_ICL_MGPLL3: ICL MG PLL 1 port 3 (E)
126 */
127 DPLL_ID_ICL_MGPLL3 = 4,
128 /**
129 * @DPLL_ID_ICL_MGPLL4: ICL MG PLL 1 port 4 (F)
130 */
131 DPLL_ID_ICL_MGPLL4 = 5,
106}; 132};
107#define I915_NUM_PLLS 6 133#define I915_NUM_PLLS 6
108 134
@@ -135,6 +161,21 @@ struct intel_dpll_hw_state {
135 /* bxt */ 161 /* bxt */
136 uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10, 162 uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10,
137 pcsdw12; 163 pcsdw12;
164
165 /*
166 * ICL uses the following, already defined:
167 * uint32_t cfgcr0, cfgcr1;
168 */
169 uint32_t mg_refclkin_ctl;
170 uint32_t mg_clktop2_coreclkctl1;
171 uint32_t mg_clktop2_hsclkctl;
172 uint32_t mg_pll_div0;
173 uint32_t mg_pll_div1;
174 uint32_t mg_pll_lf;
175 uint32_t mg_pll_frac_lock;
176 uint32_t mg_pll_ssc;
177 uint32_t mg_pll_bias;
178 uint32_t mg_pll_tdc_coldst_bias;
138}; 179};
139 180
140/** 181/**
@@ -206,6 +247,37 @@ struct intel_shared_dpll_funcs {
206}; 247};
207 248
208/** 249/**
250 * struct dpll_info - display PLL platform specific info
251 */
252struct dpll_info {
253 /**
254 * @name: DPLL name; used for logging
255 */
256 const char *name;
257
258 /**
259 * @funcs: platform specific hooks
260 */
261 const struct intel_shared_dpll_funcs *funcs;
262
263 /**
264 * @id: unique indentifier for this DPLL; should match the index in the
265 * dev_priv->shared_dplls array
266 */
267 enum intel_dpll_id id;
268
269#define INTEL_DPLL_ALWAYS_ON (1 << 0)
270 /**
271 * @flags:
272 *
273 * INTEL_DPLL_ALWAYS_ON
274 * Inform the state checker that the DPLL is kept enabled even if
275 * not in use by any CRTC.
276 */
277 uint32_t flags;
278};
279
280/**
209 * struct intel_shared_dpll - display PLL with tracked state and users 281 * struct intel_shared_dpll - display PLL with tracked state and users
210 */ 282 */
211struct intel_shared_dpll { 283struct intel_shared_dpll {
@@ -228,30 +300,9 @@ struct intel_shared_dpll {
228 bool on; 300 bool on;
229 301
230 /** 302 /**
231 * @name: DPLL name; used for logging 303 * @info: platform specific info
232 */ 304 */
233 const char *name; 305 const struct dpll_info *info;
234
235 /**
236 * @id: unique indentifier for this DPLL; should match the index in the
237 * dev_priv->shared_dplls array
238 */
239 enum intel_dpll_id id;
240
241 /**
242 * @funcs: platform specific hooks
243 */
244 struct intel_shared_dpll_funcs funcs;
245
246#define INTEL_DPLL_ALWAYS_ON (1 << 0)
247 /**
248 * @flags:
249 *
250 * INTEL_DPLL_ALWAYS_ON
251 * Inform the state checker that the DPLL is kept enabled even if
252 * not in use by any CRTC.
253 */
254 uint32_t flags;
255}; 306};
256 307
257#define SKL_DPLL0 0 308#define SKL_DPLL0 0
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a80fbad9be0f..d7dbca1aabff 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -56,6 +56,8 @@
56 for (;;) { \ 56 for (;;) { \
57 const bool expired__ = ktime_after(ktime_get_raw(), end__); \ 57 const bool expired__ = ktime_after(ktime_get_raw(), end__); \
58 OP; \ 58 OP; \
59 /* Guarantee COND check prior to timeout */ \
60 barrier(); \
59 if (COND) { \ 61 if (COND) { \
60 ret__ = 0; \ 62 ret__ = 0; \
61 break; \ 63 break; \
@@ -96,6 +98,8 @@
96 u64 now = local_clock(); \ 98 u64 now = local_clock(); \
97 if (!(ATOMIC)) \ 99 if (!(ATOMIC)) \
98 preempt_enable(); \ 100 preempt_enable(); \
101 /* Guarantee COND check prior to timeout */ \
102 barrier(); \
99 if (COND) { \ 103 if (COND) { \
100 ret = 0; \ 104 ret = 0; \
101 break; \ 105 break; \
@@ -140,6 +144,10 @@
140#define KHz(x) (1000 * (x)) 144#define KHz(x) (1000 * (x))
141#define MHz(x) KHz(1000 * (x)) 145#define MHz(x) KHz(1000 * (x))
142 146
147#define KBps(x) (1000 * (x))
148#define MBps(x) KBps(1000 * (x))
149#define GBps(x) ((u64)1000 * MBps((x)))
150
143/* 151/*
144 * Display related stuff 152 * Display related stuff
145 */ 153 */
@@ -482,7 +490,7 @@ struct intel_atomic_state {
482 bool skip_intermediate_wm; 490 bool skip_intermediate_wm;
483 491
484 /* Gen9+ only */ 492 /* Gen9+ only */
485 struct skl_wm_values wm_results; 493 struct skl_ddb_values wm_results;
486 494
487 struct i915_sw_fence commit_ready; 495 struct i915_sw_fence commit_ready;
488 496
@@ -548,6 +556,12 @@ struct intel_initial_plane_config {
548#define SKL_MAX_DST_W 4096 556#define SKL_MAX_DST_W 4096
549#define SKL_MIN_DST_H 8 557#define SKL_MIN_DST_H 8
550#define SKL_MAX_DST_H 4096 558#define SKL_MAX_DST_H 4096
559#define ICL_MAX_SRC_W 5120
560#define ICL_MAX_SRC_H 4096
561#define ICL_MAX_DST_W 5120
562#define ICL_MAX_DST_H 4096
563#define SKL_MIN_YUV_420_SRC_W 16
564#define SKL_MIN_YUV_420_SRC_H 16
551 565
552struct intel_scaler { 566struct intel_scaler {
553 int in_use; 567 int in_use;
@@ -598,7 +612,9 @@ struct intel_pipe_wm {
598 612
599struct skl_plane_wm { 613struct skl_plane_wm {
600 struct skl_wm_level wm[8]; 614 struct skl_wm_level wm[8];
615 struct skl_wm_level uv_wm[8];
601 struct skl_wm_level trans_wm; 616 struct skl_wm_level trans_wm;
617 bool is_planar;
602}; 618};
603 619
604struct skl_pipe_wm { 620struct skl_pipe_wm {
@@ -874,6 +890,7 @@ struct intel_crtc_state {
874 890
875 /* bitmask of visible planes (enum plane_id) */ 891 /* bitmask of visible planes (enum plane_id) */
876 u8 active_planes; 892 u8 active_planes;
893 u8 nv12_planes;
877 894
878 /* HDMI scrambling status */ 895 /* HDMI scrambling status */
879 bool hdmi_scrambling; 896 bool hdmi_scrambling;
@@ -1321,10 +1338,14 @@ void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv);
1321void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv); 1338void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv);
1322 1339
1323/* i915_irq.c */ 1340/* i915_irq.c */
1341bool gen11_reset_one_iir(struct drm_i915_private * const i915,
1342 const unsigned int bank,
1343 const unsigned int bit);
1324void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); 1344void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
1325void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); 1345void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
1326void gen6_mask_pm_irq(struct drm_i915_private *dev_priv, u32 mask); 1346void gen6_mask_pm_irq(struct drm_i915_private *dev_priv, u32 mask);
1327void gen6_unmask_pm_irq(struct drm_i915_private *dev_priv, u32 mask); 1347void gen6_unmask_pm_irq(struct drm_i915_private *dev_priv, u32 mask);
1348void gen11_reset_rps_interrupts(struct drm_i915_private *dev_priv);
1328void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv); 1349void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv);
1329void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv); 1350void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv);
1330void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv); 1351void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv);
@@ -1389,6 +1410,12 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
1389u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder); 1410u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
1390int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, 1411int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
1391 bool enable); 1412 bool enable);
1413void icl_map_plls_to_ports(struct drm_crtc *crtc,
1414 struct intel_crtc_state *crtc_state,
1415 struct drm_atomic_state *old_state);
1416void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
1417 struct intel_crtc_state *crtc_state,
1418 struct drm_atomic_state *old_state);
1392 1419
1393unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, 1420unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
1394 int plane, unsigned int height); 1421 int plane, unsigned int height);
@@ -1571,8 +1598,6 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv);
1571void bxt_disable_dc9(struct drm_i915_private *dev_priv); 1598void bxt_disable_dc9(struct drm_i915_private *dev_priv);
1572void gen9_enable_dc5(struct drm_i915_private *dev_priv); 1599void gen9_enable_dc5(struct drm_i915_private *dev_priv);
1573unsigned int skl_cdclk_get_vco(unsigned int freq); 1600unsigned int skl_cdclk_get_vco(unsigned int freq);
1574void skl_enable_dc6(struct drm_i915_private *dev_priv);
1575void skl_disable_dc6(struct drm_i915_private *dev_priv);
1576void intel_dp_get_m_n(struct intel_crtc *crtc, 1601void intel_dp_get_m_n(struct intel_crtc *crtc,
1577 struct intel_crtc_state *pipe_config); 1602 struct intel_crtc_state *pipe_config);
1578void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n); 1603void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n);
@@ -1588,9 +1613,12 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state);
1588enum intel_display_power_domain intel_port_to_power_domain(enum port port); 1613enum intel_display_power_domain intel_port_to_power_domain(enum port port);
1589void intel_mode_from_pipe_config(struct drm_display_mode *mode, 1614void intel_mode_from_pipe_config(struct drm_display_mode *mode,
1590 struct intel_crtc_state *pipe_config); 1615 struct intel_crtc_state *pipe_config);
1616void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
1617 struct intel_crtc_state *crtc_state);
1591 1618
1592int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state); 1619int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
1593int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state); 1620int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1621 uint32_t pixel_format);
1594 1622
1595static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state) 1623static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
1596{ 1624{
@@ -1607,6 +1635,7 @@ u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane,
1607int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, 1635int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
1608 struct intel_plane_state *plane_state); 1636 struct intel_plane_state *plane_state);
1609int i9xx_check_plane_surface(struct intel_plane_state *plane_state); 1637int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
1638int skl_format_to_fourcc(int format, bool rgb_order, bool alpha);
1610 1639
1611/* intel_csr.c */ 1640/* intel_csr.c */
1612void intel_csr_ucode_init(struct drm_i915_private *); 1641void intel_csr_ucode_init(struct drm_i915_private *);
@@ -1773,6 +1802,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
1773 unsigned int frontbuffer_bits, enum fb_op_origin origin); 1802 unsigned int frontbuffer_bits, enum fb_op_origin origin);
1774void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv); 1803void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
1775void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *dev_priv); 1804void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *dev_priv);
1805int intel_fbc_reset_underrun(struct drm_i915_private *dev_priv);
1776 1806
1777/* intel_hdmi.c */ 1807/* intel_hdmi.c */
1778void intel_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg, 1808void intel_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg,
@@ -1783,7 +1813,7 @@ struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
1783bool intel_hdmi_compute_config(struct intel_encoder *encoder, 1813bool intel_hdmi_compute_config(struct intel_encoder *encoder,
1784 struct intel_crtc_state *pipe_config, 1814 struct intel_crtc_state *pipe_config,
1785 struct drm_connector_state *conn_state); 1815 struct drm_connector_state *conn_state);
1786void intel_hdmi_handle_sink_scrambling(struct intel_encoder *intel_encoder, 1816bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
1787 struct drm_connector *connector, 1817 struct drm_connector *connector,
1788 bool high_tmds_clock_ratio, 1818 bool high_tmds_clock_ratio,
1789 bool scrambling); 1819 bool scrambling);
@@ -1877,7 +1907,8 @@ void intel_psr_enable(struct intel_dp *intel_dp,
1877void intel_psr_disable(struct intel_dp *intel_dp, 1907void intel_psr_disable(struct intel_dp *intel_dp,
1878 const struct intel_crtc_state *old_crtc_state); 1908 const struct intel_crtc_state *old_crtc_state);
1879void intel_psr_invalidate(struct drm_i915_private *dev_priv, 1909void intel_psr_invalidate(struct drm_i915_private *dev_priv,
1880 unsigned frontbuffer_bits); 1910 unsigned frontbuffer_bits,
1911 enum fb_op_origin origin);
1881void intel_psr_flush(struct drm_i915_private *dev_priv, 1912void intel_psr_flush(struct drm_i915_private *dev_priv,
1882 unsigned frontbuffer_bits, 1913 unsigned frontbuffer_bits,
1883 enum fb_op_origin origin); 1914 enum fb_op_origin origin);
@@ -1886,6 +1917,8 @@ void intel_psr_single_frame_update(struct drm_i915_private *dev_priv,
1886 unsigned frontbuffer_bits); 1917 unsigned frontbuffer_bits);
1887void intel_psr_compute_config(struct intel_dp *intel_dp, 1918void intel_psr_compute_config(struct intel_dp *intel_dp,
1888 struct intel_crtc_state *crtc_state); 1919 struct intel_crtc_state *crtc_state);
1920void intel_psr_irq_control(struct drm_i915_private *dev_priv, bool debug);
1921void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir);
1889 1922
1890/* intel_runtime_pm.c */ 1923/* intel_runtime_pm.c */
1891int intel_power_domains_init(struct drm_i915_private *); 1924int intel_power_domains_init(struct drm_i915_private *);
@@ -1909,6 +1942,8 @@ bool intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
1909 enum intel_display_power_domain domain); 1942 enum intel_display_power_domain domain);
1910void intel_display_power_put(struct drm_i915_private *dev_priv, 1943void intel_display_power_put(struct drm_i915_private *dev_priv,
1911 enum intel_display_power_domain domain); 1944 enum intel_display_power_domain domain);
1945void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
1946 u8 req_slices);
1912 1947
1913static inline void 1948static inline void
1914assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv) 1949assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
@@ -2046,6 +2081,9 @@ void skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc);
2046bool skl_plane_get_hw_state(struct intel_plane *plane); 2081bool skl_plane_get_hw_state(struct intel_plane *plane);
2047bool skl_plane_has_ccs(struct drm_i915_private *dev_priv, 2082bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
2048 enum pipe pipe, enum plane_id plane_id); 2083 enum pipe pipe, enum plane_id plane_id);
2084bool intel_format_is_yuv(uint32_t format);
2085bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
2086 enum pipe pipe, enum plane_id plane_id);
2049 2087
2050/* intel_tv.c */ 2088/* intel_tv.c */
2051void intel_tv_init(struct drm_i915_private *dev_priv); 2089void intel_tv_init(struct drm_i915_private *dev_priv);
@@ -2082,31 +2120,6 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
2082 return to_intel_crtc_state(crtc_state); 2120 return to_intel_crtc_state(crtc_state);
2083} 2121}
2084 2122
2085static inline struct intel_crtc_state *
2086intel_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
2087 struct intel_crtc *crtc)
2088{
2089 struct drm_crtc_state *crtc_state;
2090
2091 crtc_state = drm_atomic_get_existing_crtc_state(state, &crtc->base);
2092
2093 if (crtc_state)
2094 return to_intel_crtc_state(crtc_state);
2095 else
2096 return NULL;
2097}
2098
2099static inline struct intel_plane_state *
2100intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
2101 struct intel_plane *plane)
2102{
2103 struct drm_plane_state *plane_state;
2104
2105 plane_state = drm_atomic_get_existing_plane_state(state, &plane->base);
2106
2107 return to_intel_plane_state(plane_state);
2108}
2109
2110int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, 2123int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
2111 struct intel_crtc *intel_crtc, 2124 struct intel_crtc *intel_crtc,
2112 struct intel_crtc_state *crtc_state); 2125 struct intel_crtc_state *crtc_state);
@@ -2138,8 +2151,17 @@ int intel_pipe_crc_create(struct drm_minor *minor);
2138#ifdef CONFIG_DEBUG_FS 2151#ifdef CONFIG_DEBUG_FS
2139int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name, 2152int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
2140 size_t *values_cnt); 2153 size_t *values_cnt);
2154void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc);
2155void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc);
2141#else 2156#else
2142#define intel_crtc_set_crc_source NULL 2157#define intel_crtc_set_crc_source NULL
2158static inline void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
2159{
2160}
2161
2162static inline void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc)
2163{
2164}
2143#endif 2165#endif
2144extern const struct file_operations i915_display_crc_ctl_fops; 2166extern const struct file_operations i915_display_crc_ctl_fops;
2145#endif /* __INTEL_DRV_H__ */ 2167#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c
index 91c07b0c8db9..4d6ffa7b3e7b 100644
--- a/drivers/gpu/drm/i915/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c
@@ -647,6 +647,11 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
647 /* prepare count */ 647 /* prepare count */
648 prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den, ui_num * mul); 648 prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den, ui_num * mul);
649 649
650 if (prepare_cnt > PREPARE_CNT_MAX) {
651 DRM_DEBUG_KMS("prepare count too high %u\n", prepare_cnt);
652 prepare_cnt = PREPARE_CNT_MAX;
653 }
654
650 /* exit zero count */ 655 /* exit zero count */
651 exit_zero_cnt = DIV_ROUND_UP( 656 exit_zero_cnt = DIV_ROUND_UP(
652 (ths_prepare_hszero - ths_prepare_ns) * ui_den, 657 (ths_prepare_hszero - ths_prepare_ns) * ui_den,
@@ -662,32 +667,29 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
662 if (exit_zero_cnt < (55 * ui_den / ui_num) && (55 * ui_den) % ui_num) 667 if (exit_zero_cnt < (55 * ui_den / ui_num) && (55 * ui_den) % ui_num)
663 exit_zero_cnt += 1; 668 exit_zero_cnt += 1;
664 669
670 if (exit_zero_cnt > EXIT_ZERO_CNT_MAX) {
671 DRM_DEBUG_KMS("exit zero count too high %u\n", exit_zero_cnt);
672 exit_zero_cnt = EXIT_ZERO_CNT_MAX;
673 }
674
665 /* clk zero count */ 675 /* clk zero count */
666 clk_zero_cnt = DIV_ROUND_UP( 676 clk_zero_cnt = DIV_ROUND_UP(
667 (tclk_prepare_clkzero - ths_prepare_ns) 677 (tclk_prepare_clkzero - ths_prepare_ns)
668 * ui_den, ui_num * mul); 678 * ui_den, ui_num * mul);
669 679
680 if (clk_zero_cnt > CLK_ZERO_CNT_MAX) {
681 DRM_DEBUG_KMS("clock zero count too high %u\n", clk_zero_cnt);
682 clk_zero_cnt = CLK_ZERO_CNT_MAX;
683 }
684
670 /* trail count */ 685 /* trail count */
671 tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); 686 tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail);
672 trail_cnt = DIV_ROUND_UP(tclk_trail_ns * ui_den, ui_num * mul); 687 trail_cnt = DIV_ROUND_UP(tclk_trail_ns * ui_den, ui_num * mul);
673 688
674 if (prepare_cnt > PREPARE_CNT_MAX || 689 if (trail_cnt > TRAIL_CNT_MAX) {
675 exit_zero_cnt > EXIT_ZERO_CNT_MAX || 690 DRM_DEBUG_KMS("trail count too high %u\n", trail_cnt);
676 clk_zero_cnt > CLK_ZERO_CNT_MAX ||
677 trail_cnt > TRAIL_CNT_MAX)
678 DRM_DEBUG_DRIVER("Values crossing maximum limits, restricting to max values\n");
679
680 if (prepare_cnt > PREPARE_CNT_MAX)
681 prepare_cnt = PREPARE_CNT_MAX;
682
683 if (exit_zero_cnt > EXIT_ZERO_CNT_MAX)
684 exit_zero_cnt = EXIT_ZERO_CNT_MAX;
685
686 if (clk_zero_cnt > CLK_ZERO_CNT_MAX)
687 clk_zero_cnt = CLK_ZERO_CNT_MAX;
688
689 if (trail_cnt > TRAIL_CNT_MAX)
690 trail_cnt = TRAIL_CNT_MAX; 691 trail_cnt = TRAIL_CNT_MAX;
692 }
691 693
692 /* B080 */ 694 /* B080 */
693 intel_dsi->dphy_reg = exit_zero_cnt << 24 | trail_cnt << 16 | 695 intel_dsi->dphy_reg = exit_zero_cnt << 24 | trail_cnt << 16 |
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index f7c25828d3bb..6bfd7e3ed152 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -81,13 +81,17 @@ static const struct engine_class_info intel_engine_classes[] = {
81 }, 81 },
82}; 82};
83 83
84#define MAX_MMIO_BASES 3
84struct engine_info { 85struct engine_info {
85 unsigned int hw_id; 86 unsigned int hw_id;
86 unsigned int uabi_id; 87 unsigned int uabi_id;
87 u8 class; 88 u8 class;
88 u8 instance; 89 u8 instance;
89 u32 mmio_base; 90 /* mmio bases table *must* be sorted in reverse gen order */
90 unsigned irq_shift; 91 struct engine_mmio_base {
92 u32 gen : 8;
93 u32 base : 24;
94 } mmio_bases[MAX_MMIO_BASES];
91}; 95};
92 96
93static const struct engine_info intel_engines[] = { 97static const struct engine_info intel_engines[] = {
@@ -96,64 +100,76 @@ static const struct engine_info intel_engines[] = {
96 .uabi_id = I915_EXEC_RENDER, 100 .uabi_id = I915_EXEC_RENDER,
97 .class = RENDER_CLASS, 101 .class = RENDER_CLASS,
98 .instance = 0, 102 .instance = 0,
99 .mmio_base = RENDER_RING_BASE, 103 .mmio_bases = {
100 .irq_shift = GEN8_RCS_IRQ_SHIFT, 104 { .gen = 1, .base = RENDER_RING_BASE }
105 },
101 }, 106 },
102 [BCS] = { 107 [BCS] = {
103 .hw_id = BCS_HW, 108 .hw_id = BCS_HW,
104 .uabi_id = I915_EXEC_BLT, 109 .uabi_id = I915_EXEC_BLT,
105 .class = COPY_ENGINE_CLASS, 110 .class = COPY_ENGINE_CLASS,
106 .instance = 0, 111 .instance = 0,
107 .mmio_base = BLT_RING_BASE, 112 .mmio_bases = {
108 .irq_shift = GEN8_BCS_IRQ_SHIFT, 113 { .gen = 6, .base = BLT_RING_BASE }
114 },
109 }, 115 },
110 [VCS] = { 116 [VCS] = {
111 .hw_id = VCS_HW, 117 .hw_id = VCS_HW,
112 .uabi_id = I915_EXEC_BSD, 118 .uabi_id = I915_EXEC_BSD,
113 .class = VIDEO_DECODE_CLASS, 119 .class = VIDEO_DECODE_CLASS,
114 .instance = 0, 120 .instance = 0,
115 .mmio_base = GEN6_BSD_RING_BASE, 121 .mmio_bases = {
116 .irq_shift = GEN8_VCS1_IRQ_SHIFT, 122 { .gen = 11, .base = GEN11_BSD_RING_BASE },
123 { .gen = 6, .base = GEN6_BSD_RING_BASE },
124 { .gen = 4, .base = BSD_RING_BASE }
125 },
117 }, 126 },
118 [VCS2] = { 127 [VCS2] = {
119 .hw_id = VCS2_HW, 128 .hw_id = VCS2_HW,
120 .uabi_id = I915_EXEC_BSD, 129 .uabi_id = I915_EXEC_BSD,
121 .class = VIDEO_DECODE_CLASS, 130 .class = VIDEO_DECODE_CLASS,
122 .instance = 1, 131 .instance = 1,
123 .mmio_base = GEN8_BSD2_RING_BASE, 132 .mmio_bases = {
124 .irq_shift = GEN8_VCS2_IRQ_SHIFT, 133 { .gen = 11, .base = GEN11_BSD2_RING_BASE },
134 { .gen = 8, .base = GEN8_BSD2_RING_BASE }
135 },
125 }, 136 },
126 [VCS3] = { 137 [VCS3] = {
127 .hw_id = VCS3_HW, 138 .hw_id = VCS3_HW,
128 .uabi_id = I915_EXEC_BSD, 139 .uabi_id = I915_EXEC_BSD,
129 .class = VIDEO_DECODE_CLASS, 140 .class = VIDEO_DECODE_CLASS,
130 .instance = 2, 141 .instance = 2,
131 .mmio_base = GEN11_BSD3_RING_BASE, 142 .mmio_bases = {
132 .irq_shift = 0, /* not used */ 143 { .gen = 11, .base = GEN11_BSD3_RING_BASE }
144 },
133 }, 145 },
134 [VCS4] = { 146 [VCS4] = {
135 .hw_id = VCS4_HW, 147 .hw_id = VCS4_HW,
136 .uabi_id = I915_EXEC_BSD, 148 .uabi_id = I915_EXEC_BSD,
137 .class = VIDEO_DECODE_CLASS, 149 .class = VIDEO_DECODE_CLASS,
138 .instance = 3, 150 .instance = 3,
139 .mmio_base = GEN11_BSD4_RING_BASE, 151 .mmio_bases = {
140 .irq_shift = 0, /* not used */ 152 { .gen = 11, .base = GEN11_BSD4_RING_BASE }
153 },
141 }, 154 },
142 [VECS] = { 155 [VECS] = {
143 .hw_id = VECS_HW, 156 .hw_id = VECS_HW,
144 .uabi_id = I915_EXEC_VEBOX, 157 .uabi_id = I915_EXEC_VEBOX,
145 .class = VIDEO_ENHANCEMENT_CLASS, 158 .class = VIDEO_ENHANCEMENT_CLASS,
146 .instance = 0, 159 .instance = 0,
147 .mmio_base = VEBOX_RING_BASE, 160 .mmio_bases = {
148 .irq_shift = GEN8_VECS_IRQ_SHIFT, 161 { .gen = 11, .base = GEN11_VEBOX_RING_BASE },
162 { .gen = 7, .base = VEBOX_RING_BASE }
163 },
149 }, 164 },
150 [VECS2] = { 165 [VECS2] = {
151 .hw_id = VECS2_HW, 166 .hw_id = VECS2_HW,
152 .uabi_id = I915_EXEC_VEBOX, 167 .uabi_id = I915_EXEC_VEBOX,
153 .class = VIDEO_ENHANCEMENT_CLASS, 168 .class = VIDEO_ENHANCEMENT_CLASS,
154 .instance = 1, 169 .instance = 1,
155 .mmio_base = GEN11_VEBOX2_RING_BASE, 170 .mmio_bases = {
156 .irq_shift = 0, /* not used */ 171 { .gen = 11, .base = GEN11_VEBOX2_RING_BASE }
172 },
157 }, 173 },
158}; 174};
159 175
@@ -223,16 +239,36 @@ __intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class)
223 } 239 }
224} 240}
225 241
242static u32 __engine_mmio_base(struct drm_i915_private *i915,
243 const struct engine_mmio_base *bases)
244{
245 int i;
246
247 for (i = 0; i < MAX_MMIO_BASES; i++)
248 if (INTEL_GEN(i915) >= bases[i].gen)
249 break;
250
251 GEM_BUG_ON(i == MAX_MMIO_BASES);
252 GEM_BUG_ON(!bases[i].base);
253
254 return bases[i].base;
255}
256
257static void __sprint_engine_name(char *name, const struct engine_info *info)
258{
259 WARN_ON(snprintf(name, INTEL_ENGINE_CS_MAX_NAME, "%s%u",
260 intel_engine_classes[info->class].name,
261 info->instance) >= INTEL_ENGINE_CS_MAX_NAME);
262}
263
226static int 264static int
227intel_engine_setup(struct drm_i915_private *dev_priv, 265intel_engine_setup(struct drm_i915_private *dev_priv,
228 enum intel_engine_id id) 266 enum intel_engine_id id)
229{ 267{
230 const struct engine_info *info = &intel_engines[id]; 268 const struct engine_info *info = &intel_engines[id];
231 const struct engine_class_info *class_info;
232 struct intel_engine_cs *engine; 269 struct intel_engine_cs *engine;
233 270
234 GEM_BUG_ON(info->class >= ARRAY_SIZE(intel_engine_classes)); 271 GEM_BUG_ON(info->class >= ARRAY_SIZE(intel_engine_classes));
235 class_info = &intel_engine_classes[info->class];
236 272
237 BUILD_BUG_ON(MAX_ENGINE_CLASS >= BIT(GEN11_ENGINE_CLASS_WIDTH)); 273 BUILD_BUG_ON(MAX_ENGINE_CLASS >= BIT(GEN11_ENGINE_CLASS_WIDTH));
238 BUILD_BUG_ON(MAX_ENGINE_INSTANCE >= BIT(GEN11_ENGINE_INSTANCE_WIDTH)); 274 BUILD_BUG_ON(MAX_ENGINE_INSTANCE >= BIT(GEN11_ENGINE_INSTANCE_WIDTH));
@@ -253,35 +289,14 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
253 289
254 engine->id = id; 290 engine->id = id;
255 engine->i915 = dev_priv; 291 engine->i915 = dev_priv;
256 WARN_ON(snprintf(engine->name, sizeof(engine->name), "%s%u", 292 __sprint_engine_name(engine->name, info);
257 class_info->name, info->instance) >=
258 sizeof(engine->name));
259 engine->hw_id = engine->guc_id = info->hw_id; 293 engine->hw_id = engine->guc_id = info->hw_id;
260 if (INTEL_GEN(dev_priv) >= 11) { 294 engine->mmio_base = __engine_mmio_base(dev_priv, info->mmio_bases);
261 switch (engine->id) {
262 case VCS:
263 engine->mmio_base = GEN11_BSD_RING_BASE;
264 break;
265 case VCS2:
266 engine->mmio_base = GEN11_BSD2_RING_BASE;
267 break;
268 case VECS:
269 engine->mmio_base = GEN11_VEBOX_RING_BASE;
270 break;
271 default:
272 /* take the original value for all other engines */
273 engine->mmio_base = info->mmio_base;
274 break;
275 }
276 } else {
277 engine->mmio_base = info->mmio_base;
278 }
279 engine->irq_shift = info->irq_shift;
280 engine->class = info->class; 295 engine->class = info->class;
281 engine->instance = info->instance; 296 engine->instance = info->instance;
282 297
283 engine->uabi_id = info->uabi_id; 298 engine->uabi_id = info->uabi_id;
284 engine->uabi_class = class_info->uabi_class; 299 engine->uabi_class = intel_engine_classes[info->class].uabi_class;
285 300
286 engine->context_size = __intel_engine_context_size(dev_priv, 301 engine->context_size = __intel_engine_context_size(dev_priv,
287 engine->class); 302 engine->class);
@@ -291,7 +306,7 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
291 /* Nothing to do here, execute in order of dependencies */ 306 /* Nothing to do here, execute in order of dependencies */
292 engine->schedule = NULL; 307 engine->schedule = NULL;
293 308
294 spin_lock_init(&engine->stats.lock); 309 seqlock_init(&engine->stats.lock);
295 310
296 ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier); 311 ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
297 312
@@ -436,21 +451,13 @@ void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
436 GEM_BUG_ON(intel_engine_get_seqno(engine) != seqno); 451 GEM_BUG_ON(intel_engine_get_seqno(engine) != seqno);
437} 452}
438 453
439static void intel_engine_init_timeline(struct intel_engine_cs *engine) 454static void intel_engine_init_batch_pool(struct intel_engine_cs *engine)
440{ 455{
441 engine->timeline = &engine->i915->gt.global_timeline.engine[engine->id]; 456 i915_gem_batch_pool_init(&engine->batch_pool, engine);
442} 457}
443 458
444static bool csb_force_mmio(struct drm_i915_private *i915) 459static bool csb_force_mmio(struct drm_i915_private *i915)
445{ 460{
446 /*
447 * IOMMU adds unpredictable latency causing the CSB write (from the
448 * GPU into the HWSP) to only be visible some time after the interrupt
449 * (missed breadcrumb syndrome).
450 */
451 if (intel_vtd_active())
452 return true;
453
454 /* Older GVT emulation depends upon intercepting CSB mmio */ 461 /* Older GVT emulation depends upon intercepting CSB mmio */
455 if (intel_vgpu_active(i915) && !intel_vgpu_has_hwsp_emulation(i915)) 462 if (intel_vgpu_active(i915) && !intel_vgpu_has_hwsp_emulation(i915))
456 return true; 463 return true;
@@ -484,12 +491,11 @@ static void intel_engine_init_execlist(struct intel_engine_cs *engine)
484 */ 491 */
485void intel_engine_setup_common(struct intel_engine_cs *engine) 492void intel_engine_setup_common(struct intel_engine_cs *engine)
486{ 493{
487 intel_engine_init_execlist(engine); 494 i915_timeline_init(engine->i915, &engine->timeline, engine->name);
488 495
489 intel_engine_init_timeline(engine); 496 intel_engine_init_execlist(engine);
490 intel_engine_init_hangcheck(engine); 497 intel_engine_init_hangcheck(engine);
491 i915_gem_batch_pool_init(engine, &engine->batch_pool); 498 intel_engine_init_batch_pool(engine);
492
493 intel_engine_init_cmd_parser(engine); 499 intel_engine_init_cmd_parser(engine);
494} 500}
495 501
@@ -520,8 +526,6 @@ int intel_engine_create_scratch(struct intel_engine_cs *engine, int size)
520 goto err_unref; 526 goto err_unref;
521 527
522 engine->scratch = vma; 528 engine->scratch = vma;
523 DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n",
524 engine->name, i915_ggtt_offset(vma));
525 return 0; 529 return 0;
526 530
527err_unref: 531err_unref:
@@ -615,9 +619,6 @@ static int init_status_page(struct intel_engine_cs *engine)
615 engine->status_page.vma = vma; 619 engine->status_page.vma = vma;
616 engine->status_page.ggtt_offset = i915_ggtt_offset(vma); 620 engine->status_page.ggtt_offset = i915_ggtt_offset(vma);
617 engine->status_page.page_addr = memset(vaddr, 0, PAGE_SIZE); 621 engine->status_page.page_addr = memset(vaddr, 0, PAGE_SIZE);
618
619 DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
620 engine->name, i915_ggtt_offset(vma));
621 return 0; 622 return 0;
622 623
623err_unpin: 624err_unpin:
@@ -669,7 +670,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine)
669 * be available. To avoid this we always pin the default 670 * be available. To avoid this we always pin the default
670 * context. 671 * context.
671 */ 672 */
672 ring = engine->context_pin(engine, engine->i915->kernel_context); 673 ring = intel_context_pin(engine->i915->kernel_context, engine);
673 if (IS_ERR(ring)) 674 if (IS_ERR(ring))
674 return PTR_ERR(ring); 675 return PTR_ERR(ring);
675 676
@@ -678,8 +679,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine)
678 * we can interrupt the engine at any time. 679 * we can interrupt the engine at any time.
679 */ 680 */
680 if (engine->i915->preempt_context) { 681 if (engine->i915->preempt_context) {
681 ring = engine->context_pin(engine, 682 ring = intel_context_pin(engine->i915->preempt_context, engine);
682 engine->i915->preempt_context);
683 if (IS_ERR(ring)) { 683 if (IS_ERR(ring)) {
684 ret = PTR_ERR(ring); 684 ret = PTR_ERR(ring);
685 goto err_unpin_kernel; 685 goto err_unpin_kernel;
@@ -703,9 +703,9 @@ err_breadcrumbs:
703 intel_engine_fini_breadcrumbs(engine); 703 intel_engine_fini_breadcrumbs(engine);
704err_unpin_preempt: 704err_unpin_preempt:
705 if (engine->i915->preempt_context) 705 if (engine->i915->preempt_context)
706 engine->context_unpin(engine, engine->i915->preempt_context); 706 intel_context_unpin(engine->i915->preempt_context, engine);
707err_unpin_kernel: 707err_unpin_kernel:
708 engine->context_unpin(engine, engine->i915->kernel_context); 708 intel_context_unpin(engine->i915->kernel_context, engine);
709 return ret; 709 return ret;
710} 710}
711 711
@@ -733,8 +733,10 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
733 i915_gem_object_put(engine->default_state); 733 i915_gem_object_put(engine->default_state);
734 734
735 if (engine->i915->preempt_context) 735 if (engine->i915->preempt_context)
736 engine->context_unpin(engine, engine->i915->preempt_context); 736 intel_context_unpin(engine->i915->preempt_context, engine);
737 engine->context_unpin(engine, engine->i915->kernel_context); 737 intel_context_unpin(engine->i915->kernel_context, engine);
738
739 i915_timeline_fini(&engine->timeline);
738} 740}
739 741
740u64 intel_engine_get_active_head(const struct intel_engine_cs *engine) 742u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
@@ -782,10 +784,24 @@ static inline uint32_t
782read_subslice_reg(struct drm_i915_private *dev_priv, int slice, 784read_subslice_reg(struct drm_i915_private *dev_priv, int slice,
783 int subslice, i915_reg_t reg) 785 int subslice, i915_reg_t reg)
784{ 786{
787 uint32_t mcr_slice_subslice_mask;
788 uint32_t mcr_slice_subslice_select;
785 uint32_t mcr; 789 uint32_t mcr;
786 uint32_t ret; 790 uint32_t ret;
787 enum forcewake_domains fw_domains; 791 enum forcewake_domains fw_domains;
788 792
793 if (INTEL_GEN(dev_priv) >= 11) {
794 mcr_slice_subslice_mask = GEN11_MCR_SLICE_MASK |
795 GEN11_MCR_SUBSLICE_MASK;
796 mcr_slice_subslice_select = GEN11_MCR_SLICE(slice) |
797 GEN11_MCR_SUBSLICE(subslice);
798 } else {
799 mcr_slice_subslice_mask = GEN8_MCR_SLICE_MASK |
800 GEN8_MCR_SUBSLICE_MASK;
801 mcr_slice_subslice_select = GEN8_MCR_SLICE(slice) |
802 GEN8_MCR_SUBSLICE(subslice);
803 }
804
789 fw_domains = intel_uncore_forcewake_for_reg(dev_priv, reg, 805 fw_domains = intel_uncore_forcewake_for_reg(dev_priv, reg,
790 FW_REG_READ); 806 FW_REG_READ);
791 fw_domains |= intel_uncore_forcewake_for_reg(dev_priv, 807 fw_domains |= intel_uncore_forcewake_for_reg(dev_priv,
@@ -800,14 +816,14 @@ read_subslice_reg(struct drm_i915_private *dev_priv, int slice,
800 * The HW expects the slice and sublice selectors to be reset to 0 816 * The HW expects the slice and sublice selectors to be reset to 0
801 * after reading out the registers. 817 * after reading out the registers.
802 */ 818 */
803 WARN_ON_ONCE(mcr & (GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK)); 819 WARN_ON_ONCE(mcr & mcr_slice_subslice_mask);
804 mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK); 820 mcr &= ~mcr_slice_subslice_mask;
805 mcr |= GEN8_MCR_SLICE(slice) | GEN8_MCR_SUBSLICE(subslice); 821 mcr |= mcr_slice_subslice_select;
806 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr); 822 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
807 823
808 ret = I915_READ_FW(reg); 824 ret = I915_READ_FW(reg);
809 825
810 mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK); 826 mcr &= ~mcr_slice_subslice_mask;
811 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr); 827 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
812 828
813 intel_uncore_forcewake_put__locked(dev_priv, fw_domains); 829 intel_uncore_forcewake_put__locked(dev_priv, fw_domains);
@@ -871,644 +887,6 @@ void intel_engine_get_instdone(struct intel_engine_cs *engine,
871 } 887 }
872} 888}
873 889
874static int wa_add(struct drm_i915_private *dev_priv,
875 i915_reg_t addr,
876 const u32 mask, const u32 val)
877{
878 const u32 idx = dev_priv->workarounds.count;
879
880 if (WARN_ON(idx >= I915_MAX_WA_REGS))
881 return -ENOSPC;
882
883 dev_priv->workarounds.reg[idx].addr = addr;
884 dev_priv->workarounds.reg[idx].value = val;
885 dev_priv->workarounds.reg[idx].mask = mask;
886
887 dev_priv->workarounds.count++;
888
889 return 0;
890}
891
892#define WA_REG(addr, mask, val) do { \
893 const int r = wa_add(dev_priv, (addr), (mask), (val)); \
894 if (r) \
895 return r; \
896 } while (0)
897
898#define WA_SET_BIT_MASKED(addr, mask) \
899 WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask))
900
901#define WA_CLR_BIT_MASKED(addr, mask) \
902 WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask))
903
904#define WA_SET_FIELD_MASKED(addr, mask, value) \
905 WA_REG(addr, mask, _MASKED_FIELD(mask, value))
906
907static int wa_ring_whitelist_reg(struct intel_engine_cs *engine,
908 i915_reg_t reg)
909{
910 struct drm_i915_private *dev_priv = engine->i915;
911 struct i915_workarounds *wa = &dev_priv->workarounds;
912 const uint32_t index = wa->hw_whitelist_count[engine->id];
913
914 if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS))
915 return -EINVAL;
916
917 I915_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index),
918 i915_mmio_reg_offset(reg));
919 wa->hw_whitelist_count[engine->id]++;
920
921 return 0;
922}
923
924static int gen8_init_workarounds(struct intel_engine_cs *engine)
925{
926 struct drm_i915_private *dev_priv = engine->i915;
927
928 WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
929
930 /* WaDisableAsyncFlipPerfMode:bdw,chv */
931 WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE);
932
933 /* WaDisablePartialInstShootdown:bdw,chv */
934 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
935 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
936
937 /* Use Force Non-Coherent whenever executing a 3D context. This is a
938 * workaround for for a possible hang in the unlikely event a TLB
939 * invalidation occurs during a PSD flush.
940 */
941 /* WaForceEnableNonCoherent:bdw,chv */
942 /* WaHdcDisableFetchWhenMasked:bdw,chv */
943 WA_SET_BIT_MASKED(HDC_CHICKEN0,
944 HDC_DONOT_FETCH_MEM_WHEN_MASKED |
945 HDC_FORCE_NON_COHERENT);
946
947 /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
948 * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
949 * polygons in the same 8x4 pixel/sample area to be processed without
950 * stalling waiting for the earlier ones to write to Hierarchical Z
951 * buffer."
952 *
953 * This optimization is off by default for BDW and CHV; turn it on.
954 */
955 WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
956
957 /* Wa4x4STCOptimizationDisable:bdw,chv */
958 WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);
959
960 /*
961 * BSpec recommends 8x4 when MSAA is used,
962 * however in practice 16x4 seems fastest.
963 *
964 * Note that PS/WM thread counts depend on the WIZ hashing
965 * disable bit, which we don't touch here, but it's good
966 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
967 */
968 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
969 GEN6_WIZ_HASHING_MASK,
970 GEN6_WIZ_HASHING_16x4);
971
972 return 0;
973}
974
975static int bdw_init_workarounds(struct intel_engine_cs *engine)
976{
977 struct drm_i915_private *dev_priv = engine->i915;
978 int ret;
979
980 ret = gen8_init_workarounds(engine);
981 if (ret)
982 return ret;
983
984 /* WaDisableThreadStallDopClockGating:bdw (pre-production) */
985 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
986
987 /* WaDisableDopClockGating:bdw
988 *
989 * Also see the related UCGTCL1 write in broadwell_init_clock_gating()
990 * to disable EUTC clock gating.
991 */
992 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2,
993 DOP_CLOCK_GATING_DISABLE);
994
995 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
996 GEN8_SAMPLER_POWER_BYPASS_DIS);
997
998 WA_SET_BIT_MASKED(HDC_CHICKEN0,
999 /* WaForceContextSaveRestoreNonCoherent:bdw */
1000 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
1001 /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */
1002 (IS_BDW_GT3(dev_priv) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
1003
1004 return 0;
1005}
1006
1007static int chv_init_workarounds(struct intel_engine_cs *engine)
1008{
1009 struct drm_i915_private *dev_priv = engine->i915;
1010 int ret;
1011
1012 ret = gen8_init_workarounds(engine);
1013 if (ret)
1014 return ret;
1015
1016 /* WaDisableThreadStallDopClockGating:chv */
1017 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
1018
1019 /* Improve HiZ throughput on CHV. */
1020 WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
1021
1022 return 0;
1023}
1024
1025static int gen9_init_workarounds(struct intel_engine_cs *engine)
1026{
1027 struct drm_i915_private *dev_priv = engine->i915;
1028 int ret;
1029
1030 /* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
1031 I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
1032
1033 /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */
1034 I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
1035 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
1036
1037 /* WaDisableKillLogic:bxt,skl,kbl */
1038 if (!IS_COFFEELAKE(dev_priv))
1039 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
1040 ECOCHK_DIS_TLB);
1041
1042 if (HAS_LLC(dev_priv)) {
1043 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
1044 *
1045 * Must match Display Engine. See
1046 * WaCompressedResourceDisplayNewHashMode.
1047 */
1048 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1049 GEN9_PBE_COMPRESSED_HASH_SELECTION);
1050 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
1051 GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR);
1052
1053 I915_WRITE(MMCD_MISC_CTRL,
1054 I915_READ(MMCD_MISC_CTRL) |
1055 MMCD_PCLA |
1056 MMCD_HOTSPOT_EN);
1057 }
1058
1059 /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */
1060 /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */
1061 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
1062 FLOW_CONTROL_ENABLE |
1063 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
1064
1065 /* Syncing dependencies between camera and graphics:skl,bxt,kbl */
1066 if (!IS_COFFEELAKE(dev_priv))
1067 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
1068 GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
1069
1070 /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */
1071 /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */
1072 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
1073 GEN9_ENABLE_YV12_BUGFIX |
1074 GEN9_ENABLE_GPGPU_PREEMPTION);
1075
1076 /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk,cfl */
1077 /* WaDisablePartialResolveInVc:skl,bxt,kbl,cfl */
1078 WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE |
1079 GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE));
1080
1081 /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */
1082 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
1083 GEN9_CCS_TLB_PREFETCH_ENABLE);
1084
1085 /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */
1086 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1087 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
1088 HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
1089
1090 /* WaForceEnableNonCoherent and WaDisableHDCInvalidation are
1091 * both tied to WaForceContextSaveRestoreNonCoherent
1092 * in some hsds for skl. We keep the tie for all gen9. The
1093 * documentation is a bit hazy and so we want to get common behaviour,
1094 * even though there is no clear evidence we would need both on kbl/bxt.
1095 * This area has been source of system hangs so we play it safe
1096 * and mimic the skl regardless of what bspec says.
1097 *
1098 * Use Force Non-Coherent whenever executing a 3D context. This
1099 * is a workaround for a possible hang in the unlikely event
1100 * a TLB invalidation occurs during a PSD flush.
1101 */
1102
1103 /* WaForceEnableNonCoherent:skl,bxt,kbl,cfl */
1104 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1105 HDC_FORCE_NON_COHERENT);
1106
1107 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
1108 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
1109 BDW_DISABLE_HDC_INVALIDATION);
1110
1111 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */
1112 if (IS_SKYLAKE(dev_priv) ||
1113 IS_KABYLAKE(dev_priv) ||
1114 IS_COFFEELAKE(dev_priv))
1115 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
1116 GEN8_SAMPLER_POWER_BYPASS_DIS);
1117
1118 /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */
1119 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
1120
1121 /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */
1122 if (IS_GEN9_LP(dev_priv)) {
1123 u32 val = I915_READ(GEN8_L3SQCREG1);
1124
1125 val &= ~L3_PRIO_CREDITS_MASK;
1126 val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
1127 I915_WRITE(GEN8_L3SQCREG1, val);
1128 }
1129
1130 /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
1131 I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) |
1132 GEN8_LQSC_FLUSH_COHERENT_LINES));
1133
1134 /*
1135 * Supporting preemption with fine-granularity requires changes in the
1136 * batch buffer programming. Since we can't break old userspace, we
1137 * need to set our default preemption level to safe value. Userspace is
1138 * still able to use more fine-grained preemption levels, since in
1139 * WaEnablePreemptionGranularityControlByUMD we're whitelisting the
1140 * per-ctx register. As such, WaDisable{3D,GPGPU}MidCmdPreemption are
1141 * not real HW workarounds, but merely a way to start using preemption
1142 * while maintaining old contract with userspace.
1143 */
1144
1145 /* WaDisable3DMidCmdPreemption:skl,bxt,glk,cfl,[cnl] */
1146 WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL);
1147
1148 /* WaDisableGPGPUMidCmdPreemption:skl,bxt,blk,cfl,[cnl] */
1149 WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK,
1150 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);
1151
1152 /* WaClearHIZ_WM_CHICKEN3:bxt,glk */
1153 if (IS_GEN9_LP(dev_priv))
1154 WA_SET_BIT_MASKED(GEN9_WM_CHICKEN3, GEN9_FACTOR_IN_CLR_VAL_HIZ);
1155
1156 /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
1157 ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
1158 if (ret)
1159 return ret;
1160
1161 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */
1162 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
1163 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
1164 ret = wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
1165 if (ret)
1166 return ret;
1167
1168 /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
1169 ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
1170 if (ret)
1171 return ret;
1172
1173 return 0;
1174}
1175
1176static int skl_tune_iz_hashing(struct intel_engine_cs *engine)
1177{
1178 struct drm_i915_private *dev_priv = engine->i915;
1179 u8 vals[3] = { 0, 0, 0 };
1180 unsigned int i;
1181
1182 for (i = 0; i < 3; i++) {
1183 u8 ss;
1184
1185 /*
1186 * Only consider slices where one, and only one, subslice has 7
1187 * EUs
1188 */
1189 if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]))
1190 continue;
1191
1192 /*
1193 * subslice_7eu[i] != 0 (because of the check above) and
1194 * ss_max == 4 (maximum number of subslices possible per slice)
1195 *
1196 * -> 0 <= ss <= 3;
1197 */
1198 ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1;
1199 vals[i] = 3 - ss;
1200 }
1201
1202 if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
1203 return 0;
1204
1205 /* Tune IZ hashing. See intel_device_info_runtime_init() */
1206 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
1207 GEN9_IZ_HASHING_MASK(2) |
1208 GEN9_IZ_HASHING_MASK(1) |
1209 GEN9_IZ_HASHING_MASK(0),
1210 GEN9_IZ_HASHING(2, vals[2]) |
1211 GEN9_IZ_HASHING(1, vals[1]) |
1212 GEN9_IZ_HASHING(0, vals[0]));
1213
1214 return 0;
1215}
1216
1217static int skl_init_workarounds(struct intel_engine_cs *engine)
1218{
1219 struct drm_i915_private *dev_priv = engine->i915;
1220 int ret;
1221
1222 ret = gen9_init_workarounds(engine);
1223 if (ret)
1224 return ret;
1225
1226 /* WaEnableGapsTsvCreditFix:skl */
1227 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1228 GEN9_GAPS_TSV_CREDIT_DISABLE));
1229
1230 /* WaDisableGafsUnitClkGating:skl */
1231 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1232 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
1233
1234 /* WaInPlaceDecompressionHang:skl */
1235 if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER))
1236 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1237 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1238 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
1239
1240 /* WaDisableLSQCROPERFforOCL:skl */
1241 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1242 if (ret)
1243 return ret;
1244
1245 return skl_tune_iz_hashing(engine);
1246}
1247
1248static int bxt_init_workarounds(struct intel_engine_cs *engine)
1249{
1250 struct drm_i915_private *dev_priv = engine->i915;
1251 int ret;
1252
1253 ret = gen9_init_workarounds(engine);
1254 if (ret)
1255 return ret;
1256
1257 /* WaDisableThreadStallDopClockGating:bxt */
1258 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
1259 STALL_DOP_GATING_DISABLE);
1260
1261 /* WaDisablePooledEuLoadBalancingFix:bxt */
1262 I915_WRITE(FF_SLICE_CS_CHICKEN2,
1263 _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE));
1264
1265 /* WaToEnableHwFixForPushConstHWBug:bxt */
1266 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1267 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1268
1269 /* WaInPlaceDecompressionHang:bxt */
1270 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1271 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1272 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
1273
1274 return 0;
1275}
1276
1277static int cnl_init_workarounds(struct intel_engine_cs *engine)
1278{
1279 struct drm_i915_private *dev_priv = engine->i915;
1280 int ret;
1281
1282 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
1283 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
1284 I915_WRITE(GAMT_CHKN_BIT_REG,
1285 (I915_READ(GAMT_CHKN_BIT_REG) |
1286 GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT));
1287
1288 /* WaForceContextSaveRestoreNonCoherent:cnl */
1289 WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0,
1290 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT);
1291
1292 /* WaThrottleEUPerfToAvoidTDBackPressure:cnl(pre-prod) */
1293 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
1294 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, THROTTLE_12_5);
1295
1296 /* WaDisableReplayBufferBankArbitrationOptimization:cnl */
1297 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1298 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1299
1300 /* WaDisableEnhancedSBEVertexCaching:cnl (pre-prod) */
1301 if (IS_CNL_REVID(dev_priv, 0, CNL_REVID_B0))
1302 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1303 GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE);
1304
1305 /* WaInPlaceDecompressionHang:cnl */
1306 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1307 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1308 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
1309
1310 /* WaPushConstantDereferenceHoldDisable:cnl */
1311 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE);
1312
1313 /* FtrEnableFastAnisoL1BankingFix: cnl */
1314 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX);
1315
1316 /* WaDisable3DMidCmdPreemption:cnl */
1317 WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL);
1318
1319 /* WaDisableGPGPUMidCmdPreemption:cnl */
1320 WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK,
1321 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);
1322
1323 /* WaEnablePreemptionGranularityControlByUMD:cnl */
1324 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
1325 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
1326 ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
1327 if (ret)
1328 return ret;
1329
1330 /* WaDisableEarlyEOT:cnl */
1331 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, DISABLE_EARLY_EOT);
1332
1333 return 0;
1334}
1335
1336static int kbl_init_workarounds(struct intel_engine_cs *engine)
1337{
1338 struct drm_i915_private *dev_priv = engine->i915;
1339 int ret;
1340
1341 ret = gen9_init_workarounds(engine);
1342 if (ret)
1343 return ret;
1344
1345 /* WaEnableGapsTsvCreditFix:kbl */
1346 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1347 GEN9_GAPS_TSV_CREDIT_DISABLE));
1348
1349 /* WaDisableDynamicCreditSharing:kbl */
1350 if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
1351 I915_WRITE(GAMT_CHKN_BIT_REG,
1352 (I915_READ(GAMT_CHKN_BIT_REG) |
1353 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING));
1354
1355 /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */
1356 if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0))
1357 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1358 HDC_FENCE_DEST_SLM_DISABLE);
1359
1360 /* WaToEnableHwFixForPushConstHWBug:kbl */
1361 if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
1362 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1363 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1364
1365 /* WaDisableGafsUnitClkGating:kbl */
1366 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1367 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
1368
1369 /* WaDisableSbeCacheDispatchPortSharing:kbl */
1370 WA_SET_BIT_MASKED(
1371 GEN7_HALF_SLICE_CHICKEN1,
1372 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1373
1374 /* WaInPlaceDecompressionHang:kbl */
1375 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1376 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1377 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
1378
1379 /* WaDisableLSQCROPERFforOCL:kbl */
1380 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1381 if (ret)
1382 return ret;
1383
1384 return 0;
1385}
1386
1387static int glk_init_workarounds(struct intel_engine_cs *engine)
1388{
1389 struct drm_i915_private *dev_priv = engine->i915;
1390 int ret;
1391
1392 ret = gen9_init_workarounds(engine);
1393 if (ret)
1394 return ret;
1395
1396 /* WA #0862: Userspace has to set "Barrier Mode" to avoid hangs. */
1397 ret = wa_ring_whitelist_reg(engine, GEN9_SLICE_COMMON_ECO_CHICKEN1);
1398 if (ret)
1399 return ret;
1400
1401 /* WaToEnableHwFixForPushConstHWBug:glk */
1402 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1403 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1404
1405 return 0;
1406}
1407
1408static int cfl_init_workarounds(struct intel_engine_cs *engine)
1409{
1410 struct drm_i915_private *dev_priv = engine->i915;
1411 int ret;
1412
1413 ret = gen9_init_workarounds(engine);
1414 if (ret)
1415 return ret;
1416
1417 /* WaEnableGapsTsvCreditFix:cfl */
1418 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1419 GEN9_GAPS_TSV_CREDIT_DISABLE));
1420
1421 /* WaToEnableHwFixForPushConstHWBug:cfl */
1422 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1423 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1424
1425 /* WaDisableGafsUnitClkGating:cfl */
1426 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1427 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
1428
1429 /* WaDisableSbeCacheDispatchPortSharing:cfl */
1430 WA_SET_BIT_MASKED(
1431 GEN7_HALF_SLICE_CHICKEN1,
1432 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1433
1434 /* WaInPlaceDecompressionHang:cfl */
1435 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1436 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1437 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
1438
1439 return 0;
1440}
1441
1442int init_workarounds_ring(struct intel_engine_cs *engine)
1443{
1444 struct drm_i915_private *dev_priv = engine->i915;
1445 int err;
1446
1447 if (GEM_WARN_ON(engine->id != RCS))
1448 return -EINVAL;
1449
1450 dev_priv->workarounds.count = 0;
1451 dev_priv->workarounds.hw_whitelist_count[engine->id] = 0;
1452
1453 if (IS_BROADWELL(dev_priv))
1454 err = bdw_init_workarounds(engine);
1455 else if (IS_CHERRYVIEW(dev_priv))
1456 err = chv_init_workarounds(engine);
1457 else if (IS_SKYLAKE(dev_priv))
1458 err = skl_init_workarounds(engine);
1459 else if (IS_BROXTON(dev_priv))
1460 err = bxt_init_workarounds(engine);
1461 else if (IS_KABYLAKE(dev_priv))
1462 err = kbl_init_workarounds(engine);
1463 else if (IS_GEMINILAKE(dev_priv))
1464 err = glk_init_workarounds(engine);
1465 else if (IS_COFFEELAKE(dev_priv))
1466 err = cfl_init_workarounds(engine);
1467 else if (IS_CANNONLAKE(dev_priv))
1468 err = cnl_init_workarounds(engine);
1469 else
1470 err = 0;
1471 if (err)
1472 return err;
1473
1474 DRM_DEBUG_DRIVER("%s: Number of context specific w/a: %d\n",
1475 engine->name, dev_priv->workarounds.count);
1476 return 0;
1477}
1478
1479int intel_ring_workarounds_emit(struct i915_request *rq)
1480{
1481 struct i915_workarounds *w = &rq->i915->workarounds;
1482 u32 *cs;
1483 int ret, i;
1484
1485 if (w->count == 0)
1486 return 0;
1487
1488 ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
1489 if (ret)
1490 return ret;
1491
1492 cs = intel_ring_begin(rq, w->count * 2 + 2);
1493 if (IS_ERR(cs))
1494 return PTR_ERR(cs);
1495
1496 *cs++ = MI_LOAD_REGISTER_IMM(w->count);
1497 for (i = 0; i < w->count; i++) {
1498 *cs++ = i915_mmio_reg_offset(w->reg[i].addr);
1499 *cs++ = w->reg[i].value;
1500 }
1501 *cs++ = MI_NOOP;
1502
1503 intel_ring_advance(rq, cs);
1504
1505 ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
1506 if (ret)
1507 return ret;
1508
1509 return 0;
1510}
1511
1512static bool ring_is_idle(struct intel_engine_cs *engine) 890static bool ring_is_idle(struct intel_engine_cs *engine)
1513{ 891{
1514 struct drm_i915_private *dev_priv = engine->i915; 892 struct drm_i915_private *dev_priv = engine->i915;
@@ -1611,7 +989,7 @@ bool intel_engine_has_kernel_context(const struct intel_engine_cs *engine)
1611 * the last request that remains in the timeline. When idle, it is 989 * the last request that remains in the timeline. When idle, it is
1612 * the last executed context as tracked by retirement. 990 * the last executed context as tracked by retirement.
1613 */ 991 */
1614 rq = __i915_gem_active_peek(&engine->timeline->last_request); 992 rq = __i915_gem_active_peek(&engine->timeline.last_request);
1615 if (rq) 993 if (rq)
1616 return rq->ctx == kernel_context; 994 return rq->ctx == kernel_context;
1617 else 995 else
@@ -1659,6 +1037,9 @@ void intel_engines_park(struct drm_i915_private *i915)
1659 intel_engine_dump(engine, &p, NULL); 1037 intel_engine_dump(engine, &p, NULL);
1660 } 1038 }
1661 1039
1040 /* Must be reset upon idling, or we may miss the busy wakeup. */
1041 GEM_BUG_ON(engine->execlists.queue_priority != INT_MIN);
1042
1662 if (engine->park) 1043 if (engine->park)
1663 engine->park(engine); 1044 engine->park(engine);
1664 1045
@@ -1681,6 +1062,8 @@ void intel_engines_unpark(struct drm_i915_private *i915)
1681 for_each_engine(engine, i915, id) { 1062 for_each_engine(engine, i915, id) {
1682 if (engine->unpark) 1063 if (engine->unpark)
1683 engine->unpark(engine); 1064 engine->unpark(engine);
1065
1066 intel_engine_init_hangcheck(engine);
1684 } 1067 }
1685} 1068}
1686 1069
@@ -1713,17 +1096,37 @@ unsigned int intel_engines_has_context_isolation(struct drm_i915_private *i915)
1713 return which; 1096 return which;
1714} 1097}
1715 1098
1099static int print_sched_attr(struct drm_i915_private *i915,
1100 const struct i915_sched_attr *attr,
1101 char *buf, int x, int len)
1102{
1103 if (attr->priority == I915_PRIORITY_INVALID)
1104 return x;
1105
1106 x += snprintf(buf + x, len - x,
1107 " prio=%d", attr->priority);
1108
1109 return x;
1110}
1111
1716static void print_request(struct drm_printer *m, 1112static void print_request(struct drm_printer *m,
1717 struct i915_request *rq, 1113 struct i915_request *rq,
1718 const char *prefix) 1114 const char *prefix)
1719{ 1115{
1720 drm_printf(m, "%s%x%s [%llx:%x] prio=%d @ %dms: %s\n", prefix, 1116 const char *name = rq->fence.ops->get_timeline_name(&rq->fence);
1117 char buf[80];
1118 int x = 0;
1119
1120 x = print_sched_attr(rq->i915, &rq->sched.attr, buf, x, sizeof(buf));
1121
1122 drm_printf(m, "%s%x%s [%llx:%x]%s @ %dms: %s\n",
1123 prefix,
1721 rq->global_seqno, 1124 rq->global_seqno,
1722 i915_request_completed(rq) ? "!" : "", 1125 i915_request_completed(rq) ? "!" : "",
1723 rq->fence.context, rq->fence.seqno, 1126 rq->fence.context, rq->fence.seqno,
1724 rq->priotree.priority, 1127 buf,
1725 jiffies_to_msecs(jiffies - rq->emitted_jiffies), 1128 jiffies_to_msecs(jiffies - rq->emitted_jiffies),
1726 rq->timeline->common->name); 1129 name);
1727} 1130}
1728 1131
1729static void hexdump(struct drm_printer *m, const void *buf, size_t len) 1132static void hexdump(struct drm_printer *m, const void *buf, size_t len)
@@ -1829,12 +1232,15 @@ static void intel_engine_print_registers(const struct intel_engine_cs *engine,
1829 ptr = I915_READ(RING_CONTEXT_STATUS_PTR(engine)); 1232 ptr = I915_READ(RING_CONTEXT_STATUS_PTR(engine));
1830 read = GEN8_CSB_READ_PTR(ptr); 1233 read = GEN8_CSB_READ_PTR(ptr);
1831 write = GEN8_CSB_WRITE_PTR(ptr); 1234 write = GEN8_CSB_WRITE_PTR(ptr);
1832 drm_printf(m, "\tExeclist CSB read %d [%d cached], write %d [%d from hws], interrupt posted? %s\n", 1235 drm_printf(m, "\tExeclist CSB read %d [%d cached], write %d [%d from hws], interrupt posted? %s, tasklet queued? %s (%s)\n",
1833 read, execlists->csb_head, 1236 read, execlists->csb_head,
1834 write, 1237 write,
1835 intel_read_status_page(engine, intel_hws_csb_write_index(engine->i915)), 1238 intel_read_status_page(engine, intel_hws_csb_write_index(engine->i915)),
1836 yesno(test_bit(ENGINE_IRQ_EXECLIST, 1239 yesno(test_bit(ENGINE_IRQ_EXECLIST,
1837 &engine->irq_posted))); 1240 &engine->irq_posted)),
1241 yesno(test_bit(TASKLET_STATE_SCHED,
1242 &engine->execlists.tasklet.state)),
1243 enableddisabled(!atomic_read(&engine->execlists.tasklet.count)));
1838 if (read >= GEN8_CSB_ENTRIES) 1244 if (read >= GEN8_CSB_ENTRIES)
1839 read = 0; 1245 read = 0;
1840 if (write >= GEN8_CSB_ENTRIES) 1246 if (write >= GEN8_CSB_ENTRIES)
@@ -1861,8 +1267,9 @@ static void intel_engine_print_registers(const struct intel_engine_cs *engine,
1861 char hdr[80]; 1267 char hdr[80];
1862 1268
1863 snprintf(hdr, sizeof(hdr), 1269 snprintf(hdr, sizeof(hdr),
1864 "\t\tELSP[%d] count=%d, rq: ", 1270 "\t\tELSP[%d] count=%d, ring->start=%08x, rq: ",
1865 idx, count); 1271 idx, count,
1272 i915_ggtt_offset(rq->ring->vma));
1866 print_request(m, rq, hdr); 1273 print_request(m, rq, hdr);
1867 } else { 1274 } else {
1868 drm_printf(m, "\t\tELSP[%d] idle\n", idx); 1275 drm_printf(m, "\t\tELSP[%d] idle\n", idx);
@@ -1884,11 +1291,13 @@ void intel_engine_dump(struct intel_engine_cs *engine,
1884 struct drm_printer *m, 1291 struct drm_printer *m,
1885 const char *header, ...) 1292 const char *header, ...)
1886{ 1293{
1294 const int MAX_REQUESTS_TO_SHOW = 8;
1887 struct intel_breadcrumbs * const b = &engine->breadcrumbs; 1295 struct intel_breadcrumbs * const b = &engine->breadcrumbs;
1888 const struct intel_engine_execlists * const execlists = &engine->execlists; 1296 const struct intel_engine_execlists * const execlists = &engine->execlists;
1889 struct i915_gpu_error * const error = &engine->i915->gpu_error; 1297 struct i915_gpu_error * const error = &engine->i915->gpu_error;
1890 struct i915_request *rq; 1298 struct i915_request *rq, *last;
1891 struct rb_node *rb; 1299 struct rb_node *rb;
1300 int count;
1892 1301
1893 if (header) { 1302 if (header) {
1894 va_list ap; 1303 va_list ap;
@@ -1901,12 +1310,11 @@ void intel_engine_dump(struct intel_engine_cs *engine,
1901 if (i915_terminally_wedged(&engine->i915->gpu_error)) 1310 if (i915_terminally_wedged(&engine->i915->gpu_error))
1902 drm_printf(m, "*** WEDGED ***\n"); 1311 drm_printf(m, "*** WEDGED ***\n");
1903 1312
1904 drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms], inflight %d\n", 1313 drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms]\n",
1905 intel_engine_get_seqno(engine), 1314 intel_engine_get_seqno(engine),
1906 intel_engine_last_submit(engine), 1315 intel_engine_last_submit(engine),
1907 engine->hangcheck.seqno, 1316 engine->hangcheck.seqno,
1908 jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp), 1317 jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp));
1909 engine->timeline->inflight_seqnos);
1910 drm_printf(m, "\tReset count: %d (global %d)\n", 1318 drm_printf(m, "\tReset count: %d (global %d)\n",
1911 i915_reset_engine_count(error, engine), 1319 i915_reset_engine_count(error, engine),
1912 i915_reset_count(error)); 1320 i915_reset_count(error));
@@ -1915,14 +1323,14 @@ void intel_engine_dump(struct intel_engine_cs *engine,
1915 1323
1916 drm_printf(m, "\tRequests:\n"); 1324 drm_printf(m, "\tRequests:\n");
1917 1325
1918 rq = list_first_entry(&engine->timeline->requests, 1326 rq = list_first_entry(&engine->timeline.requests,
1919 struct i915_request, link); 1327 struct i915_request, link);
1920 if (&rq->link != &engine->timeline->requests) 1328 if (&rq->link != &engine->timeline.requests)
1921 print_request(m, rq, "\t\tfirst "); 1329 print_request(m, rq, "\t\tfirst ");
1922 1330
1923 rq = list_last_entry(&engine->timeline->requests, 1331 rq = list_last_entry(&engine->timeline.requests,
1924 struct i915_request, link); 1332 struct i915_request, link);
1925 if (&rq->link != &engine->timeline->requests) 1333 if (&rq->link != &engine->timeline.requests)
1926 print_request(m, rq, "\t\tlast "); 1334 print_request(m, rq, "\t\tlast ");
1927 1335
1928 rq = i915_gem_find_active_request(engine); 1336 rq = i915_gem_find_active_request(engine);
@@ -1933,12 +1341,16 @@ void intel_engine_dump(struct intel_engine_cs *engine,
1933 rq->head, rq->postfix, rq->tail, 1341 rq->head, rq->postfix, rq->tail,
1934 rq->batch ? upper_32_bits(rq->batch->node.start) : ~0u, 1342 rq->batch ? upper_32_bits(rq->batch->node.start) : ~0u,
1935 rq->batch ? lower_32_bits(rq->batch->node.start) : ~0u); 1343 rq->batch ? lower_32_bits(rq->batch->node.start) : ~0u);
1936 drm_printf(m, "\t\tring->start: 0x%08x\n", 1344 drm_printf(m, "\t\tring->start: 0x%08x\n",
1937 i915_ggtt_offset(rq->ring->vma)); 1345 i915_ggtt_offset(rq->ring->vma));
1938 drm_printf(m, "\t\tring->head: 0x%08x\n", 1346 drm_printf(m, "\t\tring->head: 0x%08x\n",
1939 rq->ring->head); 1347 rq->ring->head);
1940 drm_printf(m, "\t\tring->tail: 0x%08x\n", 1348 drm_printf(m, "\t\tring->tail: 0x%08x\n",
1941 rq->ring->tail); 1349 rq->ring->tail);
1350 drm_printf(m, "\t\tring->emit: 0x%08x\n",
1351 rq->ring->emit);
1352 drm_printf(m, "\t\tring->space: 0x%08x\n",
1353 rq->ring->space);
1942 } 1354 }
1943 1355
1944 rcu_read_unlock(); 1356 rcu_read_unlock();
@@ -1950,18 +1362,49 @@ void intel_engine_dump(struct intel_engine_cs *engine,
1950 drm_printf(m, "\tDevice is asleep; skipping register dump\n"); 1362 drm_printf(m, "\tDevice is asleep; skipping register dump\n");
1951 } 1363 }
1952 1364
1953 spin_lock_irq(&engine->timeline->lock); 1365 spin_lock_irq(&engine->timeline.lock);
1954 list_for_each_entry(rq, &engine->timeline->requests, link) 1366
1955 print_request(m, rq, "\t\tE "); 1367 last = NULL;
1368 count = 0;
1369 list_for_each_entry(rq, &engine->timeline.requests, link) {
1370 if (count++ < MAX_REQUESTS_TO_SHOW - 1)
1371 print_request(m, rq, "\t\tE ");
1372 else
1373 last = rq;
1374 }
1375 if (last) {
1376 if (count > MAX_REQUESTS_TO_SHOW) {
1377 drm_printf(m,
1378 "\t\t...skipping %d executing requests...\n",
1379 count - MAX_REQUESTS_TO_SHOW);
1380 }
1381 print_request(m, last, "\t\tE ");
1382 }
1383
1384 last = NULL;
1385 count = 0;
1956 drm_printf(m, "\t\tQueue priority: %d\n", execlists->queue_priority); 1386 drm_printf(m, "\t\tQueue priority: %d\n", execlists->queue_priority);
1957 for (rb = execlists->first; rb; rb = rb_next(rb)) { 1387 for (rb = execlists->first; rb; rb = rb_next(rb)) {
1958 struct i915_priolist *p = 1388 struct i915_priolist *p =
1959 rb_entry(rb, typeof(*p), node); 1389 rb_entry(rb, typeof(*p), node);
1960 1390
1961 list_for_each_entry(rq, &p->requests, priotree.link) 1391 list_for_each_entry(rq, &p->requests, sched.link) {
1962 print_request(m, rq, "\t\tQ "); 1392 if (count++ < MAX_REQUESTS_TO_SHOW - 1)
1393 print_request(m, rq, "\t\tQ ");
1394 else
1395 last = rq;
1396 }
1397 }
1398 if (last) {
1399 if (count > MAX_REQUESTS_TO_SHOW) {
1400 drm_printf(m,
1401 "\t\t...skipping %d queued requests...\n",
1402 count - MAX_REQUESTS_TO_SHOW);
1403 }
1404 print_request(m, last, "\t\tQ ");
1963 } 1405 }
1964 spin_unlock_irq(&engine->timeline->lock); 1406
1407 spin_unlock_irq(&engine->timeline.lock);
1965 1408
1966 spin_lock_irq(&b->rb_lock); 1409 spin_lock_irq(&b->rb_lock);
1967 for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { 1410 for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) {
@@ -2026,7 +1469,7 @@ int intel_enable_engine_stats(struct intel_engine_cs *engine)
2026 return -ENODEV; 1469 return -ENODEV;
2027 1470
2028 tasklet_disable(&execlists->tasklet); 1471 tasklet_disable(&execlists->tasklet);
2029 spin_lock_irqsave(&engine->stats.lock, flags); 1472 write_seqlock_irqsave(&engine->stats.lock, flags);
2030 1473
2031 if (unlikely(engine->stats.enabled == ~0)) { 1474 if (unlikely(engine->stats.enabled == ~0)) {
2032 err = -EBUSY; 1475 err = -EBUSY;
@@ -2050,7 +1493,7 @@ int intel_enable_engine_stats(struct intel_engine_cs *engine)
2050 } 1493 }
2051 1494
2052unlock: 1495unlock:
2053 spin_unlock_irqrestore(&engine->stats.lock, flags); 1496 write_sequnlock_irqrestore(&engine->stats.lock, flags);
2054 tasklet_enable(&execlists->tasklet); 1497 tasklet_enable(&execlists->tasklet);
2055 1498
2056 return err; 1499 return err;
@@ -2079,12 +1522,13 @@ static ktime_t __intel_engine_get_busy_time(struct intel_engine_cs *engine)
2079 */ 1522 */
2080ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine) 1523ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine)
2081{ 1524{
1525 unsigned int seq;
2082 ktime_t total; 1526 ktime_t total;
2083 unsigned long flags;
2084 1527
2085 spin_lock_irqsave(&engine->stats.lock, flags); 1528 do {
2086 total = __intel_engine_get_busy_time(engine); 1529 seq = read_seqbegin(&engine->stats.lock);
2087 spin_unlock_irqrestore(&engine->stats.lock, flags); 1530 total = __intel_engine_get_busy_time(engine);
1531 } while (read_seqretry(&engine->stats.lock, seq));
2088 1532
2089 return total; 1533 return total;
2090} 1534}
@@ -2102,15 +1546,16 @@ void intel_disable_engine_stats(struct intel_engine_cs *engine)
2102 if (!intel_engine_supports_stats(engine)) 1546 if (!intel_engine_supports_stats(engine))
2103 return; 1547 return;
2104 1548
2105 spin_lock_irqsave(&engine->stats.lock, flags); 1549 write_seqlock_irqsave(&engine->stats.lock, flags);
2106 WARN_ON_ONCE(engine->stats.enabled == 0); 1550 WARN_ON_ONCE(engine->stats.enabled == 0);
2107 if (--engine->stats.enabled == 0) { 1551 if (--engine->stats.enabled == 0) {
2108 engine->stats.total = __intel_engine_get_busy_time(engine); 1552 engine->stats.total = __intel_engine_get_busy_time(engine);
2109 engine->stats.active = 0; 1553 engine->stats.active = 0;
2110 } 1554 }
2111 spin_unlock_irqrestore(&engine->stats.lock, flags); 1555 write_sequnlock_irqrestore(&engine->stats.lock, flags);
2112} 1556}
2113 1557
2114#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 1558#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
2115#include "selftests/mock_engine.c" 1559#include "selftests/mock_engine.c"
1560#include "selftests/intel_engine_cs.c"
2116#endif 1561#endif
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 707d49c12638..b431b6733cc1 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -1272,6 +1272,34 @@ out:
1272 mutex_unlock(&fbc->lock); 1272 mutex_unlock(&fbc->lock);
1273} 1273}
1274 1274
1275/*
1276 * intel_fbc_reset_underrun - reset FBC fifo underrun status.
1277 * @dev_priv: i915 device instance
1278 *
1279 * See intel_fbc_handle_fifo_underrun_irq(). For automated testing we
1280 * want to re-enable FBC after an underrun to increase test coverage.
1281 */
1282int intel_fbc_reset_underrun(struct drm_i915_private *dev_priv)
1283{
1284 int ret;
1285
1286 cancel_work_sync(&dev_priv->fbc.underrun_work);
1287
1288 ret = mutex_lock_interruptible(&dev_priv->fbc.lock);
1289 if (ret)
1290 return ret;
1291
1292 if (dev_priv->fbc.underrun_detected) {
1293 DRM_DEBUG_KMS("Re-allowing FBC after fifo underrun\n");
1294 dev_priv->fbc.no_fbc_reason = "FIFO underrun cleared";
1295 }
1296
1297 dev_priv->fbc.underrun_detected = false;
1298 mutex_unlock(&dev_priv->fbc.lock);
1299
1300 return 0;
1301}
1302
1275/** 1303/**
1276 * intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun 1304 * intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun
1277 * @dev_priv: i915 device instance 1305 * @dev_priv: i915 device instance
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 6467a5cc2ca3..e9e02b58b7be 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -221,6 +221,9 @@ static int intelfb_create(struct drm_fb_helper *helper,
221 goto out_unlock; 221 goto out_unlock;
222 } 222 }
223 223
224 fb = &ifbdev->fb->base;
225 intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_DIRTYFB);
226
224 info = drm_fb_helper_alloc_fbi(helper); 227 info = drm_fb_helper_alloc_fbi(helper);
225 if (IS_ERR(info)) { 228 if (IS_ERR(info)) {
226 DRM_ERROR("Failed to allocate fb_info\n"); 229 DRM_ERROR("Failed to allocate fb_info\n");
@@ -230,8 +233,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
230 233
231 info->par = helper; 234 info->par = helper;
232 235
233 fb = &ifbdev->fb->base;
234
235 ifbdev->helper.fb = fb; 236 ifbdev->helper.fb = fb;
236 237
237 strcpy(info->fix.id, "inteldrmfb"); 238 strcpy(info->fix.id, "inteldrmfb");
@@ -640,7 +641,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
640 if (!crtc->state->active) 641 if (!crtc->state->active)
641 continue; 642 continue;
642 643
643 WARN(!crtc->primary->fb, 644 WARN(!crtc->primary->state->fb,
644 "re-used BIOS config but lost an fb on crtc %d\n", 645 "re-used BIOS config but lost an fb on crtc %d\n",
645 crtc->base.id); 646 crtc->base.id);
646 } 647 }
diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c
index 3a8d3d06c26a..7fff0a0eceb4 100644
--- a/drivers/gpu/drm/i915/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/intel_frontbuffer.c
@@ -80,7 +80,7 @@ void __intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
80 } 80 }
81 81
82 might_sleep(); 82 might_sleep();
83 intel_psr_invalidate(dev_priv, frontbuffer_bits); 83 intel_psr_invalidate(dev_priv, frontbuffer_bits, origin);
84 intel_edp_drrs_invalidate(dev_priv, frontbuffer_bits); 84 intel_edp_drrs_invalidate(dev_priv, frontbuffer_bits);
85 intel_fbc_invalidate(dev_priv, frontbuffer_bits, origin); 85 intel_fbc_invalidate(dev_priv, frontbuffer_bits, origin);
86} 86}
diff --git a/drivers/gpu/drm/i915/intel_gpu_commands.h b/drivers/gpu/drm/i915/intel_gpu_commands.h
new file mode 100644
index 000000000000..105e2a9e874a
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_gpu_commands.h
@@ -0,0 +1,274 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright � 2003-2018 Intel Corporation
5 */
6
7#ifndef _INTEL_GPU_COMMANDS_H_
8#define _INTEL_GPU_COMMANDS_H_
9
10/*
11 * Instruction field definitions used by the command parser
12 */
13#define INSTR_CLIENT_SHIFT 29
14#define INSTR_MI_CLIENT 0x0
15#define INSTR_BC_CLIENT 0x2
16#define INSTR_RC_CLIENT 0x3
17#define INSTR_SUBCLIENT_SHIFT 27
18#define INSTR_SUBCLIENT_MASK 0x18000000
19#define INSTR_MEDIA_SUBCLIENT 0x2
20#define INSTR_26_TO_24_MASK 0x7000000
21#define INSTR_26_TO_24_SHIFT 24
22
23/*
24 * Memory interface instructions used by the kernel
25 */
26#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
27/* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */
28#define MI_GLOBAL_GTT (1<<22)
29
30#define MI_NOOP MI_INSTR(0, 0)
31#define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
32#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0)
33#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16)
34#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
35#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
36#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
37#define MI_FLUSH MI_INSTR(0x04, 0)
38#define MI_READ_FLUSH (1 << 0)
39#define MI_EXE_FLUSH (1 << 1)
40#define MI_NO_WRITE_FLUSH (1 << 2)
41#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
42#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
43#define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */
44#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
45#define MI_ARB_ON_OFF MI_INSTR(0x08, 0)
46#define MI_ARB_ENABLE (1<<0)
47#define MI_ARB_DISABLE (0<<0)
48#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
49#define MI_SUSPEND_FLUSH MI_INSTR(0x0b, 0)
50#define MI_SUSPEND_FLUSH_EN (1<<0)
51#define MI_SET_APPID MI_INSTR(0x0e, 0)
52#define MI_OVERLAY_FLIP MI_INSTR(0x11, 0)
53#define MI_OVERLAY_CONTINUE (0x0<<21)
54#define MI_OVERLAY_ON (0x1<<21)
55#define MI_OVERLAY_OFF (0x2<<21)
56#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
57#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
58#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1)
59#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
60/* IVB has funny definitions for which plane to flip. */
61#define MI_DISPLAY_FLIP_IVB_PLANE_A (0 << 19)
62#define MI_DISPLAY_FLIP_IVB_PLANE_B (1 << 19)
63#define MI_DISPLAY_FLIP_IVB_SPRITE_A (2 << 19)
64#define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
65#define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19)
66#define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
67/* SKL ones */
68#define MI_DISPLAY_FLIP_SKL_PLANE_1_A (0 << 8)
69#define MI_DISPLAY_FLIP_SKL_PLANE_1_B (1 << 8)
70#define MI_DISPLAY_FLIP_SKL_PLANE_1_C (2 << 8)
71#define MI_DISPLAY_FLIP_SKL_PLANE_2_A (4 << 8)
72#define MI_DISPLAY_FLIP_SKL_PLANE_2_B (5 << 8)
73#define MI_DISPLAY_FLIP_SKL_PLANE_2_C (6 << 8)
74#define MI_DISPLAY_FLIP_SKL_PLANE_3_A (7 << 8)
75#define MI_DISPLAY_FLIP_SKL_PLANE_3_B (8 << 8)
76#define MI_DISPLAY_FLIP_SKL_PLANE_3_C (9 << 8)
77#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6, gen7 */
78#define MI_SEMAPHORE_GLOBAL_GTT (1<<22)
79#define MI_SEMAPHORE_UPDATE (1<<21)
80#define MI_SEMAPHORE_COMPARE (1<<20)
81#define MI_SEMAPHORE_REGISTER (1<<18)
82#define MI_SEMAPHORE_SYNC_VR (0<<16) /* RCS wait for VCS (RVSYNC) */
83#define MI_SEMAPHORE_SYNC_VER (1<<16) /* RCS wait for VECS (RVESYNC) */
84#define MI_SEMAPHORE_SYNC_BR (2<<16) /* RCS wait for BCS (RBSYNC) */
85#define MI_SEMAPHORE_SYNC_BV (0<<16) /* VCS wait for BCS (VBSYNC) */
86#define MI_SEMAPHORE_SYNC_VEV (1<<16) /* VCS wait for VECS (VVESYNC) */
87#define MI_SEMAPHORE_SYNC_RV (2<<16) /* VCS wait for RCS (VRSYNC) */
88#define MI_SEMAPHORE_SYNC_RB (0<<16) /* BCS wait for RCS (BRSYNC) */
89#define MI_SEMAPHORE_SYNC_VEB (1<<16) /* BCS wait for VECS (BVESYNC) */
90#define MI_SEMAPHORE_SYNC_VB (2<<16) /* BCS wait for VCS (BVSYNC) */
91#define MI_SEMAPHORE_SYNC_BVE (0<<16) /* VECS wait for BCS (VEBSYNC) */
92#define MI_SEMAPHORE_SYNC_VVE (1<<16) /* VECS wait for VCS (VEVSYNC) */
93#define MI_SEMAPHORE_SYNC_RVE (2<<16) /* VECS wait for RCS (VERSYNC) */
94#define MI_SEMAPHORE_SYNC_INVALID (3<<16)
95#define MI_SEMAPHORE_SYNC_MASK (3<<16)
96#define MI_SET_CONTEXT MI_INSTR(0x18, 0)
97#define MI_MM_SPACE_GTT (1<<8)
98#define MI_MM_SPACE_PHYSICAL (0<<8)
99#define MI_SAVE_EXT_STATE_EN (1<<3)
100#define MI_RESTORE_EXT_STATE_EN (1<<2)
101#define MI_FORCE_RESTORE (1<<1)
102#define MI_RESTORE_INHIBIT (1<<0)
103#define HSW_MI_RS_SAVE_STATE_EN (1<<3)
104#define HSW_MI_RS_RESTORE_STATE_EN (1<<2)
105#define MI_SEMAPHORE_SIGNAL MI_INSTR(0x1b, 0) /* GEN8+ */
106#define MI_SEMAPHORE_TARGET(engine) ((engine)<<15)
107#define MI_SEMAPHORE_WAIT MI_INSTR(0x1c, 2) /* GEN8+ */
108#define MI_SEMAPHORE_POLL (1<<15)
109#define MI_SEMAPHORE_SAD_GTE_SDD (1<<12)
110#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
111#define MI_STORE_DWORD_IMM_GEN4 MI_INSTR(0x20, 2)
112#define MI_MEM_VIRTUAL (1 << 22) /* 945,g33,965 */
113#define MI_USE_GGTT (1 << 22) /* g4x+ */
114#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
115#define MI_STORE_DWORD_INDEX_SHIFT 2
116/*
117 * Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM:
118 * - Always issue a MI_NOOP _before_ the MI_LOAD_REGISTER_IMM - otherwise hw
119 * simply ignores the register load under certain conditions.
120 * - One can actually load arbitrary many arbitrary registers: Simply issue x
121 * address/value pairs. Don't overdue it, though, x <= 2^4 must hold!
122 */
123#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*(x)-1)
124#define MI_LRI_FORCE_POSTED (1<<12)
125#define MI_STORE_REGISTER_MEM MI_INSTR(0x24, 1)
126#define MI_STORE_REGISTER_MEM_GEN8 MI_INSTR(0x24, 2)
127#define MI_SRM_LRM_GLOBAL_GTT (1<<22)
128#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */
129#define MI_FLUSH_DW_STORE_INDEX (1<<21)
130#define MI_INVALIDATE_TLB (1<<18)
131#define MI_FLUSH_DW_OP_STOREDW (1<<14)
132#define MI_FLUSH_DW_OP_MASK (3<<14)
133#define MI_FLUSH_DW_NOTIFY (1<<8)
134#define MI_INVALIDATE_BSD (1<<7)
135#define MI_FLUSH_DW_USE_GTT (1<<2)
136#define MI_FLUSH_DW_USE_PPGTT (0<<2)
137#define MI_LOAD_REGISTER_MEM MI_INSTR(0x29, 1)
138#define MI_LOAD_REGISTER_MEM_GEN8 MI_INSTR(0x29, 2)
139#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
140#define MI_BATCH_NON_SECURE (1)
141/* for snb/ivb/vlv this also means "batch in ppgtt" when ppgtt is enabled. */
142#define MI_BATCH_NON_SECURE_I965 (1<<8)
143#define MI_BATCH_PPGTT_HSW (1<<8)
144#define MI_BATCH_NON_SECURE_HSW (1<<13)
145#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
146#define MI_BATCH_GTT (2<<6) /* aliased with (1<<7) on gen4 */
147#define MI_BATCH_BUFFER_START_GEN8 MI_INSTR(0x31, 1)
148#define MI_BATCH_RESOURCE_STREAMER (1<<10)
149
150/*
151 * 3D instructions used by the kernel
152 */
153#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
154
155#define GEN9_MEDIA_POOL_STATE ((0x3 << 29) | (0x2 << 27) | (0x5 << 16) | 4)
156#define GEN9_MEDIA_POOL_ENABLE (1 << 31)
157#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
158#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
159#define SC_UPDATE_SCISSOR (0x1<<1)
160#define SC_ENABLE_MASK (0x1<<0)
161#define SC_ENABLE (0x1<<0)
162#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
163#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
164#define SCI_YMIN_MASK (0xffff<<16)
165#define SCI_XMIN_MASK (0xffff<<0)
166#define SCI_YMAX_MASK (0xffff<<16)
167#define SCI_XMAX_MASK (0xffff<<0)
168#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
169#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
170#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
171#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
172#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
173#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
174#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
175#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
176#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
177
178#define COLOR_BLT_CMD (2<<29 | 0x40<<22 | (5-2))
179#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
180#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
181#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5)
182#define BLT_WRITE_A (2<<20)
183#define BLT_WRITE_RGB (1<<20)
184#define BLT_WRITE_RGBA (BLT_WRITE_RGB | BLT_WRITE_A)
185#define BLT_DEPTH_8 (0<<24)
186#define BLT_DEPTH_16_565 (1<<24)
187#define BLT_DEPTH_16_1555 (2<<24)
188#define BLT_DEPTH_32 (3<<24)
189#define BLT_ROP_SRC_COPY (0xcc<<16)
190#define BLT_ROP_COLOR_COPY (0xf0<<16)
191#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */
192#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */
193#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
194#define ASYNC_FLIP (1<<22)
195#define DISPLAY_PLANE_A (0<<20)
196#define DISPLAY_PLANE_B (1<<20)
197#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|((len)-2))
198#define PIPE_CONTROL_FLUSH_L3 (1<<27)
199#define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */
200#define PIPE_CONTROL_MMIO_WRITE (1<<23)
201#define PIPE_CONTROL_STORE_DATA_INDEX (1<<21)
202#define PIPE_CONTROL_CS_STALL (1<<20)
203#define PIPE_CONTROL_TLB_INVALIDATE (1<<18)
204#define PIPE_CONTROL_MEDIA_STATE_CLEAR (1<<16)
205#define PIPE_CONTROL_QW_WRITE (1<<14)
206#define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14)
207#define PIPE_CONTROL_DEPTH_STALL (1<<13)
208#define PIPE_CONTROL_WRITE_FLUSH (1<<12)
209#define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */
210#define PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE (1<<11) /* MBZ on ILK */
211#define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */
212#define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9)
213#define PIPE_CONTROL_NOTIFY (1<<8)
214#define PIPE_CONTROL_FLUSH_ENABLE (1<<7) /* gen7+ */
215#define PIPE_CONTROL_DC_FLUSH_ENABLE (1<<5)
216#define PIPE_CONTROL_VF_CACHE_INVALIDATE (1<<4)
217#define PIPE_CONTROL_CONST_CACHE_INVALIDATE (1<<3)
218#define PIPE_CONTROL_STATE_CACHE_INVALIDATE (1<<2)
219#define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1)
220#define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0)
221#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
222
223/*
224 * Commands used only by the command parser
225 */
226#define MI_SET_PREDICATE MI_INSTR(0x01, 0)
227#define MI_ARB_CHECK MI_INSTR(0x05, 0)
228#define MI_RS_CONTROL MI_INSTR(0x06, 0)
229#define MI_URB_ATOMIC_ALLOC MI_INSTR(0x09, 0)
230#define MI_PREDICATE MI_INSTR(0x0C, 0)
231#define MI_RS_CONTEXT MI_INSTR(0x0F, 0)
232#define MI_TOPOLOGY_FILTER MI_INSTR(0x0D, 0)
233#define MI_LOAD_SCAN_LINES_EXCL MI_INSTR(0x13, 0)
234#define MI_URB_CLEAR MI_INSTR(0x19, 0)
235#define MI_UPDATE_GTT MI_INSTR(0x23, 0)
236#define MI_CLFLUSH MI_INSTR(0x27, 0)
237#define MI_REPORT_PERF_COUNT MI_INSTR(0x28, 0)
238#define MI_REPORT_PERF_COUNT_GGTT (1<<0)
239#define MI_LOAD_REGISTER_REG MI_INSTR(0x2A, 0)
240#define MI_RS_STORE_DATA_IMM MI_INSTR(0x2B, 0)
241#define MI_LOAD_URB_MEM MI_INSTR(0x2C, 0)
242#define MI_STORE_URB_MEM MI_INSTR(0x2D, 0)
243#define MI_CONDITIONAL_BATCH_BUFFER_END MI_INSTR(0x36, 0)
244
245#define PIPELINE_SELECT ((0x3<<29)|(0x1<<27)|(0x1<<24)|(0x4<<16))
246#define GFX_OP_3DSTATE_VF_STATISTICS ((0x3<<29)|(0x1<<27)|(0x0<<24)|(0xB<<16))
247#define MEDIA_VFE_STATE ((0x3<<29)|(0x2<<27)|(0x0<<24)|(0x0<<16))
248#define MEDIA_VFE_STATE_MMIO_ACCESS_MASK (0x18)
249#define GPGPU_OBJECT ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x4<<16))
250#define GPGPU_WALKER ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x5<<16))
251#define GFX_OP_3DSTATE_DX9_CONSTANTF_VS \
252 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x39<<16))
253#define GFX_OP_3DSTATE_DX9_CONSTANTF_PS \
254 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x3A<<16))
255#define GFX_OP_3DSTATE_SO_DECL_LIST \
256 ((0x3<<29)|(0x3<<27)|(0x1<<24)|(0x17<<16))
257
258#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_VS \
259 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x43<<16))
260#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_GS \
261 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x44<<16))
262#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_HS \
263 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x45<<16))
264#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_DS \
265 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x46<<16))
266#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS \
267 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x47<<16))
268
269#define MFX_WAIT ((0x3<<29)|(0x1<<27)|(0x0<<16))
270
271#define COLOR_BLT ((0x2<<29)|(0x40<<22))
272#define SRC_COPY_BLT ((0x2<<29)|(0x43<<22))
273
274#endif /* _INTEL_GPU_COMMANDS_H_ */
diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index ff08ea0ebf49..116f4ccf1bbd 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -64,10 +64,12 @@ void intel_guc_init_early(struct intel_guc *guc)
64{ 64{
65 intel_guc_fw_init_early(guc); 65 intel_guc_fw_init_early(guc);
66 intel_guc_ct_init_early(&guc->ct); 66 intel_guc_ct_init_early(&guc->ct);
67 intel_guc_log_init_early(guc); 67 intel_guc_log_init_early(&guc->log);
68 68
69 mutex_init(&guc->send_mutex); 69 mutex_init(&guc->send_mutex);
70 spin_lock_init(&guc->irq_lock);
70 guc->send = intel_guc_send_nop; 71 guc->send = intel_guc_send_nop;
72 guc->handler = intel_guc_to_host_event_handler_nop;
71 guc->notify = gen8_guc_raise_irq; 73 guc->notify = gen8_guc_raise_irq;
72} 74}
73 75
@@ -86,9 +88,10 @@ int intel_guc_init_wq(struct intel_guc *guc)
86 * or scheduled later on resume. This way the handling of work 88 * or scheduled later on resume. This way the handling of work
87 * item can be kept same between system suspend & rpm suspend. 89 * item can be kept same between system suspend & rpm suspend.
88 */ 90 */
89 guc->log.runtime.flush_wq = alloc_ordered_workqueue("i915-guc_log", 91 guc->log.relay.flush_wq =
90 WQ_HIGHPRI | WQ_FREEZABLE); 92 alloc_ordered_workqueue("i915-guc_log",
91 if (!guc->log.runtime.flush_wq) { 93 WQ_HIGHPRI | WQ_FREEZABLE);
94 if (!guc->log.relay.flush_wq) {
92 DRM_ERROR("Couldn't allocate workqueue for GuC log\n"); 95 DRM_ERROR("Couldn't allocate workqueue for GuC log\n");
93 return -ENOMEM; 96 return -ENOMEM;
94 } 97 }
@@ -111,7 +114,7 @@ int intel_guc_init_wq(struct intel_guc *guc)
111 guc->preempt_wq = alloc_ordered_workqueue("i915-guc_preempt", 114 guc->preempt_wq = alloc_ordered_workqueue("i915-guc_preempt",
112 WQ_HIGHPRI); 115 WQ_HIGHPRI);
113 if (!guc->preempt_wq) { 116 if (!guc->preempt_wq) {
114 destroy_workqueue(guc->log.runtime.flush_wq); 117 destroy_workqueue(guc->log.relay.flush_wq);
115 DRM_ERROR("Couldn't allocate workqueue for GuC " 118 DRM_ERROR("Couldn't allocate workqueue for GuC "
116 "preemption\n"); 119 "preemption\n");
117 return -ENOMEM; 120 return -ENOMEM;
@@ -129,7 +132,7 @@ void intel_guc_fini_wq(struct intel_guc *guc)
129 USES_GUC_SUBMISSION(dev_priv)) 132 USES_GUC_SUBMISSION(dev_priv))
130 destroy_workqueue(guc->preempt_wq); 133 destroy_workqueue(guc->preempt_wq);
131 134
132 destroy_workqueue(guc->log.runtime.flush_wq); 135 destroy_workqueue(guc->log.relay.flush_wq);
133} 136}
134 137
135static int guc_shared_data_create(struct intel_guc *guc) 138static int guc_shared_data_create(struct intel_guc *guc)
@@ -169,7 +172,7 @@ int intel_guc_init(struct intel_guc *guc)
169 return ret; 172 return ret;
170 GEM_BUG_ON(!guc->shared_data); 173 GEM_BUG_ON(!guc->shared_data);
171 174
172 ret = intel_guc_log_create(guc); 175 ret = intel_guc_log_create(&guc->log);
173 if (ret) 176 if (ret)
174 goto err_shared; 177 goto err_shared;
175 178
@@ -184,7 +187,7 @@ int intel_guc_init(struct intel_guc *guc)
184 return 0; 187 return 0;
185 188
186err_log: 189err_log:
187 intel_guc_log_destroy(guc); 190 intel_guc_log_destroy(&guc->log);
188err_shared: 191err_shared:
189 guc_shared_data_destroy(guc); 192 guc_shared_data_destroy(guc);
190 return ret; 193 return ret;
@@ -196,41 +199,27 @@ void intel_guc_fini(struct intel_guc *guc)
196 199
197 i915_ggtt_disable_guc(dev_priv); 200 i915_ggtt_disable_guc(dev_priv);
198 intel_guc_ads_destroy(guc); 201 intel_guc_ads_destroy(guc);
199 intel_guc_log_destroy(guc); 202 intel_guc_log_destroy(&guc->log);
200 guc_shared_data_destroy(guc); 203 guc_shared_data_destroy(guc);
201} 204}
202 205
203static u32 get_gt_type(struct drm_i915_private *dev_priv) 206static u32 get_log_control_flags(void)
204{ 207{
205 /* XXX: GT type based on PCI device ID? field seems unused by fw */ 208 u32 level = i915_modparams.guc_log_level;
206 return 0; 209 u32 flags = 0;
207}
208
209static u32 get_core_family(struct drm_i915_private *dev_priv)
210{
211 u32 gen = INTEL_GEN(dev_priv);
212 210
213 switch (gen) { 211 GEM_BUG_ON(level < 0);
214 case 9:
215 return GUC_CORE_FAMILY_GEN9;
216
217 default:
218 MISSING_CASE(gen);
219 return GUC_CORE_FAMILY_UNKNOWN;
220 }
221}
222 212
223static u32 get_log_verbosity_flags(void) 213 if (!GUC_LOG_LEVEL_IS_ENABLED(level))
224{ 214 flags |= GUC_LOG_DEFAULT_DISABLED;
225 if (i915_modparams.guc_log_level > 0) {
226 u32 verbosity = i915_modparams.guc_log_level - 1;
227 215
228 GEM_BUG_ON(verbosity > GUC_LOG_VERBOSITY_MAX); 216 if (!GUC_LOG_LEVEL_IS_VERBOSE(level))
229 return verbosity << GUC_LOG_VERBOSITY_SHIFT; 217 flags |= GUC_LOG_DISABLED;
230 } 218 else
219 flags |= GUC_LOG_LEVEL_TO_VERBOSITY(level) <<
220 GUC_LOG_VERBOSITY_SHIFT;
231 221
232 GEM_BUG_ON(i915_modparams.enable_guc < 0); 222 return flags;
233 return GUC_LOG_DISABLED;
234} 223}
235 224
236/* 225/*
@@ -246,10 +235,6 @@ void intel_guc_init_params(struct intel_guc *guc)
246 235
247 memset(params, 0, sizeof(params)); 236 memset(params, 0, sizeof(params));
248 237
249 params[GUC_CTL_DEVICE_INFO] |=
250 (get_gt_type(dev_priv) << GUC_CTL_GT_TYPE_SHIFT) |
251 (get_core_family(dev_priv) << GUC_CTL_CORE_FAMILY_SHIFT);
252
253 /* 238 /*
254 * GuC ARAT increment is 10 ns. GuC default scheduler quantum is one 239 * GuC ARAT increment is 10 ns. GuC default scheduler quantum is one
255 * second. This ARAR is calculated by: 240 * second. This ARAR is calculated by:
@@ -265,12 +250,13 @@ void intel_guc_init_params(struct intel_guc *guc)
265 250
266 params[GUC_CTL_LOG_PARAMS] = guc->log.flags; 251 params[GUC_CTL_LOG_PARAMS] = guc->log.flags;
267 252
268 params[GUC_CTL_DEBUG] = get_log_verbosity_flags(); 253 params[GUC_CTL_DEBUG] = get_log_control_flags();
269 254
270 /* If GuC submission is enabled, set up additional parameters here */ 255 /* If GuC submission is enabled, set up additional parameters here */
271 if (USES_GUC_SUBMISSION(dev_priv)) { 256 if (USES_GUC_SUBMISSION(dev_priv)) {
272 u32 ads = guc_ggtt_offset(guc->ads_vma) >> PAGE_SHIFT; 257 u32 ads = intel_guc_ggtt_offset(guc,
273 u32 pgs = guc_ggtt_offset(dev_priv->guc.stage_desc_pool); 258 guc->ads_vma) >> PAGE_SHIFT;
259 u32 pgs = intel_guc_ggtt_offset(guc, guc->stage_desc_pool);
274 u32 ctx_in_16 = GUC_MAX_STAGE_DESCRIPTORS / 16; 260 u32 ctx_in_16 = GUC_MAX_STAGE_DESCRIPTORS / 16;
275 261
276 params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT; 262 params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT;
@@ -301,16 +287,23 @@ void intel_guc_init_params(struct intel_guc *guc)
301 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_BLITTER); 287 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_BLITTER);
302} 288}
303 289
304int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len) 290int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len,
291 u32 *response_buf, u32 response_buf_size)
305{ 292{
306 WARN(1, "Unexpected send: action=%#x\n", *action); 293 WARN(1, "Unexpected send: action=%#x\n", *action);
307 return -ENODEV; 294 return -ENODEV;
308} 295}
309 296
297void intel_guc_to_host_event_handler_nop(struct intel_guc *guc)
298{
299 WARN(1, "Unexpected event: no suitable handler\n");
300}
301
310/* 302/*
311 * This function implements the MMIO based host to GuC interface. 303 * This function implements the MMIO based host to GuC interface.
312 */ 304 */
313int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len) 305int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len,
306 u32 *response_buf, u32 response_buf_size)
314{ 307{
315 struct drm_i915_private *dev_priv = guc_to_i915(guc); 308 struct drm_i915_private *dev_priv = guc_to_i915(guc);
316 u32 status; 309 u32 status;
@@ -320,6 +313,9 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len)
320 GEM_BUG_ON(!len); 313 GEM_BUG_ON(!len);
321 GEM_BUG_ON(len > guc->send_regs.count); 314 GEM_BUG_ON(len > guc->send_regs.count);
322 315
316 /* We expect only action code */
317 GEM_BUG_ON(*action & ~INTEL_GUC_MSG_CODE_MASK);
318
323 /* If CT is available, we expect to use MMIO only during init/fini */ 319 /* If CT is available, we expect to use MMIO only during init/fini */
324 GEM_BUG_ON(HAS_GUC_CT(dev_priv) && 320 GEM_BUG_ON(HAS_GUC_CT(dev_priv) &&
325 *action != INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER && 321 *action != INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER &&
@@ -341,29 +337,74 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len)
341 */ 337 */
342 ret = __intel_wait_for_register_fw(dev_priv, 338 ret = __intel_wait_for_register_fw(dev_priv,
343 guc_send_reg(guc, 0), 339 guc_send_reg(guc, 0),
344 INTEL_GUC_RECV_MASK, 340 INTEL_GUC_MSG_TYPE_MASK,
345 INTEL_GUC_RECV_MASK, 341 INTEL_GUC_MSG_TYPE_RESPONSE <<
342 INTEL_GUC_MSG_TYPE_SHIFT,
346 10, 10, &status); 343 10, 10, &status);
347 if (status != INTEL_GUC_STATUS_SUCCESS) { 344 /* If GuC explicitly returned an error, convert it to -EIO */
348 /* 345 if (!ret && !INTEL_GUC_MSG_IS_RESPONSE_SUCCESS(status))
349 * Either the GuC explicitly returned an error (which 346 ret = -EIO;
350 * we convert to -EIO here) or no response at all was 347
351 * received within the timeout limit (-ETIMEDOUT) 348 if (ret) {
352 */ 349 DRM_DEBUG_DRIVER("INTEL_GUC_SEND: Action 0x%X failed;"
353 if (ret != -ETIMEDOUT) 350 " ret=%d status=0x%08X response=0x%08X\n",
354 ret = -EIO; 351 action[0], ret, status,
355 352 I915_READ(SOFT_SCRATCH(15)));
356 DRM_WARN("INTEL_GUC_SEND: Action 0x%X failed;" 353 goto out;
357 " ret=%d status=0x%08X response=0x%08X\n",
358 action[0], ret, status, I915_READ(SOFT_SCRATCH(15)));
359 } 354 }
360 355
356 if (response_buf) {
357 int count = min(response_buf_size, guc->send_regs.count - 1);
358
359 for (i = 0; i < count; i++)
360 response_buf[i] = I915_READ(guc_send_reg(guc, i + 1));
361 }
362
363 /* Use data from the GuC response as our return value */
364 ret = INTEL_GUC_MSG_TO_DATA(status);
365
366out:
361 intel_uncore_forcewake_put(dev_priv, guc->send_regs.fw_domains); 367 intel_uncore_forcewake_put(dev_priv, guc->send_regs.fw_domains);
362 mutex_unlock(&guc->send_mutex); 368 mutex_unlock(&guc->send_mutex);
363 369
364 return ret; 370 return ret;
365} 371}
366 372
373void intel_guc_to_host_event_handler_mmio(struct intel_guc *guc)
374{
375 struct drm_i915_private *dev_priv = guc_to_i915(guc);
376 u32 msg, val;
377
378 /*
379 * Sample the log buffer flush related bits & clear them out now
380 * itself from the message identity register to minimize the
381 * probability of losing a flush interrupt, when there are back
382 * to back flush interrupts.
383 * There can be a new flush interrupt, for different log buffer
384 * type (like for ISR), whilst Host is handling one (for DPC).
385 * Since same bit is used in message register for ISR & DPC, it
386 * could happen that GuC sets the bit for 2nd interrupt but Host
387 * clears out the bit on handling the 1st interrupt.
388 */
389 spin_lock(&guc->irq_lock);
390 val = I915_READ(SOFT_SCRATCH(15));
391 msg = val & guc->msg_enabled_mask;
392 I915_WRITE(SOFT_SCRATCH(15), val & ~msg);
393 spin_unlock(&guc->irq_lock);
394
395 intel_guc_to_host_process_recv_msg(guc, msg);
396}
397
398void intel_guc_to_host_process_recv_msg(struct intel_guc *guc, u32 msg)
399{
400 /* Make sure to handle only enabled messages */
401 msg &= guc->msg_enabled_mask;
402
403 if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
404 INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED))
405 intel_guc_log_handle_flush_event(&guc->log);
406}
407
367int intel_guc_sample_forcewake(struct intel_guc *guc) 408int intel_guc_sample_forcewake(struct intel_guc *guc)
368{ 409{
369 struct drm_i915_private *dev_priv = guc_to_i915(guc); 410 struct drm_i915_private *dev_priv = guc_to_i915(guc);
@@ -410,7 +451,7 @@ int intel_guc_suspend(struct intel_guc *guc)
410 u32 data[] = { 451 u32 data[] = {
411 INTEL_GUC_ACTION_ENTER_S_STATE, 452 INTEL_GUC_ACTION_ENTER_S_STATE,
412 GUC_POWER_D1, /* any value greater than GUC_POWER_D0 */ 453 GUC_POWER_D1, /* any value greater than GUC_POWER_D0 */
413 guc_ggtt_offset(guc->shared_data) 454 intel_guc_ggtt_offset(guc, guc->shared_data)
414 }; 455 };
415 456
416 return intel_guc_send(guc, data, ARRAY_SIZE(data)); 457 return intel_guc_send(guc, data, ARRAY_SIZE(data));
@@ -434,7 +475,7 @@ int intel_guc_reset_engine(struct intel_guc *guc,
434 data[3] = 0; 475 data[3] = 0;
435 data[4] = 0; 476 data[4] = 0;
436 data[5] = guc->execbuf_client->stage_id; 477 data[5] = guc->execbuf_client->stage_id;
437 data[6] = guc_ggtt_offset(guc->shared_data); 478 data[6] = intel_guc_ggtt_offset(guc, guc->shared_data);
438 479
439 return intel_guc_send(guc, data, ARRAY_SIZE(data)); 480 return intel_guc_send(guc, data, ARRAY_SIZE(data));
440} 481}
@@ -448,13 +489,66 @@ int intel_guc_resume(struct intel_guc *guc)
448 u32 data[] = { 489 u32 data[] = {
449 INTEL_GUC_ACTION_EXIT_S_STATE, 490 INTEL_GUC_ACTION_EXIT_S_STATE,
450 GUC_POWER_D0, 491 GUC_POWER_D0,
451 guc_ggtt_offset(guc->shared_data) 492 intel_guc_ggtt_offset(guc, guc->shared_data)
452 }; 493 };
453 494
454 return intel_guc_send(guc, data, ARRAY_SIZE(data)); 495 return intel_guc_send(guc, data, ARRAY_SIZE(data));
455} 496}
456 497
457/** 498/**
499 * DOC: GuC Address Space
500 *
501 * The layout of GuC address space is shown below:
502 *
503 * ::
504 *
505 * +==============> +====================+ <== GUC_GGTT_TOP
506 * ^ | |
507 * | | |
508 * | | DRAM |
509 * | | Memory |
510 * | | |
511 * GuC | |
512 * Address +========> +====================+ <== WOPCM Top
513 * Space ^ | HW contexts RSVD |
514 * | | | WOPCM |
515 * | | +==> +--------------------+ <== GuC WOPCM Top
516 * | GuC ^ | |
517 * | GGTT | | |
518 * | Pin GuC | GuC |
519 * | Bias WOPCM | WOPCM |
520 * | | Size | |
521 * | | | | |
522 * v v v | |
523 * +=====+=====+==> +====================+ <== GuC WOPCM Base
524 * | Non-GuC WOPCM |
525 * | (HuC/Reserved) |
526 * +====================+ <== WOPCM Base
527 *
528 * The lower part of GuC Address Space [0, ggtt_pin_bias) is mapped to WOPCM
529 * while upper part of GuC Address Space [ggtt_pin_bias, GUC_GGTT_TOP) is mapped
530 * to DRAM. The value of the GuC ggtt_pin_bias is determined by WOPCM size and
531 * actual GuC WOPCM size.
532 */
533
534/**
535 * intel_guc_init_ggtt_pin_bias() - Initialize the GuC ggtt_pin_bias value.
536 * @guc: intel_guc structure.
537 *
538 * This function will calculate and initialize the ggtt_pin_bias value based on
539 * overall WOPCM size and GuC WOPCM size.
540 */
541void intel_guc_init_ggtt_pin_bias(struct intel_guc *guc)
542{
543 struct drm_i915_private *i915 = guc_to_i915(guc);
544
545 GEM_BUG_ON(!i915->wopcm.size);
546 GEM_BUG_ON(i915->wopcm.size < i915->wopcm.guc.base);
547
548 guc->ggtt_pin_bias = i915->wopcm.size - i915->wopcm.guc.base;
549}
550
551/**
458 * intel_guc_allocate_vma() - Allocate a GGTT VMA for GuC usage 552 * intel_guc_allocate_vma() - Allocate a GGTT VMA for GuC usage
459 * @guc: the guc 553 * @guc: the guc
460 * @size: size of area to allocate (both virtual space and memory) 554 * @size: size of area to allocate (both virtual space and memory)
@@ -462,7 +556,7 @@ int intel_guc_resume(struct intel_guc *guc)
462 * This is a wrapper to create an object for use with the GuC. In order to 556 * This is a wrapper to create an object for use with the GuC. In order to
463 * use it inside the GuC, an object needs to be pinned lifetime, so we allocate 557 * use it inside the GuC, an object needs to be pinned lifetime, so we allocate
464 * both some backing storage and a range inside the Global GTT. We must pin 558 * both some backing storage and a range inside the Global GTT. We must pin
465 * it in the GGTT somewhere other than than [0, GUC_WOPCM_TOP) because that 559 * it in the GGTT somewhere other than than [0, GUC ggtt_pin_bias) because that
466 * range is reserved inside GuC. 560 * range is reserved inside GuC.
467 * 561 *
468 * Return: A i915_vma if successful, otherwise an ERR_PTR. 562 * Return: A i915_vma if successful, otherwise an ERR_PTR.
@@ -483,7 +577,7 @@ struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size)
483 goto err; 577 goto err;
484 578
485 ret = i915_vma_pin(vma, 0, PAGE_SIZE, 579 ret = i915_vma_pin(vma, 0, PAGE_SIZE,
486 PIN_GLOBAL | PIN_OFFSET_BIAS | GUC_WOPCM_TOP); 580 PIN_GLOBAL | PIN_OFFSET_BIAS | guc->ggtt_pin_bias);
487 if (ret) { 581 if (ret) {
488 vma = ERR_PTR(ret); 582 vma = ERR_PTR(ret);
489 goto err; 583 goto err;
@@ -495,14 +589,3 @@ err:
495 i915_gem_object_put(obj); 589 i915_gem_object_put(obj);
496 return vma; 590 return vma;
497} 591}
498
499u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv)
500{
501 u32 wopcm_size = GUC_WOPCM_TOP;
502
503 /* On BXT, the top of WOPCM is reserved for RC6 context */
504 if (IS_GEN9_LP(dev_priv))
505 wopcm_size -= BXT_GUC_WOPCM_RC6_RESERVED;
506
507 return wopcm_size;
508}
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index b9424ac644ac..f1265e122d30 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -49,11 +49,16 @@ struct intel_guc {
49 struct intel_guc_log log; 49 struct intel_guc_log log;
50 struct intel_guc_ct ct; 50 struct intel_guc_ct ct;
51 51
52 /* Offset where Non-WOPCM memory starts. */
53 u32 ggtt_pin_bias;
54
52 /* Log snapshot if GuC errors during load */ 55 /* Log snapshot if GuC errors during load */
53 struct drm_i915_gem_object *load_err_log; 56 struct drm_i915_gem_object *load_err_log;
54 57
55 /* intel_guc_recv interrupt related state */ 58 /* intel_guc_recv interrupt related state */
59 spinlock_t irq_lock;
56 bool interrupts_enabled; 60 bool interrupts_enabled;
61 unsigned int msg_enabled_mask;
57 62
58 struct i915_vma *ads_vma; 63 struct i915_vma *ads_vma;
59 struct i915_vma *stage_desc_pool; 64 struct i915_vma *stage_desc_pool;
@@ -83,7 +88,11 @@ struct intel_guc {
83 struct mutex send_mutex; 88 struct mutex send_mutex;
84 89
85 /* GuC's FW specific send function */ 90 /* GuC's FW specific send function */
86 int (*send)(struct intel_guc *guc, const u32 *data, u32 len); 91 int (*send)(struct intel_guc *guc, const u32 *data, u32 len,
92 u32 *response_buf, u32 response_buf_size);
93
94 /* GuC's FW specific event handler function */
95 void (*handler)(struct intel_guc *guc);
87 96
88 /* GuC's FW specific notify function */ 97 /* GuC's FW specific notify function */
89 void (*notify)(struct intel_guc *guc); 98 void (*notify)(struct intel_guc *guc);
@@ -92,7 +101,14 @@ struct intel_guc {
92static 101static
93inline int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len) 102inline int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len)
94{ 103{
95 return guc->send(guc, action, len); 104 return guc->send(guc, action, len, NULL, 0);
105}
106
107static inline int
108intel_guc_send_and_receive(struct intel_guc *guc, const u32 *action, u32 len,
109 u32 *response_buf, u32 response_buf_size)
110{
111 return guc->send(guc, action, len, response_buf, response_buf_size);
96} 112}
97 113
98static inline void intel_guc_notify(struct intel_guc *guc) 114static inline void intel_guc_notify(struct intel_guc *guc)
@@ -100,17 +116,33 @@ static inline void intel_guc_notify(struct intel_guc *guc)
100 guc->notify(guc); 116 guc->notify(guc);
101} 117}
102 118
103/* 119static inline void intel_guc_to_host_event_handler(struct intel_guc *guc)
104 * GuC does not allow any gfx GGTT address that falls into range [0, WOPCM_TOP), 120{
105 * which is reserved for Boot ROM, SRAM and WOPCM. Currently this top address is 121 guc->handler(guc);
106 * 512K. In order to exclude 0-512K address space from GGTT, all gfx objects 122}
107 * used by GuC is pinned with PIN_OFFSET_BIAS along with size of WOPCM. 123
124/* GuC addresses above GUC_GGTT_TOP also don't map through the GTT */
125#define GUC_GGTT_TOP 0xFEE00000
126
127/**
128 * intel_guc_ggtt_offset() - Get and validate the GGTT offset of @vma
129 * @guc: intel_guc structure.
130 * @vma: i915 graphics virtual memory area.
131 *
132 * GuC does not allow any gfx GGTT address that falls into range
133 * [0, GuC ggtt_pin_bias), which is reserved for Boot ROM, SRAM and WOPCM.
134 * Currently, in order to exclude [0, GuC ggtt_pin_bias) address space from
135 * GGTT, all gfx objects used by GuC are allocated with intel_guc_allocate_vma()
136 * and pinned with PIN_OFFSET_BIAS along with the value of GuC ggtt_pin_bias.
137 *
138 * Return: GGTT offset of the @vma.
108 */ 139 */
109static inline u32 guc_ggtt_offset(struct i915_vma *vma) 140static inline u32 intel_guc_ggtt_offset(struct intel_guc *guc,
141 struct i915_vma *vma)
110{ 142{
111 u32 offset = i915_ggtt_offset(vma); 143 u32 offset = i915_ggtt_offset(vma);
112 144
113 GEM_BUG_ON(offset < GUC_WOPCM_TOP); 145 GEM_BUG_ON(offset < guc->ggtt_pin_bias);
114 GEM_BUG_ON(range_overflows_t(u64, offset, vma->size, GUC_GGTT_TOP)); 146 GEM_BUG_ON(range_overflows_t(u64, offset, vma->size, GUC_GGTT_TOP));
115 147
116 return offset; 148 return offset;
@@ -119,17 +151,43 @@ static inline u32 guc_ggtt_offset(struct i915_vma *vma)
119void intel_guc_init_early(struct intel_guc *guc); 151void intel_guc_init_early(struct intel_guc *guc);
120void intel_guc_init_send_regs(struct intel_guc *guc); 152void intel_guc_init_send_regs(struct intel_guc *guc);
121void intel_guc_init_params(struct intel_guc *guc); 153void intel_guc_init_params(struct intel_guc *guc);
154void intel_guc_init_ggtt_pin_bias(struct intel_guc *guc);
122int intel_guc_init_wq(struct intel_guc *guc); 155int intel_guc_init_wq(struct intel_guc *guc);
123void intel_guc_fini_wq(struct intel_guc *guc); 156void intel_guc_fini_wq(struct intel_guc *guc);
124int intel_guc_init(struct intel_guc *guc); 157int intel_guc_init(struct intel_guc *guc);
125void intel_guc_fini(struct intel_guc *guc); 158void intel_guc_fini(struct intel_guc *guc);
126int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len); 159int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len,
127int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len); 160 u32 *response_buf, u32 response_buf_size);
161int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len,
162 u32 *response_buf, u32 response_buf_size);
163void intel_guc_to_host_event_handler(struct intel_guc *guc);
164void intel_guc_to_host_event_handler_nop(struct intel_guc *guc);
165void intel_guc_to_host_event_handler_mmio(struct intel_guc *guc);
166void intel_guc_to_host_process_recv_msg(struct intel_guc *guc, u32 msg);
128int intel_guc_sample_forcewake(struct intel_guc *guc); 167int intel_guc_sample_forcewake(struct intel_guc *guc);
129int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset); 168int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset);
130int intel_guc_suspend(struct intel_guc *guc); 169int intel_guc_suspend(struct intel_guc *guc);
131int intel_guc_resume(struct intel_guc *guc); 170int intel_guc_resume(struct intel_guc *guc);
132struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size); 171struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size);
133u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv); 172
173static inline int intel_guc_sanitize(struct intel_guc *guc)
174{
175 intel_uc_fw_sanitize(&guc->fw);
176 return 0;
177}
178
179static inline void intel_guc_enable_msg(struct intel_guc *guc, u32 mask)
180{
181 spin_lock_irq(&guc->irq_lock);
182 guc->msg_enabled_mask |= mask;
183 spin_unlock_irq(&guc->irq_lock);
184}
185
186static inline void intel_guc_disable_msg(struct intel_guc *guc, u32 mask)
187{
188 spin_lock_irq(&guc->irq_lock);
189 guc->msg_enabled_mask &= ~mask;
190 spin_unlock_irq(&guc->irq_lock);
191}
134 192
135#endif 193#endif
diff --git a/drivers/gpu/drm/i915/intel_guc_ads.c b/drivers/gpu/drm/i915/intel_guc_ads.c
index ac627534667d..dcaa3fb71765 100644
--- a/drivers/gpu/drm/i915/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/intel_guc_ads.c
@@ -75,7 +75,7 @@ static void guc_policies_init(struct guc_policies *policies)
75int intel_guc_ads_create(struct intel_guc *guc) 75int intel_guc_ads_create(struct intel_guc *guc)
76{ 76{
77 struct drm_i915_private *dev_priv = guc_to_i915(guc); 77 struct drm_i915_private *dev_priv = guc_to_i915(guc);
78 struct i915_vma *vma; 78 struct i915_vma *vma, *kernel_ctx_vma;
79 struct page *page; 79 struct page *page;
80 /* The ads obj includes the struct itself and buffers passed to GuC */ 80 /* The ads obj includes the struct itself and buffers passed to GuC */
81 struct { 81 struct {
@@ -121,9 +121,10 @@ int intel_guc_ads_create(struct intel_guc *guc)
121 * to find it. Note that we have to skip our header (1 page), 121 * to find it. Note that we have to skip our header (1 page),
122 * because our GuC shared data is there. 122 * because our GuC shared data is there.
123 */ 123 */
124 kernel_ctx_vma = to_intel_context(dev_priv->kernel_context,
125 dev_priv->engine[RCS])->state;
124 blob->ads.golden_context_lrca = 126 blob->ads.golden_context_lrca =
125 guc_ggtt_offset(dev_priv->kernel_context->engine[RCS].state) + 127 intel_guc_ggtt_offset(guc, kernel_ctx_vma) + skipped_offset;
126 skipped_offset;
127 128
128 /* 129 /*
129 * The GuC expects us to exclude the portion of the context image that 130 * The GuC expects us to exclude the portion of the context image that
@@ -135,7 +136,7 @@ int intel_guc_ads_create(struct intel_guc *guc)
135 blob->ads.eng_state_size[engine->guc_id] = 136 blob->ads.eng_state_size[engine->guc_id] =
136 engine->context_size - skipped_size; 137 engine->context_size - skipped_size;
137 138
138 base = guc_ggtt_offset(vma); 139 base = intel_guc_ggtt_offset(guc, vma);
139 blob->ads.scheduler_policies = base + ptr_offset(blob, policies); 140 blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
140 blob->ads.reg_state_buffer = base + ptr_offset(blob, reg_state_buffer); 141 blob->ads.reg_state_buffer = base + ptr_offset(blob, reg_state_buffer);
141 blob->ads.reg_state_addr = base + ptr_offset(blob, reg_state); 142 blob->ads.reg_state_addr = base + ptr_offset(blob, reg_state);
diff --git a/drivers/gpu/drm/i915/intel_guc_ct.c b/drivers/gpu/drm/i915/intel_guc_ct.c
index 24ad55752396..371b6005954a 100644
--- a/drivers/gpu/drm/i915/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/intel_guc_ct.c
@@ -24,14 +24,49 @@
24#include "i915_drv.h" 24#include "i915_drv.h"
25#include "intel_guc_ct.h" 25#include "intel_guc_ct.h"
26 26
27#ifdef CONFIG_DRM_I915_DEBUG_GUC
28#define CT_DEBUG_DRIVER(...) DRM_DEBUG_DRIVER(__VA_ARGS__)
29#else
30#define CT_DEBUG_DRIVER(...) do { } while (0)
31#endif
32
33struct ct_request {
34 struct list_head link;
35 u32 fence;
36 u32 status;
37 u32 response_len;
38 u32 *response_buf;
39};
40
41struct ct_incoming_request {
42 struct list_head link;
43 u32 msg[];
44};
45
27enum { CTB_SEND = 0, CTB_RECV = 1 }; 46enum { CTB_SEND = 0, CTB_RECV = 1 };
28 47
29enum { CTB_OWNER_HOST = 0 }; 48enum { CTB_OWNER_HOST = 0 };
30 49
50static void ct_incoming_request_worker_func(struct work_struct *w);
51
52/**
53 * intel_guc_ct_init_early - Initialize CT state without requiring device access
54 * @ct: pointer to CT struct
55 */
31void intel_guc_ct_init_early(struct intel_guc_ct *ct) 56void intel_guc_ct_init_early(struct intel_guc_ct *ct)
32{ 57{
33 /* we're using static channel owners */ 58 /* we're using static channel owners */
34 ct->host_channel.owner = CTB_OWNER_HOST; 59 ct->host_channel.owner = CTB_OWNER_HOST;
60
61 spin_lock_init(&ct->lock);
62 INIT_LIST_HEAD(&ct->pending_requests);
63 INIT_LIST_HEAD(&ct->incoming_requests);
64 INIT_WORK(&ct->worker, ct_incoming_request_worker_func);
65}
66
67static inline struct intel_guc *ct_to_guc(struct intel_guc_ct *ct)
68{
69 return container_of(ct, struct intel_guc, ct);
35} 70}
36 71
37static inline const char *guc_ct_buffer_type_to_str(u32 type) 72static inline const char *guc_ct_buffer_type_to_str(u32 type)
@@ -49,8 +84,8 @@ static inline const char *guc_ct_buffer_type_to_str(u32 type)
49static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc, 84static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc,
50 u32 cmds_addr, u32 size, u32 owner) 85 u32 cmds_addr, u32 size, u32 owner)
51{ 86{
52 DRM_DEBUG_DRIVER("CT: desc %p init addr=%#x size=%u owner=%u\n", 87 CT_DEBUG_DRIVER("CT: desc %p init addr=%#x size=%u owner=%u\n",
53 desc, cmds_addr, size, owner); 88 desc, cmds_addr, size, owner);
54 memset(desc, 0, sizeof(*desc)); 89 memset(desc, 0, sizeof(*desc));
55 desc->addr = cmds_addr; 90 desc->addr = cmds_addr;
56 desc->size = size; 91 desc->size = size;
@@ -59,8 +94,8 @@ static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc,
59 94
60static void guc_ct_buffer_desc_reset(struct guc_ct_buffer_desc *desc) 95static void guc_ct_buffer_desc_reset(struct guc_ct_buffer_desc *desc)
61{ 96{
62 DRM_DEBUG_DRIVER("CT: desc %p reset head=%u tail=%u\n", 97 CT_DEBUG_DRIVER("CT: desc %p reset head=%u tail=%u\n",
63 desc, desc->head, desc->tail); 98 desc, desc->head, desc->tail);
64 desc->head = 0; 99 desc->head = 0;
65 desc->tail = 0; 100 desc->tail = 0;
66 desc->is_in_error = 0; 101 desc->is_in_error = 0;
@@ -79,7 +114,7 @@ static int guc_action_register_ct_buffer(struct intel_guc *guc,
79 int err; 114 int err;
80 115
81 /* Can't use generic send(), CT registration must go over MMIO */ 116 /* Can't use generic send(), CT registration must go over MMIO */
82 err = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action)); 117 err = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), NULL, 0);
83 if (err) 118 if (err)
84 DRM_ERROR("CT: register %s buffer failed; err=%d\n", 119 DRM_ERROR("CT: register %s buffer failed; err=%d\n",
85 guc_ct_buffer_type_to_str(type), err); 120 guc_ct_buffer_type_to_str(type), err);
@@ -98,7 +133,7 @@ static int guc_action_deregister_ct_buffer(struct intel_guc *guc,
98 int err; 133 int err;
99 134
100 /* Can't use generic send(), CT deregistration must go over MMIO */ 135 /* Can't use generic send(), CT deregistration must go over MMIO */
101 err = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action)); 136 err = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), NULL, 0);
102 if (err) 137 if (err)
103 DRM_ERROR("CT: deregister %s buffer failed; owner=%d err=%d\n", 138 DRM_ERROR("CT: deregister %s buffer failed; owner=%d err=%d\n",
104 guc_ct_buffer_type_to_str(type), owner, err); 139 guc_ct_buffer_type_to_str(type), owner, err);
@@ -156,7 +191,8 @@ static int ctch_init(struct intel_guc *guc,
156 err = PTR_ERR(blob); 191 err = PTR_ERR(blob);
157 goto err_vma; 192 goto err_vma;
158 } 193 }
159 DRM_DEBUG_DRIVER("CT: vma base=%#x\n", guc_ggtt_offset(ctch->vma)); 194 CT_DEBUG_DRIVER("CT: vma base=%#x\n",
195 intel_guc_ggtt_offset(guc, ctch->vma));
160 196
161 /* store pointers to desc and cmds */ 197 /* store pointers to desc and cmds */
162 for (i = 0; i < ARRAY_SIZE(ctch->ctbs); i++) { 198 for (i = 0; i < ARRAY_SIZE(ctch->ctbs); i++) {
@@ -170,8 +206,8 @@ static int ctch_init(struct intel_guc *guc,
170err_vma: 206err_vma:
171 i915_vma_unpin_and_release(&ctch->vma); 207 i915_vma_unpin_and_release(&ctch->vma);
172err_out: 208err_out:
173 DRM_DEBUG_DRIVER("CT: channel %d initialization failed; err=%d\n", 209 CT_DEBUG_DRIVER("CT: channel %d initialization failed; err=%d\n",
174 ctch->owner, err); 210 ctch->owner, err);
175 return err; 211 return err;
176} 212}
177 213
@@ -191,8 +227,8 @@ static int ctch_open(struct intel_guc *guc,
191 int err; 227 int err;
192 int i; 228 int i;
193 229
194 DRM_DEBUG_DRIVER("CT: channel %d reopen=%s\n", 230 CT_DEBUG_DRIVER("CT: channel %d reopen=%s\n",
195 ctch->owner, yesno(ctch_is_open(ctch))); 231 ctch->owner, yesno(ctch_is_open(ctch)));
196 232
197 if (!ctch->vma) { 233 if (!ctch->vma) {
198 err = ctch_init(guc, ctch); 234 err = ctch_init(guc, ctch);
@@ -202,7 +238,7 @@ static int ctch_open(struct intel_guc *guc,
202 } 238 }
203 239
204 /* vma should be already allocated and map'ed */ 240 /* vma should be already allocated and map'ed */
205 base = guc_ggtt_offset(ctch->vma); 241 base = intel_guc_ggtt_offset(guc, ctch->vma);
206 242
207 /* (re)initialize descriptors 243 /* (re)initialize descriptors
208 * cmds buffers are in the second half of the blob page 244 * cmds buffers are in the second half of the blob page
@@ -263,10 +299,29 @@ static u32 ctch_get_next_fence(struct intel_guc_ct_channel *ctch)
263 return ++ctch->next_fence; 299 return ++ctch->next_fence;
264} 300}
265 301
302/**
303 * DOC: CTB Host to GuC request
304 *
305 * Format of the CTB Host to GuC request message is as follows::
306 *
307 * +------------+---------+---------+---------+---------+
308 * | msg[0] | [1] | [2] | ... | [n-1] |
309 * +------------+---------+---------+---------+---------+
310 * | MESSAGE | MESSAGE PAYLOAD |
311 * + HEADER +---------+---------+---------+---------+
312 * | | 0 | 1 | ... | n |
313 * +============+=========+=========+=========+=========+
314 * | len >= 1 | FENCE | request specific data |
315 * +------+-----+---------+---------+---------+---------+
316 *
317 * ^-----------------len-------------------^
318 */
319
266static int ctb_write(struct intel_guc_ct_buffer *ctb, 320static int ctb_write(struct intel_guc_ct_buffer *ctb,
267 const u32 *action, 321 const u32 *action,
268 u32 len /* in dwords */, 322 u32 len /* in dwords */,
269 u32 fence) 323 u32 fence,
324 bool want_response)
270{ 325{
271 struct guc_ct_buffer_desc *desc = ctb->desc; 326 struct guc_ct_buffer_desc *desc = ctb->desc;
272 u32 head = desc->head / 4; /* in dwords */ 327 u32 head = desc->head / 4; /* in dwords */
@@ -295,15 +350,21 @@ static int ctb_write(struct intel_guc_ct_buffer *ctb,
295 if (unlikely(used + len + 1 >= size)) 350 if (unlikely(used + len + 1 >= size))
296 return -ENOSPC; 351 return -ENOSPC;
297 352
298 /* Write the message. The format is the following: 353 /*
354 * Write the message. The format is the following:
299 * DW0: header (including action code) 355 * DW0: header (including action code)
300 * DW1: fence 356 * DW1: fence
301 * DW2+: action data 357 * DW2+: action data
302 */ 358 */
303 header = (len << GUC_CT_MSG_LEN_SHIFT) | 359 header = (len << GUC_CT_MSG_LEN_SHIFT) |
304 (GUC_CT_MSG_WRITE_FENCE_TO_DESC) | 360 (GUC_CT_MSG_WRITE_FENCE_TO_DESC) |
361 (want_response ? GUC_CT_MSG_SEND_STATUS : 0) |
305 (action[0] << GUC_CT_MSG_ACTION_SHIFT); 362 (action[0] << GUC_CT_MSG_ACTION_SHIFT);
306 363
364 CT_DEBUG_DRIVER("CT: writing %*ph %*ph %*ph\n",
365 4, &header, 4, &fence,
366 4 * (len - 1), &action[1]);
367
307 cmds[tail] = header; 368 cmds[tail] = header;
308 tail = (tail + 1) % size; 369 tail = (tail + 1) % size;
309 370
@@ -322,16 +383,25 @@ static int ctb_write(struct intel_guc_ct_buffer *ctb,
322 return 0; 383 return 0;
323} 384}
324 385
325/* Wait for the response from the GuC. 386/**
387 * wait_for_ctb_desc_update - Wait for the CT buffer descriptor update.
388 * @desc: buffer descriptor
326 * @fence: response fence 389 * @fence: response fence
327 * @status: placeholder for status 390 * @status: placeholder for status
328 * return: 0 response received (status is valid) 391 *
329 * -ETIMEDOUT no response within hardcoded timeout 392 * Guc will update CT buffer descriptor with new fence and status
330 * -EPROTO no response, ct buffer was in error 393 * after processing the command identified by the fence. Wait for
394 * specified fence and then read from the descriptor status of the
395 * command.
396 *
397 * Return:
398 * * 0 response received (status is valid)
399 * * -ETIMEDOUT no response within hardcoded timeout
400 * * -EPROTO no response, CT buffer is in error
331 */ 401 */
332static int wait_for_response(struct guc_ct_buffer_desc *desc, 402static int wait_for_ctb_desc_update(struct guc_ct_buffer_desc *desc,
333 u32 fence, 403 u32 fence,
334 u32 *status) 404 u32 *status)
335{ 405{
336 int err; 406 int err;
337 407
@@ -363,71 +433,440 @@ static int wait_for_response(struct guc_ct_buffer_desc *desc,
363 return err; 433 return err;
364} 434}
365 435
366static int ctch_send(struct intel_guc *guc, 436/**
437 * wait_for_ct_request_update - Wait for CT request state update.
438 * @req: pointer to pending request
439 * @status: placeholder for status
440 *
441 * For each sent request, Guc shall send bac CT response message.
442 * Our message handler will update status of tracked request once
443 * response message with given fence is received. Wait here and
444 * check for valid response status value.
445 *
446 * Return:
447 * * 0 response received (status is valid)
448 * * -ETIMEDOUT no response within hardcoded timeout
449 */
450static int wait_for_ct_request_update(struct ct_request *req, u32 *status)
451{
452 int err;
453
454 /*
455 * Fast commands should complete in less than 10us, so sample quickly
456 * up to that length of time, then switch to a slower sleep-wait loop.
457 * No GuC command should ever take longer than 10ms.
458 */
459#define done INTEL_GUC_MSG_IS_RESPONSE(READ_ONCE(req->status))
460 err = wait_for_us(done, 10);
461 if (err)
462 err = wait_for(done, 10);
463#undef done
464
465 if (unlikely(err))
466 DRM_ERROR("CT: fence %u err %d\n", req->fence, err);
467
468 *status = req->status;
469 return err;
470}
471
472static int ctch_send(struct intel_guc_ct *ct,
367 struct intel_guc_ct_channel *ctch, 473 struct intel_guc_ct_channel *ctch,
368 const u32 *action, 474 const u32 *action,
369 u32 len, 475 u32 len,
476 u32 *response_buf,
477 u32 response_buf_size,
370 u32 *status) 478 u32 *status)
371{ 479{
372 struct intel_guc_ct_buffer *ctb = &ctch->ctbs[CTB_SEND]; 480 struct intel_guc_ct_buffer *ctb = &ctch->ctbs[CTB_SEND];
373 struct guc_ct_buffer_desc *desc = ctb->desc; 481 struct guc_ct_buffer_desc *desc = ctb->desc;
482 struct ct_request request;
483 unsigned long flags;
374 u32 fence; 484 u32 fence;
375 int err; 485 int err;
376 486
377 GEM_BUG_ON(!ctch_is_open(ctch)); 487 GEM_BUG_ON(!ctch_is_open(ctch));
378 GEM_BUG_ON(!len); 488 GEM_BUG_ON(!len);
379 GEM_BUG_ON(len & ~GUC_CT_MSG_LEN_MASK); 489 GEM_BUG_ON(len & ~GUC_CT_MSG_LEN_MASK);
490 GEM_BUG_ON(!response_buf && response_buf_size);
380 491
381 fence = ctch_get_next_fence(ctch); 492 fence = ctch_get_next_fence(ctch);
382 err = ctb_write(ctb, action, len, fence); 493 request.fence = fence;
494 request.status = 0;
495 request.response_len = response_buf_size;
496 request.response_buf = response_buf;
497
498 spin_lock_irqsave(&ct->lock, flags);
499 list_add_tail(&request.link, &ct->pending_requests);
500 spin_unlock_irqrestore(&ct->lock, flags);
501
502 err = ctb_write(ctb, action, len, fence, !!response_buf);
383 if (unlikely(err)) 503 if (unlikely(err))
384 return err; 504 goto unlink;
385 505
386 intel_guc_notify(guc); 506 intel_guc_notify(ct_to_guc(ct));
387 507
388 err = wait_for_response(desc, fence, status); 508 if (response_buf)
509 err = wait_for_ct_request_update(&request, status);
510 else
511 err = wait_for_ctb_desc_update(desc, fence, status);
389 if (unlikely(err)) 512 if (unlikely(err))
390 return err; 513 goto unlink;
391 if (*status != INTEL_GUC_STATUS_SUCCESS) 514
392 return -EIO; 515 if (!INTEL_GUC_MSG_IS_RESPONSE_SUCCESS(*status)) {
393 return 0; 516 err = -EIO;
517 goto unlink;
518 }
519
520 if (response_buf) {
521 /* There shall be no data in the status */
522 WARN_ON(INTEL_GUC_MSG_TO_DATA(request.status));
523 /* Return actual response len */
524 err = request.response_len;
525 } else {
526 /* There shall be no response payload */
527 WARN_ON(request.response_len);
528 /* Return data decoded from the status dword */
529 err = INTEL_GUC_MSG_TO_DATA(*status);
530 }
531
532unlink:
533 spin_lock_irqsave(&ct->lock, flags);
534 list_del(&request.link);
535 spin_unlock_irqrestore(&ct->lock, flags);
536
537 return err;
394} 538}
395 539
396/* 540/*
397 * Command Transport (CT) buffer based GuC send function. 541 * Command Transport (CT) buffer based GuC send function.
398 */ 542 */
399static int intel_guc_send_ct(struct intel_guc *guc, const u32 *action, u32 len) 543static int intel_guc_send_ct(struct intel_guc *guc, const u32 *action, u32 len,
544 u32 *response_buf, u32 response_buf_size)
400{ 545{
401 struct intel_guc_ct_channel *ctch = &guc->ct.host_channel; 546 struct intel_guc_ct *ct = &guc->ct;
547 struct intel_guc_ct_channel *ctch = &ct->host_channel;
402 u32 status = ~0; /* undefined */ 548 u32 status = ~0; /* undefined */
403 int err; 549 int ret;
404 550
405 mutex_lock(&guc->send_mutex); 551 mutex_lock(&guc->send_mutex);
406 552
407 err = ctch_send(guc, ctch, action, len, &status); 553 ret = ctch_send(ct, ctch, action, len, response_buf, response_buf_size,
408 if (unlikely(err)) { 554 &status);
555 if (unlikely(ret < 0)) {
409 DRM_ERROR("CT: send action %#X failed; err=%d status=%#X\n", 556 DRM_ERROR("CT: send action %#X failed; err=%d status=%#X\n",
410 action[0], err, status); 557 action[0], ret, status);
558 } else if (unlikely(ret)) {
559 CT_DEBUG_DRIVER("CT: send action %#x returned %d (%#x)\n",
560 action[0], ret, ret);
411 } 561 }
412 562
413 mutex_unlock(&guc->send_mutex); 563 mutex_unlock(&guc->send_mutex);
414 return err; 564 return ret;
565}
566
567static inline unsigned int ct_header_get_len(u32 header)
568{
569 return (header >> GUC_CT_MSG_LEN_SHIFT) & GUC_CT_MSG_LEN_MASK;
570}
571
572static inline unsigned int ct_header_get_action(u32 header)
573{
574 return (header >> GUC_CT_MSG_ACTION_SHIFT) & GUC_CT_MSG_ACTION_MASK;
575}
576
577static inline bool ct_header_is_response(u32 header)
578{
579 return ct_header_get_action(header) == INTEL_GUC_ACTION_DEFAULT;
580}
581
582static int ctb_read(struct intel_guc_ct_buffer *ctb, u32 *data)
583{
584 struct guc_ct_buffer_desc *desc = ctb->desc;
585 u32 head = desc->head / 4; /* in dwords */
586 u32 tail = desc->tail / 4; /* in dwords */
587 u32 size = desc->size / 4; /* in dwords */
588 u32 *cmds = ctb->cmds;
589 s32 available; /* in dwords */
590 unsigned int len;
591 unsigned int i;
592
593 GEM_BUG_ON(desc->size % 4);
594 GEM_BUG_ON(desc->head % 4);
595 GEM_BUG_ON(desc->tail % 4);
596 GEM_BUG_ON(tail >= size);
597 GEM_BUG_ON(head >= size);
598
599 /* tail == head condition indicates empty */
600 available = tail - head;
601 if (unlikely(available == 0))
602 return -ENODATA;
603
604 /* beware of buffer wrap case */
605 if (unlikely(available < 0))
606 available += size;
607 CT_DEBUG_DRIVER("CT: available %d (%u:%u)\n", available, head, tail);
608 GEM_BUG_ON(available < 0);
609
610 data[0] = cmds[head];
611 head = (head + 1) % size;
612
613 /* message len with header */
614 len = ct_header_get_len(data[0]) + 1;
615 if (unlikely(len > (u32)available)) {
616 DRM_ERROR("CT: incomplete message %*ph %*ph %*ph\n",
617 4, data,
618 4 * (head + available - 1 > size ?
619 size - head : available - 1), &cmds[head],
620 4 * (head + available - 1 > size ?
621 available - 1 - size + head : 0), &cmds[0]);
622 return -EPROTO;
623 }
624
625 for (i = 1; i < len; i++) {
626 data[i] = cmds[head];
627 head = (head + 1) % size;
628 }
629 CT_DEBUG_DRIVER("CT: received %*ph\n", 4 * len, data);
630
631 desc->head = head * 4;
632 return 0;
415} 633}
416 634
417/** 635/**
418 * Enable buffer based command transport 636 * DOC: CTB GuC to Host response
637 *
638 * Format of the CTB GuC to Host response message is as follows::
639 *
640 * +------------+---------+---------+---------+---------+---------+
641 * | msg[0] | [1] | [2] | [3] | ... | [n-1] |
642 * +------------+---------+---------+---------+---------+---------+
643 * | MESSAGE | MESSAGE PAYLOAD |
644 * + HEADER +---------+---------+---------+---------+---------+
645 * | | 0 | 1 | 2 | ... | n |
646 * +============+=========+=========+=========+=========+=========+
647 * | len >= 2 | FENCE | STATUS | response specific data |
648 * +------+-----+---------+---------+---------+---------+---------+
649 *
650 * ^-----------------------len-----------------------^
651 */
652
653static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg)
654{
655 u32 header = msg[0];
656 u32 len = ct_header_get_len(header);
657 u32 msglen = len + 1; /* total message length including header */
658 u32 fence;
659 u32 status;
660 u32 datalen;
661 struct ct_request *req;
662 bool found = false;
663
664 GEM_BUG_ON(!ct_header_is_response(header));
665 GEM_BUG_ON(!in_irq());
666
667 /* Response payload shall at least include fence and status */
668 if (unlikely(len < 2)) {
669 DRM_ERROR("CT: corrupted response %*ph\n", 4 * msglen, msg);
670 return -EPROTO;
671 }
672
673 fence = msg[1];
674 status = msg[2];
675 datalen = len - 2;
676
677 /* Format of the status follows RESPONSE message */
678 if (unlikely(!INTEL_GUC_MSG_IS_RESPONSE(status))) {
679 DRM_ERROR("CT: corrupted response %*ph\n", 4 * msglen, msg);
680 return -EPROTO;
681 }
682
683 CT_DEBUG_DRIVER("CT: response fence %u status %#x\n", fence, status);
684
685 spin_lock(&ct->lock);
686 list_for_each_entry(req, &ct->pending_requests, link) {
687 if (unlikely(fence != req->fence)) {
688 CT_DEBUG_DRIVER("CT: request %u awaits response\n",
689 req->fence);
690 continue;
691 }
692 if (unlikely(datalen > req->response_len)) {
693 DRM_ERROR("CT: response %u too long %*ph\n",
694 req->fence, 4 * msglen, msg);
695 datalen = 0;
696 }
697 if (datalen)
698 memcpy(req->response_buf, msg + 3, 4 * datalen);
699 req->response_len = datalen;
700 WRITE_ONCE(req->status, status);
701 found = true;
702 break;
703 }
704 spin_unlock(&ct->lock);
705
706 if (!found)
707 DRM_ERROR("CT: unsolicited response %*ph\n", 4 * msglen, msg);
708 return 0;
709}
710
711static void ct_process_request(struct intel_guc_ct *ct,
712 u32 action, u32 len, const u32 *payload)
713{
714 struct intel_guc *guc = ct_to_guc(ct);
715
716 CT_DEBUG_DRIVER("CT: request %x %*ph\n", action, 4 * len, payload);
717
718 switch (action) {
719 case INTEL_GUC_ACTION_DEFAULT:
720 if (unlikely(len < 1))
721 goto fail_unexpected;
722 intel_guc_to_host_process_recv_msg(guc, *payload);
723 break;
724
725 default:
726fail_unexpected:
727 DRM_ERROR("CT: unexpected request %x %*ph\n",
728 action, 4 * len, payload);
729 break;
730 }
731}
732
733static bool ct_process_incoming_requests(struct intel_guc_ct *ct)
734{
735 unsigned long flags;
736 struct ct_incoming_request *request;
737 u32 header;
738 u32 *payload;
739 bool done;
740
741 spin_lock_irqsave(&ct->lock, flags);
742 request = list_first_entry_or_null(&ct->incoming_requests,
743 struct ct_incoming_request, link);
744 if (request)
745 list_del(&request->link);
746 done = !!list_empty(&ct->incoming_requests);
747 spin_unlock_irqrestore(&ct->lock, flags);
748
749 if (!request)
750 return true;
751
752 header = request->msg[0];
753 payload = &request->msg[1];
754 ct_process_request(ct,
755 ct_header_get_action(header),
756 ct_header_get_len(header),
757 payload);
758
759 kfree(request);
760 return done;
761}
762
763static void ct_incoming_request_worker_func(struct work_struct *w)
764{
765 struct intel_guc_ct *ct = container_of(w, struct intel_guc_ct, worker);
766 bool done;
767
768 done = ct_process_incoming_requests(ct);
769 if (!done)
770 queue_work(system_unbound_wq, &ct->worker);
771}
772
773/**
774 * DOC: CTB GuC to Host request
775 *
776 * Format of the CTB GuC to Host request message is as follows::
777 *
778 * +------------+---------+---------+---------+---------+---------+
779 * | msg[0] | [1] | [2] | [3] | ... | [n-1] |
780 * +------------+---------+---------+---------+---------+---------+
781 * | MESSAGE | MESSAGE PAYLOAD |
782 * + HEADER +---------+---------+---------+---------+---------+
783 * | | 0 | 1 | 2 | ... | n |
784 * +============+=========+=========+=========+=========+=========+
785 * | len | request specific data |
786 * +------+-----+---------+---------+---------+---------+---------+
787 *
788 * ^-----------------------len-----------------------^
789 */
790
791static int ct_handle_request(struct intel_guc_ct *ct, const u32 *msg)
792{
793 u32 header = msg[0];
794 u32 len = ct_header_get_len(header);
795 u32 msglen = len + 1; /* total message length including header */
796 struct ct_incoming_request *request;
797 unsigned long flags;
798
799 GEM_BUG_ON(ct_header_is_response(header));
800
801 request = kmalloc(sizeof(*request) + 4 * msglen, GFP_ATOMIC);
802 if (unlikely(!request)) {
803 DRM_ERROR("CT: dropping request %*ph\n", 4 * msglen, msg);
804 return 0; /* XXX: -ENOMEM ? */
805 }
806 memcpy(request->msg, msg, 4 * msglen);
807
808 spin_lock_irqsave(&ct->lock, flags);
809 list_add_tail(&request->link, &ct->incoming_requests);
810 spin_unlock_irqrestore(&ct->lock, flags);
811
812 queue_work(system_unbound_wq, &ct->worker);
813 return 0;
814}
815
816static void ct_process_host_channel(struct intel_guc_ct *ct)
817{
818 struct intel_guc_ct_channel *ctch = &ct->host_channel;
819 struct intel_guc_ct_buffer *ctb = &ctch->ctbs[CTB_RECV];
820 u32 msg[GUC_CT_MSG_LEN_MASK + 1]; /* one extra dw for the header */
821 int err = 0;
822
823 if (!ctch_is_open(ctch))
824 return;
825
826 do {
827 err = ctb_read(ctb, msg);
828 if (err)
829 break;
830
831 if (ct_header_is_response(msg[0]))
832 err = ct_handle_response(ct, msg);
833 else
834 err = ct_handle_request(ct, msg);
835 } while (!err);
836
837 if (GEM_WARN_ON(err == -EPROTO)) {
838 DRM_ERROR("CT: corrupted message detected!\n");
839 ctb->desc->is_in_error = 1;
840 }
841}
842
843/*
844 * When we're communicating with the GuC over CT, GuC uses events
845 * to notify us about new messages being posted on the RECV buffer.
846 */
847static void intel_guc_to_host_event_handler_ct(struct intel_guc *guc)
848{
849 struct intel_guc_ct *ct = &guc->ct;
850
851 ct_process_host_channel(ct);
852}
853
854/**
855 * intel_guc_ct_enable - Enable buffer based command transport.
856 * @ct: pointer to CT struct
857 *
419 * Shall only be called for platforms with HAS_GUC_CT. 858 * Shall only be called for platforms with HAS_GUC_CT.
420 * @guc: the guc 859 *
421 * return: 0 on success 860 * Return: 0 on success, a negative errno code on failure.
422 * non-zero on failure
423 */ 861 */
424int intel_guc_enable_ct(struct intel_guc *guc) 862int intel_guc_ct_enable(struct intel_guc_ct *ct)
425{ 863{
426 struct drm_i915_private *dev_priv = guc_to_i915(guc); 864 struct intel_guc *guc = ct_to_guc(ct);
427 struct intel_guc_ct_channel *ctch = &guc->ct.host_channel; 865 struct drm_i915_private *i915 = guc_to_i915(guc);
866 struct intel_guc_ct_channel *ctch = &ct->host_channel;
428 int err; 867 int err;
429 868
430 GEM_BUG_ON(!HAS_GUC_CT(dev_priv)); 869 GEM_BUG_ON(!HAS_GUC_CT(i915));
431 870
432 err = ctch_open(guc, ctch); 871 err = ctch_open(guc, ctch);
433 if (unlikely(err)) 872 if (unlikely(err))
@@ -435,21 +874,24 @@ int intel_guc_enable_ct(struct intel_guc *guc)
435 874
436 /* Switch into cmd transport buffer based send() */ 875 /* Switch into cmd transport buffer based send() */
437 guc->send = intel_guc_send_ct; 876 guc->send = intel_guc_send_ct;
877 guc->handler = intel_guc_to_host_event_handler_ct;
438 DRM_INFO("CT: %s\n", enableddisabled(true)); 878 DRM_INFO("CT: %s\n", enableddisabled(true));
439 return 0; 879 return 0;
440} 880}
441 881
442/** 882/**
443 * Disable buffer based command transport. 883 * intel_guc_ct_disable - Disable buffer based command transport.
884 * @ct: pointer to CT struct
885 *
444 * Shall only be called for platforms with HAS_GUC_CT. 886 * Shall only be called for platforms with HAS_GUC_CT.
445 * @guc: the guc
446 */ 887 */
447void intel_guc_disable_ct(struct intel_guc *guc) 888void intel_guc_ct_disable(struct intel_guc_ct *ct)
448{ 889{
449 struct drm_i915_private *dev_priv = guc_to_i915(guc); 890 struct intel_guc *guc = ct_to_guc(ct);
450 struct intel_guc_ct_channel *ctch = &guc->ct.host_channel; 891 struct drm_i915_private *i915 = guc_to_i915(guc);
892 struct intel_guc_ct_channel *ctch = &ct->host_channel;
451 893
452 GEM_BUG_ON(!HAS_GUC_CT(dev_priv)); 894 GEM_BUG_ON(!HAS_GUC_CT(i915));
453 895
454 if (!ctch_is_open(ctch)) 896 if (!ctch_is_open(ctch))
455 return; 897 return;
@@ -458,5 +900,6 @@ void intel_guc_disable_ct(struct intel_guc *guc)
458 900
459 /* Disable send */ 901 /* Disable send */
460 guc->send = intel_guc_send_nop; 902 guc->send = intel_guc_send_nop;
903 guc->handler = intel_guc_to_host_event_handler_nop;
461 DRM_INFO("CT: %s\n", enableddisabled(false)); 904 DRM_INFO("CT: %s\n", enableddisabled(false));
462} 905}
diff --git a/drivers/gpu/drm/i915/intel_guc_ct.h b/drivers/gpu/drm/i915/intel_guc_ct.h
index 6d97f36fcc62..d774895ab143 100644
--- a/drivers/gpu/drm/i915/intel_guc_ct.h
+++ b/drivers/gpu/drm/i915/intel_guc_ct.h
@@ -75,12 +75,22 @@ struct intel_guc_ct_channel {
75struct intel_guc_ct { 75struct intel_guc_ct {
76 struct intel_guc_ct_channel host_channel; 76 struct intel_guc_ct_channel host_channel;
77 /* other channels are tbd */ 77 /* other channels are tbd */
78
79 /** @lock: protects pending requests list */
80 spinlock_t lock;
81
82 /** @pending_requests: list of requests waiting for response */
83 struct list_head pending_requests;
84
85 /** @incoming_requests: list of incoming requests */
86 struct list_head incoming_requests;
87
88 /** @worker: worker for handling incoming requests */
89 struct work_struct worker;
78}; 90};
79 91
80void intel_guc_ct_init_early(struct intel_guc_ct *ct); 92void intel_guc_ct_init_early(struct intel_guc_ct *ct);
81 93int intel_guc_ct_enable(struct intel_guc_ct *ct);
82/* XXX: move to intel_uc.h ? don't fit there either */ 94void intel_guc_ct_disable(struct intel_guc_ct *ct);
83int intel_guc_enable_ct(struct intel_guc *guc);
84void intel_guc_disable_ct(struct intel_guc *guc);
85 95
86#endif /* _INTEL_GUC_CT_H_ */ 96#endif /* _INTEL_GUC_CT_H_ */
diff --git a/drivers/gpu/drm/i915/intel_guc_fw.c b/drivers/gpu/drm/i915/intel_guc_fw.c
index d07f2b985f1c..a9e6fcce467c 100644
--- a/drivers/gpu/drm/i915/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/intel_guc_fw.c
@@ -165,7 +165,7 @@ static int guc_xfer_ucode(struct intel_guc *guc, struct i915_vma *vma)
165 I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size); 165 I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size);
166 166
167 /* Set the source address for the new blob */ 167 /* Set the source address for the new blob */
168 offset = guc_ggtt_offset(vma) + guc_fw->header_offset; 168 offset = intel_guc_ggtt_offset(guc, vma) + guc_fw->header_offset;
169 I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset)); 169 I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
170 I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF); 170 I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
171 171
@@ -275,9 +275,8 @@ static int guc_fw_xfer(struct intel_uc_fw *guc_fw, struct i915_vma *vma)
275 * Called from intel_uc_init_hw() during driver load, resume from sleep and 275 * Called from intel_uc_init_hw() during driver load, resume from sleep and
276 * after a GPU reset. 276 * after a GPU reset.
277 * 277 *
278 * The firmware image should have already been fetched into memory by the 278 * The firmware image should have already been fetched into memory, so only
279 * earlier call to intel_uc_init_fw(), so here we need to only check that 279 * check that fetch succeeded, and then transfer the image to the h/w.
280 * fetch succeeded, and then transfer the image to the h/w.
281 * 280 *
282 * Return: non-zero code on error 281 * Return: non-zero code on error
283 */ 282 */
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 6a10aa6f04d3..0867ba76d445 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -23,9 +23,6 @@
23#ifndef _INTEL_GUC_FWIF_H 23#ifndef _INTEL_GUC_FWIF_H
24#define _INTEL_GUC_FWIF_H 24#define _INTEL_GUC_FWIF_H
25 25
26#define GUC_CORE_FAMILY_GEN9 12
27#define GUC_CORE_FAMILY_UNKNOWN 0x7fffffff
28
29#define GUC_CLIENT_PRIORITY_KMD_HIGH 0 26#define GUC_CLIENT_PRIORITY_KMD_HIGH 0
30#define GUC_CLIENT_PRIORITY_HIGH 1 27#define GUC_CLIENT_PRIORITY_HIGH 1
31#define GUC_CLIENT_PRIORITY_KMD_NORMAL 2 28#define GUC_CLIENT_PRIORITY_KMD_NORMAL 2
@@ -82,8 +79,6 @@
82#define GUC_CTL_ARAT_LOW 2 79#define GUC_CTL_ARAT_LOW 2
83 80
84#define GUC_CTL_DEVICE_INFO 3 81#define GUC_CTL_DEVICE_INFO 3
85#define GUC_CTL_GT_TYPE_SHIFT 0
86#define GUC_CTL_CORE_FAMILY_SHIFT 7
87 82
88#define GUC_CTL_LOG_PARAMS 4 83#define GUC_CTL_LOG_PARAMS 4
89#define GUC_LOG_VALID (1 << 0) 84#define GUC_LOG_VALID (1 << 0)
@@ -127,7 +122,7 @@
127#define GUC_PROFILE_ENABLED (1 << 7) 122#define GUC_PROFILE_ENABLED (1 << 7)
128#define GUC_WQ_TRACK_ENABLED (1 << 8) 123#define GUC_WQ_TRACK_ENABLED (1 << 8)
129#define GUC_ADS_ENABLED (1 << 9) 124#define GUC_ADS_ENABLED (1 << 9)
130#define GUC_DEBUG_RESERVED (1 << 10) 125#define GUC_LOG_DEFAULT_DISABLED (1 << 10)
131#define GUC_ADS_ADDR_SHIFT 11 126#define GUC_ADS_ADDR_SHIFT 11
132#define GUC_ADS_ADDR_MASK 0xfffff800 127#define GUC_ADS_ADDR_MASK 0xfffff800
133 128
@@ -327,6 +322,58 @@ struct guc_stage_desc {
327 u64 desc_private; 322 u64 desc_private;
328} __packed; 323} __packed;
329 324
325/**
326 * DOC: CTB based communication
327 *
328 * The CTB (command transport buffer) communication between Host and GuC
329 * is based on u32 data stream written to the shared buffer. One buffer can
330 * be used to transmit data only in one direction (one-directional channel).
331 *
332 * Current status of the each buffer is stored in the buffer descriptor.
333 * Buffer descriptor holds tail and head fields that represents active data
334 * stream. The tail field is updated by the data producer (sender), and head
335 * field is updated by the data consumer (receiver)::
336 *
337 * +------------+
338 * | DESCRIPTOR | +=================+============+========+
339 * +============+ | | MESSAGE(s) | |
340 * | address |--------->+=================+============+========+
341 * +------------+
342 * | head | ^-----head--------^
343 * +------------+
344 * | tail | ^---------tail-----------------^
345 * +------------+
346 * | size | ^---------------size--------------------^
347 * +------------+
348 *
349 * Each message in data stream starts with the single u32 treated as a header,
350 * followed by optional set of u32 data that makes message specific payload::
351 *
352 * +------------+---------+---------+---------+
353 * | MESSAGE |
354 * +------------+---------+---------+---------+
355 * | msg[0] | [1] | ... | [n-1] |
356 * +------------+---------+---------+---------+
357 * | MESSAGE | MESSAGE PAYLOAD |
358 * + HEADER +---------+---------+---------+
359 * | | 0 | ... | n |
360 * +======+=====+=========+=========+=========+
361 * | 31:16| code| | | |
362 * +------+-----+ | | |
363 * | 15:5|flags| | | |
364 * +------+-----+ | | |
365 * | 4:0| len| | | |
366 * +------+-----+---------+---------+---------+
367 *
368 * ^-------------len-------------^
369 *
370 * The message header consists of:
371 *
372 * - **len**, indicates length of the message payload (in u32)
373 * - **code**, indicates message code
374 * - **flags**, holds various bits to control message handling
375 */
376
330/* 377/*
331 * Describes single command transport buffer. 378 * Describes single command transport buffer.
332 * Used by both guc-master and clients. 379 * Used by both guc-master and clients.
@@ -534,16 +581,6 @@ struct guc_log_buffer_state {
534 u32 version; 581 u32 version;
535} __packed; 582} __packed;
536 583
537union guc_log_control {
538 struct {
539 u32 logging_enabled:1;
540 u32 reserved1:3;
541 u32 verbosity:4;
542 u32 reserved2:24;
543 };
544 u32 value;
545} __packed;
546
547struct guc_ctx_report { 584struct guc_ctx_report {
548 u32 report_return_status; 585 u32 report_return_status;
549 u32 reserved1[64]; 586 u32 reserved1[64];
@@ -570,7 +607,68 @@ struct guc_shared_ctx_data {
570 struct guc_ctx_report preempt_ctx_report[GUC_MAX_ENGINES_NUM]; 607 struct guc_ctx_report preempt_ctx_report[GUC_MAX_ENGINES_NUM];
571} __packed; 608} __packed;
572 609
573/* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ 610/**
611 * DOC: MMIO based communication
612 *
613 * The MMIO based communication between Host and GuC uses software scratch
614 * registers, where first register holds data treated as message header,
615 * and other registers are used to hold message payload.
616 *
617 * For Gen9+, GuC uses software scratch registers 0xC180-0xC1B8
618 *
619 * +-----------+---------+---------+---------+
620 * | MMIO[0] | MMIO[1] | ... | MMIO[n] |
621 * +-----------+---------+---------+---------+
622 * | header | optional payload |
623 * +======+====+=========+=========+=========+
624 * | 31:28|type| | | |
625 * +------+----+ | | |
626 * | 27:16|data| | | |
627 * +------+----+ | | |
628 * | 15:0|code| | | |
629 * +------+----+---------+---------+---------+
630 *
631 * The message header consists of:
632 *
633 * - **type**, indicates message type
634 * - **code**, indicates message code, is specific for **type**
635 * - **data**, indicates message data, optional, depends on **code**
636 *
637 * The following message **types** are supported:
638 *
639 * - **REQUEST**, indicates Host-to-GuC request, requested GuC action code
640 * must be priovided in **code** field. Optional action specific parameters
641 * can be provided in remaining payload registers or **data** field.
642 *
643 * - **RESPONSE**, indicates GuC-to-Host response from earlier GuC request,
644 * action response status will be provided in **code** field. Optional
645 * response data can be returned in remaining payload registers or **data**
646 * field.
647 */
648
649#define INTEL_GUC_MSG_TYPE_SHIFT 28
650#define INTEL_GUC_MSG_TYPE_MASK (0xF << INTEL_GUC_MSG_TYPE_SHIFT)
651#define INTEL_GUC_MSG_DATA_SHIFT 16
652#define INTEL_GUC_MSG_DATA_MASK (0xFFF << INTEL_GUC_MSG_DATA_SHIFT)
653#define INTEL_GUC_MSG_CODE_SHIFT 0
654#define INTEL_GUC_MSG_CODE_MASK (0xFFFF << INTEL_GUC_MSG_CODE_SHIFT)
655
656#define __INTEL_GUC_MSG_GET(T, m) \
657 (((m) & INTEL_GUC_MSG_ ## T ## _MASK) >> INTEL_GUC_MSG_ ## T ## _SHIFT)
658#define INTEL_GUC_MSG_TO_TYPE(m) __INTEL_GUC_MSG_GET(TYPE, m)
659#define INTEL_GUC_MSG_TO_DATA(m) __INTEL_GUC_MSG_GET(DATA, m)
660#define INTEL_GUC_MSG_TO_CODE(m) __INTEL_GUC_MSG_GET(CODE, m)
661
662enum intel_guc_msg_type {
663 INTEL_GUC_MSG_TYPE_REQUEST = 0x0,
664 INTEL_GUC_MSG_TYPE_RESPONSE = 0xF,
665};
666
667#define __INTEL_GUC_MSG_TYPE_IS(T, m) \
668 (INTEL_GUC_MSG_TO_TYPE(m) == INTEL_GUC_MSG_TYPE_ ## T)
669#define INTEL_GUC_MSG_IS_REQUEST(m) __INTEL_GUC_MSG_TYPE_IS(REQUEST, m)
670#define INTEL_GUC_MSG_IS_RESPONSE(m) __INTEL_GUC_MSG_TYPE_IS(RESPONSE, m)
671
574enum intel_guc_action { 672enum intel_guc_action {
575 INTEL_GUC_ACTION_DEFAULT = 0x0, 673 INTEL_GUC_ACTION_DEFAULT = 0x0,
576 INTEL_GUC_ACTION_REQUEST_PREEMPTION = 0x2, 674 INTEL_GUC_ACTION_REQUEST_PREEMPTION = 0x2,
@@ -602,24 +700,22 @@ enum intel_guc_report_status {
602 INTEL_GUC_REPORT_STATUS_COMPLETE = 0x4, 700 INTEL_GUC_REPORT_STATUS_COMPLETE = 0x4,
603}; 701};
604 702
605/* 703#define GUC_LOG_CONTROL_LOGGING_ENABLED (1 << 0)
606 * The GuC sends its response to a command by overwriting the 704#define GUC_LOG_CONTROL_VERBOSITY_SHIFT 4
607 * command in SS0. The response is distinguishable from a command 705#define GUC_LOG_CONTROL_VERBOSITY_MASK (0xF << GUC_LOG_CONTROL_VERBOSITY_SHIFT)
608 * by the fact that all the MASK bits are set. The remaining bits 706#define GUC_LOG_CONTROL_DEFAULT_LOGGING (1 << 8)
609 * give more detail. 707
610 */ 708enum intel_guc_response_status {
611#define INTEL_GUC_RECV_MASK ((u32)0xF0000000) 709 INTEL_GUC_RESPONSE_STATUS_SUCCESS = 0x0,
612#define INTEL_GUC_RECV_IS_RESPONSE(x) ((u32)(x) >= INTEL_GUC_RECV_MASK) 710 INTEL_GUC_RESPONSE_STATUS_GENERIC_FAIL = 0xF000,
613#define INTEL_GUC_RECV_STATUS(x) (INTEL_GUC_RECV_MASK | (x))
614
615/* GUC will return status back to SOFT_SCRATCH_O_REG */
616enum intel_guc_status {
617 INTEL_GUC_STATUS_SUCCESS = INTEL_GUC_RECV_STATUS(0x0),
618 INTEL_GUC_STATUS_ALLOCATE_DOORBELL_FAIL = INTEL_GUC_RECV_STATUS(0x10),
619 INTEL_GUC_STATUS_DEALLOCATE_DOORBELL_FAIL = INTEL_GUC_RECV_STATUS(0x20),
620 INTEL_GUC_STATUS_GENERIC_FAIL = INTEL_GUC_RECV_STATUS(0x0000F000)
621}; 711};
622 712
713#define INTEL_GUC_MSG_IS_RESPONSE_SUCCESS(m) \
714 (typecheck(u32, (m)) && \
715 ((m) & (INTEL_GUC_MSG_TYPE_MASK | INTEL_GUC_MSG_CODE_MASK)) == \
716 ((INTEL_GUC_MSG_TYPE_RESPONSE << INTEL_GUC_MSG_TYPE_SHIFT) | \
717 (INTEL_GUC_RESPONSE_STATUS_SUCCESS << INTEL_GUC_MSG_CODE_SHIFT)))
718
623/* This action will be programmed in C1BC - SOFT_SCRATCH_15_REG */ 719/* This action will be programmed in C1BC - SOFT_SCRATCH_15_REG */
624enum intel_guc_recv_message { 720enum intel_guc_recv_message {
625 INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED = BIT(1), 721 INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED = BIT(1),
diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c
index c0c2e7d1c7d7..401e1704d61e 100644
--- a/drivers/gpu/drm/i915/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/intel_guc_log.c
@@ -23,12 +23,11 @@
23 */ 23 */
24 24
25#include <linux/debugfs.h> 25#include <linux/debugfs.h>
26#include <linux/relay.h>
27 26
28#include "intel_guc_log.h" 27#include "intel_guc_log.h"
29#include "i915_drv.h" 28#include "i915_drv.h"
30 29
31static void guc_log_capture_logs(struct intel_guc *guc); 30static void guc_log_capture_logs(struct intel_guc_log *log);
32 31
33/** 32/**
34 * DOC: GuC firmware log 33 * DOC: GuC firmware log
@@ -39,7 +38,7 @@ static void guc_log_capture_logs(struct intel_guc *guc);
39 * registers value. 38 * registers value.
40 */ 39 */
41 40
42static int guc_log_flush_complete(struct intel_guc *guc) 41static int guc_action_flush_log_complete(struct intel_guc *guc)
43{ 42{
44 u32 action[] = { 43 u32 action[] = {
45 INTEL_GUC_ACTION_LOG_BUFFER_FILE_FLUSH_COMPLETE 44 INTEL_GUC_ACTION_LOG_BUFFER_FILE_FLUSH_COMPLETE
@@ -48,7 +47,7 @@ static int guc_log_flush_complete(struct intel_guc *guc)
48 return intel_guc_send(guc, action, ARRAY_SIZE(action)); 47 return intel_guc_send(guc, action, ARRAY_SIZE(action));
49} 48}
50 49
51static int guc_log_flush(struct intel_guc *guc) 50static int guc_action_flush_log(struct intel_guc *guc)
52{ 51{
53 u32 action[] = { 52 u32 action[] = {
54 INTEL_GUC_ACTION_FORCE_LOG_BUFFER_FLUSH, 53 INTEL_GUC_ACTION_FORCE_LOG_BUFFER_FLUSH,
@@ -58,22 +57,40 @@ static int guc_log_flush(struct intel_guc *guc)
58 return intel_guc_send(guc, action, ARRAY_SIZE(action)); 57 return intel_guc_send(guc, action, ARRAY_SIZE(action));
59} 58}
60 59
61static int guc_log_control(struct intel_guc *guc, bool enable, u32 verbosity) 60static int guc_action_control_log(struct intel_guc *guc, bool enable,
61 bool default_logging, u32 verbosity)
62{ 62{
63 union guc_log_control control_val = {
64 {
65 .logging_enabled = enable,
66 .verbosity = verbosity,
67 },
68 };
69 u32 action[] = { 63 u32 action[] = {
70 INTEL_GUC_ACTION_UK_LOG_ENABLE_LOGGING, 64 INTEL_GUC_ACTION_UK_LOG_ENABLE_LOGGING,
71 control_val.value 65 (enable ? GUC_LOG_CONTROL_LOGGING_ENABLED : 0) |
66 (verbosity << GUC_LOG_CONTROL_VERBOSITY_SHIFT) |
67 (default_logging ? GUC_LOG_CONTROL_DEFAULT_LOGGING : 0)
72 }; 68 };
73 69
70 GEM_BUG_ON(verbosity > GUC_LOG_VERBOSITY_MAX);
71
74 return intel_guc_send(guc, action, ARRAY_SIZE(action)); 72 return intel_guc_send(guc, action, ARRAY_SIZE(action));
75} 73}
76 74
75static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
76{
77 return container_of(log, struct intel_guc, log);
78}
79
80static void guc_log_enable_flush_events(struct intel_guc_log *log)
81{
82 intel_guc_enable_msg(log_to_guc(log),
83 INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
84 INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
85}
86
87static void guc_log_disable_flush_events(struct intel_guc_log *log)
88{
89 intel_guc_disable_msg(log_to_guc(log),
90 INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
91 INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
92}
93
77/* 94/*
78 * Sub buffer switch callback. Called whenever relay has to switch to a new 95 * Sub buffer switch callback. Called whenever relay has to switch to a new
79 * sub buffer, relay stays on the same sub buffer if 0 is returned. 96 * sub buffer, relay stays on the same sub buffer if 0 is returned.
@@ -121,14 +138,7 @@ static struct dentry *create_buf_file_callback(const char *filename,
121 if (!parent) 138 if (!parent)
122 return NULL; 139 return NULL;
123 140
124 /* 141 buf_file = debugfs_create_file(filename, mode,
125 * Not using the channel filename passed as an argument, since for each
126 * channel relay appends the corresponding CPU number to the filename
127 * passed in relay_open(). This should be fine as relay just needs a
128 * dentry of the file associated with the channel buffer and that file's
129 * name need not be same as the filename passed as an argument.
130 */
131 buf_file = debugfs_create_file("guc_log", mode,
132 parent, buf, &relay_file_operations); 142 parent, buf, &relay_file_operations);
133 return buf_file; 143 return buf_file;
134} 144}
@@ -149,59 +159,7 @@ static struct rchan_callbacks relay_callbacks = {
149 .remove_buf_file = remove_buf_file_callback, 159 .remove_buf_file = remove_buf_file_callback,
150}; 160};
151 161
152static int guc_log_relay_file_create(struct intel_guc *guc) 162static void guc_move_to_next_buf(struct intel_guc_log *log)
153{
154 struct drm_i915_private *dev_priv = guc_to_i915(guc);
155 struct dentry *log_dir;
156 int ret;
157
158 if (!i915_modparams.guc_log_level)
159 return 0;
160
161 mutex_lock(&guc->log.runtime.relay_lock);
162
163 /* For now create the log file in /sys/kernel/debug/dri/0 dir */
164 log_dir = dev_priv->drm.primary->debugfs_root;
165
166 /*
167 * If /sys/kernel/debug/dri/0 location do not exist, then debugfs is
168 * not mounted and so can't create the relay file.
169 * The relay API seems to fit well with debugfs only, for availing relay
170 * there are 3 requirements which can be met for debugfs file only in a
171 * straightforward/clean manner :-
172 * i) Need the associated dentry pointer of the file, while opening the
173 * relay channel.
174 * ii) Should be able to use 'relay_file_operations' fops for the file.
175 * iii) Set the 'i_private' field of file's inode to the pointer of
176 * relay channel buffer.
177 */
178 if (!log_dir) {
179 DRM_ERROR("Debugfs dir not available yet for GuC log file\n");
180 ret = -ENODEV;
181 goto out_unlock;
182 }
183
184 ret = relay_late_setup_files(guc->log.runtime.relay_chan, "guc_log", log_dir);
185 if (ret < 0 && ret != -EEXIST) {
186 DRM_ERROR("Couldn't associate relay chan with file %d\n", ret);
187 goto out_unlock;
188 }
189
190 ret = 0;
191
192out_unlock:
193 mutex_unlock(&guc->log.runtime.relay_lock);
194 return ret;
195}
196
197static bool guc_log_has_relay(struct intel_guc *guc)
198{
199 lockdep_assert_held(&guc->log.runtime.relay_lock);
200
201 return guc->log.runtime.relay_chan != NULL;
202}
203
204static void guc_move_to_next_buf(struct intel_guc *guc)
205{ 163{
206 /* 164 /*
207 * Make sure the updates made in the sub buffer are visible when 165 * Make sure the updates made in the sub buffer are visible when
@@ -209,21 +167,15 @@ static void guc_move_to_next_buf(struct intel_guc *guc)
209 */ 167 */
210 smp_wmb(); 168 smp_wmb();
211 169
212 if (!guc_log_has_relay(guc))
213 return;
214
215 /* All data has been written, so now move the offset of sub buffer. */ 170 /* All data has been written, so now move the offset of sub buffer. */
216 relay_reserve(guc->log.runtime.relay_chan, guc->log.vma->obj->base.size); 171 relay_reserve(log->relay.channel, log->vma->obj->base.size);
217 172
218 /* Switch to the next sub buffer */ 173 /* Switch to the next sub buffer */
219 relay_flush(guc->log.runtime.relay_chan); 174 relay_flush(log->relay.channel);
220} 175}
221 176
222static void *guc_get_write_buffer(struct intel_guc *guc) 177static void *guc_get_write_buffer(struct intel_guc_log *log)
223{ 178{
224 if (!guc_log_has_relay(guc))
225 return NULL;
226
227 /* 179 /*
228 * Just get the base address of a new sub buffer and copy data into it 180 * Just get the base address of a new sub buffer and copy data into it
229 * ourselves. NULL will be returned in no-overwrite mode, if all sub 181 * ourselves. NULL will be returned in no-overwrite mode, if all sub
@@ -233,25 +185,25 @@ static void *guc_get_write_buffer(struct intel_guc *guc)
233 * done without using relay_reserve() along with relay_write(). So its 185 * done without using relay_reserve() along with relay_write(). So its
234 * better to use relay_reserve() alone. 186 * better to use relay_reserve() alone.
235 */ 187 */
236 return relay_reserve(guc->log.runtime.relay_chan, 0); 188 return relay_reserve(log->relay.channel, 0);
237} 189}
238 190
239static bool guc_check_log_buf_overflow(struct intel_guc *guc, 191static bool guc_check_log_buf_overflow(struct intel_guc_log *log,
240 enum guc_log_buffer_type type, 192 enum guc_log_buffer_type type,
241 unsigned int full_cnt) 193 unsigned int full_cnt)
242{ 194{
243 unsigned int prev_full_cnt = guc->log.prev_overflow_count[type]; 195 unsigned int prev_full_cnt = log->stats[type].sampled_overflow;
244 bool overflow = false; 196 bool overflow = false;
245 197
246 if (full_cnt != prev_full_cnt) { 198 if (full_cnt != prev_full_cnt) {
247 overflow = true; 199 overflow = true;
248 200
249 guc->log.prev_overflow_count[type] = full_cnt; 201 log->stats[type].overflow = full_cnt;
250 guc->log.total_overflow_count[type] += full_cnt - prev_full_cnt; 202 log->stats[type].sampled_overflow += full_cnt - prev_full_cnt;
251 203
252 if (full_cnt < prev_full_cnt) { 204 if (full_cnt < prev_full_cnt) {
253 /* buffer_full_cnt is a 4 bit counter */ 205 /* buffer_full_cnt is a 4 bit counter */
254 guc->log.total_overflow_count[type] += 16; 206 log->stats[type].sampled_overflow += 16;
255 } 207 }
256 DRM_ERROR_RATELIMITED("GuC log buffer overflow\n"); 208 DRM_ERROR_RATELIMITED("GuC log buffer overflow\n");
257 } 209 }
@@ -275,7 +227,7 @@ static unsigned int guc_get_log_buffer_size(enum guc_log_buffer_type type)
275 return 0; 227 return 0;
276} 228}
277 229
278static void guc_read_update_log_buffer(struct intel_guc *guc) 230static void guc_read_update_log_buffer(struct intel_guc_log *log)
279{ 231{
280 unsigned int buffer_size, read_offset, write_offset, bytes_to_copy, full_cnt; 232 unsigned int buffer_size, read_offset, write_offset, bytes_to_copy, full_cnt;
281 struct guc_log_buffer_state *log_buf_state, *log_buf_snapshot_state; 233 struct guc_log_buffer_state *log_buf_state, *log_buf_snapshot_state;
@@ -284,16 +236,16 @@ static void guc_read_update_log_buffer(struct intel_guc *guc)
284 void *src_data, *dst_data; 236 void *src_data, *dst_data;
285 bool new_overflow; 237 bool new_overflow;
286 238
287 if (WARN_ON(!guc->log.runtime.buf_addr)) 239 mutex_lock(&log->relay.lock);
288 return;
289 240
290 /* Get the pointer to shared GuC log buffer */ 241 if (WARN_ON(!intel_guc_log_relay_enabled(log)))
291 log_buf_state = src_data = guc->log.runtime.buf_addr; 242 goto out_unlock;
292 243
293 mutex_lock(&guc->log.runtime.relay_lock); 244 /* Get the pointer to shared GuC log buffer */
245 log_buf_state = src_data = log->relay.buf_addr;
294 246
295 /* Get the pointer to local buffer to store the logs */ 247 /* Get the pointer to local buffer to store the logs */
296 log_buf_snapshot_state = dst_data = guc_get_write_buffer(guc); 248 log_buf_snapshot_state = dst_data = guc_get_write_buffer(log);
297 249
298 if (unlikely(!log_buf_snapshot_state)) { 250 if (unlikely(!log_buf_snapshot_state)) {
299 /* 251 /*
@@ -301,10 +253,9 @@ static void guc_read_update_log_buffer(struct intel_guc *guc)
301 * getting consumed by User at a slow rate. 253 * getting consumed by User at a slow rate.
302 */ 254 */
303 DRM_ERROR_RATELIMITED("no sub-buffer to capture logs\n"); 255 DRM_ERROR_RATELIMITED("no sub-buffer to capture logs\n");
304 guc->log.capture_miss_count++; 256 log->relay.full_count++;
305 mutex_unlock(&guc->log.runtime.relay_lock);
306 257
307 return; 258 goto out_unlock;
308 } 259 }
309 260
310 /* Actual logs are present from the 2nd page */ 261 /* Actual logs are present from the 2nd page */
@@ -325,8 +276,8 @@ static void guc_read_update_log_buffer(struct intel_guc *guc)
325 full_cnt = log_buf_state_local.buffer_full_cnt; 276 full_cnt = log_buf_state_local.buffer_full_cnt;
326 277
327 /* Bookkeeping stuff */ 278 /* Bookkeeping stuff */
328 guc->log.flush_count[type] += log_buf_state_local.flush_to_file; 279 log->stats[type].flush += log_buf_state_local.flush_to_file;
329 new_overflow = guc_check_log_buf_overflow(guc, type, full_cnt); 280 new_overflow = guc_check_log_buf_overflow(log, type, full_cnt);
330 281
331 /* Update the state of shared log buffer */ 282 /* Update the state of shared log buffer */
332 log_buf_state->read_ptr = write_offset; 283 log_buf_state->read_ptr = write_offset;
@@ -373,38 +324,35 @@ static void guc_read_update_log_buffer(struct intel_guc *guc)
373 dst_data += buffer_size; 324 dst_data += buffer_size;
374 } 325 }
375 326
376 guc_move_to_next_buf(guc); 327 guc_move_to_next_buf(log);
377 328
378 mutex_unlock(&guc->log.runtime.relay_lock); 329out_unlock:
330 mutex_unlock(&log->relay.lock);
379} 331}
380 332
381static void capture_logs_work(struct work_struct *work) 333static void capture_logs_work(struct work_struct *work)
382{ 334{
383 struct intel_guc *guc = 335 struct intel_guc_log *log =
384 container_of(work, struct intel_guc, log.runtime.flush_work); 336 container_of(work, struct intel_guc_log, relay.flush_work);
385
386 guc_log_capture_logs(guc);
387}
388 337
389static bool guc_log_has_runtime(struct intel_guc *guc) 338 guc_log_capture_logs(log);
390{
391 return guc->log.runtime.buf_addr != NULL;
392} 339}
393 340
394static int guc_log_runtime_create(struct intel_guc *guc) 341static int guc_log_map(struct intel_guc_log *log)
395{ 342{
343 struct intel_guc *guc = log_to_guc(log);
396 struct drm_i915_private *dev_priv = guc_to_i915(guc); 344 struct drm_i915_private *dev_priv = guc_to_i915(guc);
397 void *vaddr; 345 void *vaddr;
398 int ret; 346 int ret;
399 347
400 lockdep_assert_held(&dev_priv->drm.struct_mutex); 348 lockdep_assert_held(&log->relay.lock);
401 349
402 if (!guc->log.vma) 350 if (!log->vma)
403 return -ENODEV; 351 return -ENODEV;
404 352
405 GEM_BUG_ON(guc_log_has_runtime(guc)); 353 mutex_lock(&dev_priv->drm.struct_mutex);
406 354 ret = i915_gem_object_set_to_wc_domain(log->vma->obj, true);
407 ret = i915_gem_object_set_to_wc_domain(guc->log.vma->obj, true); 355 mutex_unlock(&dev_priv->drm.struct_mutex);
408 if (ret) 356 if (ret)
409 return ret; 357 return ret;
410 358
@@ -413,49 +361,40 @@ static int guc_log_runtime_create(struct intel_guc *guc)
413 * buffer pages, so that we can directly get the data 361 * buffer pages, so that we can directly get the data
414 * (up-to-date) from memory. 362 * (up-to-date) from memory.
415 */ 363 */
416 vaddr = i915_gem_object_pin_map(guc->log.vma->obj, I915_MAP_WC); 364 vaddr = i915_gem_object_pin_map(log->vma->obj, I915_MAP_WC);
417 if (IS_ERR(vaddr)) { 365 if (IS_ERR(vaddr)) {
418 DRM_ERROR("Couldn't map log buffer pages %d\n", ret); 366 DRM_ERROR("Couldn't map log buffer pages %d\n", ret);
419 return PTR_ERR(vaddr); 367 return PTR_ERR(vaddr);
420 } 368 }
421 369
422 guc->log.runtime.buf_addr = vaddr; 370 log->relay.buf_addr = vaddr;
423 371
424 return 0; 372 return 0;
425} 373}
426 374
427static void guc_log_runtime_destroy(struct intel_guc *guc) 375static void guc_log_unmap(struct intel_guc_log *log)
428{ 376{
429 /* 377 lockdep_assert_held(&log->relay.lock);
430 * It's possible that the runtime stuff was never allocated because
431 * GuC log was disabled at the boot time.
432 */
433 if (!guc_log_has_runtime(guc))
434 return;
435 378
436 i915_gem_object_unpin_map(guc->log.vma->obj); 379 i915_gem_object_unpin_map(log->vma->obj);
437 guc->log.runtime.buf_addr = NULL; 380 log->relay.buf_addr = NULL;
438} 381}
439 382
440void intel_guc_log_init_early(struct intel_guc *guc) 383void intel_guc_log_init_early(struct intel_guc_log *log)
441{ 384{
442 mutex_init(&guc->log.runtime.relay_lock); 385 mutex_init(&log->relay.lock);
443 INIT_WORK(&guc->log.runtime.flush_work, capture_logs_work); 386 INIT_WORK(&log->relay.flush_work, capture_logs_work);
444} 387}
445 388
446int intel_guc_log_relay_create(struct intel_guc *guc) 389static int guc_log_relay_create(struct intel_guc_log *log)
447{ 390{
391 struct intel_guc *guc = log_to_guc(log);
448 struct drm_i915_private *dev_priv = guc_to_i915(guc); 392 struct drm_i915_private *dev_priv = guc_to_i915(guc);
449 struct rchan *guc_log_relay_chan; 393 struct rchan *guc_log_relay_chan;
450 size_t n_subbufs, subbuf_size; 394 size_t n_subbufs, subbuf_size;
451 int ret; 395 int ret;
452 396
453 if (!i915_modparams.guc_log_level) 397 lockdep_assert_held(&log->relay.lock);
454 return 0;
455
456 mutex_lock(&guc->log.runtime.relay_lock);
457
458 GEM_BUG_ON(guc_log_has_relay(guc));
459 398
460 /* Keep the size of sub buffers same as shared log buffer */ 399 /* Keep the size of sub buffers same as shared log buffer */
461 subbuf_size = GUC_LOG_SIZE; 400 subbuf_size = GUC_LOG_SIZE;
@@ -468,157 +407,56 @@ int intel_guc_log_relay_create(struct intel_guc *guc)
468 */ 407 */
469 n_subbufs = 8; 408 n_subbufs = 8;
470 409
471 /* 410 guc_log_relay_chan = relay_open("guc_log",
472 * Create a relay channel, so that we have buffers for storing 411 dev_priv->drm.primary->debugfs_root,
473 * the GuC firmware logs, the channel will be linked with a file 412 subbuf_size, n_subbufs,
474 * later on when debugfs is registered. 413 &relay_callbacks, dev_priv);
475 */
476 guc_log_relay_chan = relay_open(NULL, NULL, subbuf_size,
477 n_subbufs, &relay_callbacks, dev_priv);
478 if (!guc_log_relay_chan) { 414 if (!guc_log_relay_chan) {
479 DRM_ERROR("Couldn't create relay chan for GuC logging\n"); 415 DRM_ERROR("Couldn't create relay chan for GuC logging\n");
480 416
481 ret = -ENOMEM; 417 ret = -ENOMEM;
482 goto err; 418 return ret;
483 } 419 }
484 420
485 GEM_BUG_ON(guc_log_relay_chan->subbuf_size < subbuf_size); 421 GEM_BUG_ON(guc_log_relay_chan->subbuf_size < subbuf_size);
486 guc->log.runtime.relay_chan = guc_log_relay_chan; 422 log->relay.channel = guc_log_relay_chan;
487
488 mutex_unlock(&guc->log.runtime.relay_lock);
489 423
490 return 0; 424 return 0;
491
492err:
493 mutex_unlock(&guc->log.runtime.relay_lock);
494 /* logging will be off */
495 i915_modparams.guc_log_level = 0;
496 return ret;
497}
498
499void intel_guc_log_relay_destroy(struct intel_guc *guc)
500{
501 mutex_lock(&guc->log.runtime.relay_lock);
502
503 /*
504 * It's possible that the relay was never allocated because
505 * GuC log was disabled at the boot time.
506 */
507 if (!guc_log_has_relay(guc))
508 goto out_unlock;
509
510 relay_close(guc->log.runtime.relay_chan);
511 guc->log.runtime.relay_chan = NULL;
512
513out_unlock:
514 mutex_unlock(&guc->log.runtime.relay_lock);
515} 425}
516 426
517static int guc_log_late_setup(struct intel_guc *guc) 427static void guc_log_relay_destroy(struct intel_guc_log *log)
518{ 428{
519 struct drm_i915_private *dev_priv = guc_to_i915(guc); 429 lockdep_assert_held(&log->relay.lock);
520 int ret;
521
522 if (!guc_log_has_runtime(guc)) {
523 /*
524 * If log was disabled at boot time, then setup needed to handle
525 * log buffer flush interrupts would not have been done yet, so
526 * do that now.
527 */
528 ret = intel_guc_log_relay_create(guc);
529 if (ret)
530 goto err;
531
532 mutex_lock(&dev_priv->drm.struct_mutex);
533 intel_runtime_pm_get(dev_priv);
534 ret = guc_log_runtime_create(guc);
535 intel_runtime_pm_put(dev_priv);
536 mutex_unlock(&dev_priv->drm.struct_mutex);
537
538 if (ret)
539 goto err_relay;
540 }
541
542 ret = guc_log_relay_file_create(guc);
543 if (ret)
544 goto err_runtime;
545
546 return 0;
547 430
548err_runtime: 431 relay_close(log->relay.channel);
549 mutex_lock(&dev_priv->drm.struct_mutex); 432 log->relay.channel = NULL;
550 guc_log_runtime_destroy(guc);
551 mutex_unlock(&dev_priv->drm.struct_mutex);
552err_relay:
553 intel_guc_log_relay_destroy(guc);
554err:
555 /* logging will remain off */
556 i915_modparams.guc_log_level = 0;
557 return ret;
558} 433}
559 434
560static void guc_log_capture_logs(struct intel_guc *guc) 435static void guc_log_capture_logs(struct intel_guc_log *log)
561{ 436{
437 struct intel_guc *guc = log_to_guc(log);
562 struct drm_i915_private *dev_priv = guc_to_i915(guc); 438 struct drm_i915_private *dev_priv = guc_to_i915(guc);
563 439
564 guc_read_update_log_buffer(guc); 440 guc_read_update_log_buffer(log);
565 441
566 /* 442 /*
567 * Generally device is expected to be active only at this 443 * Generally device is expected to be active only at this
568 * time, so get/put should be really quick. 444 * time, so get/put should be really quick.
569 */ 445 */
570 intel_runtime_pm_get(dev_priv); 446 intel_runtime_pm_get(dev_priv);
571 guc_log_flush_complete(guc); 447 guc_action_flush_log_complete(guc);
572 intel_runtime_pm_put(dev_priv);
573}
574
575static void guc_flush_logs(struct intel_guc *guc)
576{
577 struct drm_i915_private *dev_priv = guc_to_i915(guc);
578
579 if (!USES_GUC_SUBMISSION(dev_priv) || !i915_modparams.guc_log_level)
580 return;
581
582 /* First disable the interrupts, will be renabled afterwards */
583 mutex_lock(&dev_priv->drm.struct_mutex);
584 intel_runtime_pm_get(dev_priv);
585 gen9_disable_guc_interrupts(dev_priv);
586 intel_runtime_pm_put(dev_priv);
587 mutex_unlock(&dev_priv->drm.struct_mutex);
588
589 /*
590 * Before initiating the forceful flush, wait for any pending/ongoing
591 * flush to complete otherwise forceful flush may not actually happen.
592 */
593 flush_work(&guc->log.runtime.flush_work);
594
595 /* Ask GuC to update the log buffer state */
596 intel_runtime_pm_get(dev_priv);
597 guc_log_flush(guc);
598 intel_runtime_pm_put(dev_priv); 448 intel_runtime_pm_put(dev_priv);
599
600 /* GuC would have updated log buffer by now, so capture it */
601 guc_log_capture_logs(guc);
602} 449}
603 450
604int intel_guc_log_create(struct intel_guc *guc) 451int intel_guc_log_create(struct intel_guc_log *log)
605{ 452{
453 struct intel_guc *guc = log_to_guc(log);
606 struct i915_vma *vma; 454 struct i915_vma *vma;
607 unsigned long offset; 455 unsigned long offset;
608 u32 flags; 456 u32 flags;
609 int ret; 457 int ret;
610 458
611 GEM_BUG_ON(guc->log.vma); 459 GEM_BUG_ON(log->vma);
612
613 /*
614 * We require SSE 4.1 for fast reads from the GuC log buffer and
615 * it should be present on the chipsets supporting GuC based
616 * submisssions.
617 */
618 if (WARN_ON(!i915_has_memcpy_from_wc())) {
619 ret = -EINVAL;
620 goto err;
621 }
622 460
623 vma = intel_guc_allocate_vma(guc, GUC_LOG_SIZE); 461 vma = intel_guc_allocate_vma(guc, GUC_LOG_SIZE);
624 if (IS_ERR(vma)) { 462 if (IS_ERR(vma)) {
@@ -626,13 +464,7 @@ int intel_guc_log_create(struct intel_guc *guc)
626 goto err; 464 goto err;
627 } 465 }
628 466
629 guc->log.vma = vma; 467 log->vma = vma;
630
631 if (i915_modparams.guc_log_level) {
632 ret = guc_log_runtime_create(guc);
633 if (ret < 0)
634 goto err_vma;
635 }
636 468
637 /* each allocated unit is a page */ 469 /* each allocated unit is a page */
638 flags = GUC_LOG_VALID | GUC_LOG_NOTIFY_ON_HALF_FULL | 470 flags = GUC_LOG_VALID | GUC_LOG_NOTIFY_ON_HALF_FULL |
@@ -640,117 +472,159 @@ int intel_guc_log_create(struct intel_guc *guc)
640 (GUC_LOG_ISR_PAGES << GUC_LOG_ISR_SHIFT) | 472 (GUC_LOG_ISR_PAGES << GUC_LOG_ISR_SHIFT) |
641 (GUC_LOG_CRASH_PAGES << GUC_LOG_CRASH_SHIFT); 473 (GUC_LOG_CRASH_PAGES << GUC_LOG_CRASH_SHIFT);
642 474
643 offset = guc_ggtt_offset(vma) >> PAGE_SHIFT; /* in pages */ 475 offset = intel_guc_ggtt_offset(guc, vma) >> PAGE_SHIFT;
644 guc->log.flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags; 476 log->flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags;
645 477
646 return 0; 478 return 0;
647 479
648err_vma:
649 i915_vma_unpin_and_release(&guc->log.vma);
650err: 480err:
651 /* logging will be off */ 481 /* logging will be off */
652 i915_modparams.guc_log_level = 0; 482 i915_modparams.guc_log_level = 0;
653 return ret; 483 return ret;
654} 484}
655 485
656void intel_guc_log_destroy(struct intel_guc *guc) 486void intel_guc_log_destroy(struct intel_guc_log *log)
487{
488 i915_vma_unpin_and_release(&log->vma);
489}
490
491int intel_guc_log_level_get(struct intel_guc_log *log)
657{ 492{
658 guc_log_runtime_destroy(guc); 493 GEM_BUG_ON(!log->vma);
659 i915_vma_unpin_and_release(&guc->log.vma); 494 GEM_BUG_ON(i915_modparams.guc_log_level < 0);
495
496 return i915_modparams.guc_log_level;
660} 497}
661 498
662int intel_guc_log_control(struct intel_guc *guc, u64 control_val) 499int intel_guc_log_level_set(struct intel_guc_log *log, u64 val)
663{ 500{
501 struct intel_guc *guc = log_to_guc(log);
664 struct drm_i915_private *dev_priv = guc_to_i915(guc); 502 struct drm_i915_private *dev_priv = guc_to_i915(guc);
665 bool enable_logging = control_val > 0;
666 u32 verbosity;
667 int ret; 503 int ret;
668 504
669 if (!guc->log.vma) 505 BUILD_BUG_ON(GUC_LOG_VERBOSITY_MIN != 0);
670 return -ENODEV; 506 GEM_BUG_ON(!log->vma);
507 GEM_BUG_ON(i915_modparams.guc_log_level < 0);
671 508
672 BUILD_BUG_ON(GUC_LOG_VERBOSITY_MIN); 509 /*
673 if (control_val > 1 + GUC_LOG_VERBOSITY_MAX) 510 * GuC is recognizing log levels starting from 0 to max, we're using 0
511 * as indication that logging should be disabled.
512 */
513 if (val < GUC_LOG_LEVEL_DISABLED || val > GUC_LOG_LEVEL_MAX)
674 return -EINVAL; 514 return -EINVAL;
675 515
676 /* This combination doesn't make sense & won't have any effect */ 516 mutex_lock(&dev_priv->drm.struct_mutex);
677 if (!enable_logging && !i915_modparams.guc_log_level)
678 return 0;
679 517
680 verbosity = enable_logging ? control_val - 1 : 0; 518 if (i915_modparams.guc_log_level == val) {
519 ret = 0;
520 goto out_unlock;
521 }
681 522
682 ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex);
683 if (ret)
684 return ret;
685 intel_runtime_pm_get(dev_priv); 523 intel_runtime_pm_get(dev_priv);
686 ret = guc_log_control(guc, enable_logging, verbosity); 524 ret = guc_action_control_log(guc, GUC_LOG_LEVEL_IS_VERBOSE(val),
525 GUC_LOG_LEVEL_IS_ENABLED(val),
526 GUC_LOG_LEVEL_TO_VERBOSITY(val));
687 intel_runtime_pm_put(dev_priv); 527 intel_runtime_pm_put(dev_priv);
528 if (ret) {
529 DRM_DEBUG_DRIVER("guc_log_control action failed %d\n", ret);
530 goto out_unlock;
531 }
532
533 i915_modparams.guc_log_level = val;
534
535out_unlock:
688 mutex_unlock(&dev_priv->drm.struct_mutex); 536 mutex_unlock(&dev_priv->drm.struct_mutex);
689 537
690 if (ret < 0) { 538 return ret;
691 DRM_DEBUG_DRIVER("guc_logging_control action failed %d\n", ret); 539}
692 return ret;
693 }
694 540
695 if (enable_logging) { 541bool intel_guc_log_relay_enabled(const struct intel_guc_log *log)
696 i915_modparams.guc_log_level = 1 + verbosity; 542{
543 return log->relay.buf_addr;
544}
697 545
698 /* 546int intel_guc_log_relay_open(struct intel_guc_log *log)
699 * If log was disabled at boot time, then the relay channel file 547{
700 * wouldn't have been created by now and interrupts also would 548 int ret;
701 * not have been enabled. Try again now, just in case.
702 */
703 ret = guc_log_late_setup(guc);
704 if (ret < 0) {
705 DRM_DEBUG_DRIVER("GuC log late setup failed %d\n", ret);
706 return ret;
707 }
708 549
709 /* GuC logging is currently the only user of Guc2Host interrupts */ 550 mutex_lock(&log->relay.lock);
710 mutex_lock(&dev_priv->drm.struct_mutex);
711 intel_runtime_pm_get(dev_priv);
712 gen9_enable_guc_interrupts(dev_priv);
713 intel_runtime_pm_put(dev_priv);
714 mutex_unlock(&dev_priv->drm.struct_mutex);
715 } else {
716 /*
717 * Once logging is disabled, GuC won't generate logs & send an
718 * interrupt. But there could be some data in the log buffer
719 * which is yet to be captured. So request GuC to update the log
720 * buffer state and then collect the left over logs.
721 */
722 guc_flush_logs(guc);
723 551
724 /* As logging is disabled, update log level to reflect that */ 552 if (intel_guc_log_relay_enabled(log)) {
725 i915_modparams.guc_log_level = 0; 553 ret = -EEXIST;
554 goto out_unlock;
726 } 555 }
727 556
728 return ret; 557 /*
729} 558 * We require SSE 4.1 for fast reads from the GuC log buffer and
559 * it should be present on the chipsets supporting GuC based
560 * submisssions.
561 */
562 if (!i915_has_memcpy_from_wc()) {
563 ret = -ENXIO;
564 goto out_unlock;
565 }
730 566
731void i915_guc_log_register(struct drm_i915_private *dev_priv) 567 ret = guc_log_relay_create(log);
732{ 568 if (ret)
733 if (!USES_GUC_SUBMISSION(dev_priv) || !i915_modparams.guc_log_level) 569 goto out_unlock;
734 return; 570
571 ret = guc_log_map(log);
572 if (ret)
573 goto out_relay;
735 574
736 guc_log_late_setup(&dev_priv->guc); 575 mutex_unlock(&log->relay.lock);
576
577 guc_log_enable_flush_events(log);
578
579 /*
580 * When GuC is logging without us relaying to userspace, we're ignoring
581 * the flush notification. This means that we need to unconditionally
582 * flush on relay enabling, since GuC only notifies us once.
583 */
584 queue_work(log->relay.flush_wq, &log->relay.flush_work);
585
586 return 0;
587
588out_relay:
589 guc_log_relay_destroy(log);
590out_unlock:
591 mutex_unlock(&log->relay.lock);
592
593 return ret;
737} 594}
738 595
739void i915_guc_log_unregister(struct drm_i915_private *dev_priv) 596void intel_guc_log_relay_flush(struct intel_guc_log *log)
740{ 597{
741 struct intel_guc *guc = &dev_priv->guc; 598 struct intel_guc *guc = log_to_guc(log);
599 struct drm_i915_private *i915 = guc_to_i915(guc);
600
601 /*
602 * Before initiating the forceful flush, wait for any pending/ongoing
603 * flush to complete otherwise forceful flush may not actually happen.
604 */
605 flush_work(&log->relay.flush_work);
742 606
743 if (!USES_GUC_SUBMISSION(dev_priv)) 607 intel_runtime_pm_get(i915);
744 return; 608 guc_action_flush_log(guc);
609 intel_runtime_pm_put(i915);
745 610
746 mutex_lock(&dev_priv->drm.struct_mutex); 611 /* GuC would have updated log buffer by now, so capture it */
747 /* GuC logging is currently the only user of Guc2Host interrupts */ 612 guc_log_capture_logs(log);
748 intel_runtime_pm_get(dev_priv); 613}
749 gen9_disable_guc_interrupts(dev_priv);
750 intel_runtime_pm_put(dev_priv);
751 614
752 guc_log_runtime_destroy(guc); 615void intel_guc_log_relay_close(struct intel_guc_log *log)
753 mutex_unlock(&dev_priv->drm.struct_mutex); 616{
617 guc_log_disable_flush_events(log);
618 flush_work(&log->relay.flush_work);
619
620 mutex_lock(&log->relay.lock);
621 GEM_BUG_ON(!intel_guc_log_relay_enabled(log));
622 guc_log_unmap(log);
623 guc_log_relay_destroy(log);
624 mutex_unlock(&log->relay.lock);
625}
754 626
755 intel_guc_log_relay_destroy(guc); 627void intel_guc_log_handle_flush_event(struct intel_guc_log *log)
628{
629 queue_work(log->relay.flush_wq, &log->relay.flush_work);
756} 630}
diff --git a/drivers/gpu/drm/i915/intel_guc_log.h b/drivers/gpu/drm/i915/intel_guc_log.h
index dab0e949567a..fa80535a6f9d 100644
--- a/drivers/gpu/drm/i915/intel_guc_log.h
+++ b/drivers/gpu/drm/i915/intel_guc_log.h
@@ -25,11 +25,12 @@
25#ifndef _INTEL_GUC_LOG_H_ 25#ifndef _INTEL_GUC_LOG_H_
26#define _INTEL_GUC_LOG_H_ 26#define _INTEL_GUC_LOG_H_
27 27
28#include <linux/mutex.h>
29#include <linux/relay.h>
28#include <linux/workqueue.h> 30#include <linux/workqueue.h>
29 31
30#include "intel_guc_fwif.h" 32#include "intel_guc_fwif.h"
31 33
32struct drm_i915_private;
33struct intel_guc; 34struct intel_guc;
34 35
35/* 36/*
@@ -39,33 +40,53 @@ struct intel_guc;
39#define GUC_LOG_SIZE ((1 + GUC_LOG_DPC_PAGES + 1 + GUC_LOG_ISR_PAGES + \ 40#define GUC_LOG_SIZE ((1 + GUC_LOG_DPC_PAGES + 1 + GUC_LOG_ISR_PAGES + \
40 1 + GUC_LOG_CRASH_PAGES + 1) << PAGE_SHIFT) 41 1 + GUC_LOG_CRASH_PAGES + 1) << PAGE_SHIFT)
41 42
43/*
44 * While we're using plain log level in i915, GuC controls are much more...
45 * "elaborate"? We have a couple of bits for verbosity, separate bit for actual
46 * log enabling, and separate bit for default logging - which "conveniently"
47 * ignores the enable bit.
48 */
49#define GUC_LOG_LEVEL_DISABLED 0
50#define GUC_LOG_LEVEL_NON_VERBOSE 1
51#define GUC_LOG_LEVEL_IS_ENABLED(x) ((x) > GUC_LOG_LEVEL_DISABLED)
52#define GUC_LOG_LEVEL_IS_VERBOSE(x) ((x) > GUC_LOG_LEVEL_NON_VERBOSE)
53#define GUC_LOG_LEVEL_TO_VERBOSITY(x) ({ \
54 typeof(x) _x = (x); \
55 GUC_LOG_LEVEL_IS_VERBOSE(_x) ? _x - 2 : 0; \
56})
57#define GUC_VERBOSITY_TO_LOG_LEVEL(x) ((x) + 2)
58#define GUC_LOG_LEVEL_MAX GUC_VERBOSITY_TO_LOG_LEVEL(GUC_LOG_VERBOSITY_MAX)
59
42struct intel_guc_log { 60struct intel_guc_log {
43 u32 flags; 61 u32 flags;
44 struct i915_vma *vma; 62 struct i915_vma *vma;
45 /* The runtime stuff gets created only when GuC logging gets enabled */
46 struct { 63 struct {
47 void *buf_addr; 64 void *buf_addr;
48 struct workqueue_struct *flush_wq; 65 struct workqueue_struct *flush_wq;
49 struct work_struct flush_work; 66 struct work_struct flush_work;
50 struct rchan *relay_chan; 67 struct rchan *channel;
51 /* To serialize the access to relay_chan */ 68 struct mutex lock;
52 struct mutex relay_lock; 69 u32 full_count;
53 } runtime; 70 } relay;
54 /* logging related stats */ 71 /* logging related stats */
55 u32 capture_miss_count; 72 struct {
56 u32 flush_interrupt_count; 73 u32 sampled_overflow;
57 u32 prev_overflow_count[GUC_MAX_LOG_BUFFER]; 74 u32 overflow;
58 u32 total_overflow_count[GUC_MAX_LOG_BUFFER]; 75 u32 flush;
59 u32 flush_count[GUC_MAX_LOG_BUFFER]; 76 } stats[GUC_MAX_LOG_BUFFER];
60}; 77};
61 78
62int intel_guc_log_create(struct intel_guc *guc); 79void intel_guc_log_init_early(struct intel_guc_log *log);
63void intel_guc_log_destroy(struct intel_guc *guc); 80int intel_guc_log_create(struct intel_guc_log *log);
64void intel_guc_log_init_early(struct intel_guc *guc); 81void intel_guc_log_destroy(struct intel_guc_log *log);
65int intel_guc_log_relay_create(struct intel_guc *guc); 82
66void intel_guc_log_relay_destroy(struct intel_guc *guc); 83int intel_guc_log_level_get(struct intel_guc_log *log);
67int intel_guc_log_control(struct intel_guc *guc, u64 control_val); 84int intel_guc_log_level_set(struct intel_guc_log *log, u64 control_val);
68void i915_guc_log_register(struct drm_i915_private *dev_priv); 85bool intel_guc_log_relay_enabled(const struct intel_guc_log *log);
69void i915_guc_log_unregister(struct drm_i915_private *dev_priv); 86int intel_guc_log_relay_open(struct intel_guc_log *log);
87void intel_guc_log_relay_flush(struct intel_guc_log *log);
88void intel_guc_log_relay_close(struct intel_guc_log *log);
89
90void intel_guc_log_handle_flush_event(struct intel_guc_log *log);
70 91
71#endif 92#endif
diff --git a/drivers/gpu/drm/i915/intel_guc_reg.h b/drivers/gpu/drm/i915/intel_guc_reg.h
index 19a9247c5664..d86084742a4a 100644
--- a/drivers/gpu/drm/i915/intel_guc_reg.h
+++ b/drivers/gpu/drm/i915/intel_guc_reg.h
@@ -66,22 +66,20 @@
66#define UOS_MOVE (1<<4) 66#define UOS_MOVE (1<<4)
67#define START_DMA (1<<0) 67#define START_DMA (1<<0)
68#define DMA_GUC_WOPCM_OFFSET _MMIO(0xc340) 68#define DMA_GUC_WOPCM_OFFSET _MMIO(0xc340)
69#define GUC_WOPCM_OFFSET_VALID (1<<0)
69#define HUC_LOADING_AGENT_VCR (0<<1) 70#define HUC_LOADING_AGENT_VCR (0<<1)
70#define HUC_LOADING_AGENT_GUC (1<<1) 71#define HUC_LOADING_AGENT_GUC (1<<1)
71#define GUC_WOPCM_OFFSET_VALUE 0x80000 /* 512KB */ 72#define GUC_WOPCM_OFFSET_SHIFT 14
73#define GUC_WOPCM_OFFSET_MASK (0x3ffff << GUC_WOPCM_OFFSET_SHIFT)
72#define GUC_MAX_IDLE_COUNT _MMIO(0xC3E4) 74#define GUC_MAX_IDLE_COUNT _MMIO(0xC3E4)
73 75
74#define HUC_STATUS2 _MMIO(0xD3B0) 76#define HUC_STATUS2 _MMIO(0xD3B0)
75#define HUC_FW_VERIFIED (1<<7) 77#define HUC_FW_VERIFIED (1<<7)
76 78
77/* Defines WOPCM space available to GuC firmware */
78#define GUC_WOPCM_SIZE _MMIO(0xc050) 79#define GUC_WOPCM_SIZE _MMIO(0xc050)
79/* GuC addresses below GUC_WOPCM_TOP don't map through the GTT */ 80#define GUC_WOPCM_SIZE_LOCKED (1<<0)
80#define GUC_WOPCM_TOP (0x80 << 12) /* 512KB */ 81#define GUC_WOPCM_SIZE_SHIFT 12
81#define BXT_GUC_WOPCM_RC6_RESERVED (0x10 << 12) /* 64KB */ 82#define GUC_WOPCM_SIZE_MASK (0xfffff << GUC_WOPCM_SIZE_SHIFT)
82
83/* GuC addresses above GUC_GGTT_TOP also don't map through the GTT */
84#define GUC_GGTT_TOP 0xFEE00000
85 83
86#define GEN8_GT_PM_CONFIG _MMIO(0x138140) 84#define GEN8_GT_PM_CONFIG _MMIO(0x138140)
87#define GEN9LP_GT_PM_CONFIG _MMIO(0x138140) 85#define GEN9LP_GT_PM_CONFIG _MMIO(0x138140)
diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
index 8a8ad2fe158d..2feb65096966 100644
--- a/drivers/gpu/drm/i915/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/intel_guc_submission.c
@@ -124,9 +124,17 @@ static int reserve_doorbell(struct intel_guc_client *client)
124 return 0; 124 return 0;
125} 125}
126 126
127static bool has_doorbell(struct intel_guc_client *client)
128{
129 if (client->doorbell_id == GUC_DOORBELL_INVALID)
130 return false;
131
132 return test_bit(client->doorbell_id, client->guc->doorbell_bitmap);
133}
134
127static void unreserve_doorbell(struct intel_guc_client *client) 135static void unreserve_doorbell(struct intel_guc_client *client)
128{ 136{
129 GEM_BUG_ON(client->doorbell_id == GUC_DOORBELL_INVALID); 137 GEM_BUG_ON(!has_doorbell(client));
130 138
131 __clear_bit(client->doorbell_id, client->guc->doorbell_bitmap); 139 __clear_bit(client->doorbell_id, client->guc->doorbell_bitmap);
132 client->doorbell_id = GUC_DOORBELL_INVALID; 140 client->doorbell_id = GUC_DOORBELL_INVALID;
@@ -184,14 +192,6 @@ static struct guc_doorbell_info *__get_doorbell(struct intel_guc_client *client)
184 return client->vaddr + client->doorbell_offset; 192 return client->vaddr + client->doorbell_offset;
185} 193}
186 194
187static bool has_doorbell(struct intel_guc_client *client)
188{
189 if (client->doorbell_id == GUC_DOORBELL_INVALID)
190 return false;
191
192 return test_bit(client->doorbell_id, client->guc->doorbell_bitmap);
193}
194
195static void __create_doorbell(struct intel_guc_client *client) 195static void __create_doorbell(struct intel_guc_client *client)
196{ 196{
197 struct guc_doorbell_info *doorbell; 197 struct guc_doorbell_info *doorbell;
@@ -207,7 +207,6 @@ static void __destroy_doorbell(struct intel_guc_client *client)
207 struct guc_doorbell_info *doorbell; 207 struct guc_doorbell_info *doorbell;
208 u16 db_id = client->doorbell_id; 208 u16 db_id = client->doorbell_id;
209 209
210
211 doorbell = __get_doorbell(client); 210 doorbell = __get_doorbell(client);
212 doorbell->db_status = GUC_DOORBELL_DISABLED; 211 doorbell->db_status = GUC_DOORBELL_DISABLED;
213 doorbell->cookie = 0; 212 doorbell->cookie = 0;
@@ -224,6 +223,9 @@ static int create_doorbell(struct intel_guc_client *client)
224{ 223{
225 int ret; 224 int ret;
226 225
226 if (WARN_ON(!has_doorbell(client)))
227 return -ENODEV; /* internal setup error, should never happen */
228
227 __update_doorbell_desc(client, client->doorbell_id); 229 __update_doorbell_desc(client, client->doorbell_id);
228 __create_doorbell(client); 230 __create_doorbell(client);
229 231
@@ -231,8 +233,8 @@ static int create_doorbell(struct intel_guc_client *client)
231 if (ret) { 233 if (ret) {
232 __destroy_doorbell(client); 234 __destroy_doorbell(client);
233 __update_doorbell_desc(client, GUC_DOORBELL_INVALID); 235 __update_doorbell_desc(client, GUC_DOORBELL_INVALID);
234 DRM_ERROR("Couldn't create client %u doorbell: %d\n", 236 DRM_DEBUG_DRIVER("Couldn't create client %u doorbell: %d\n",
235 client->stage_id, ret); 237 client->stage_id, ret);
236 return ret; 238 return ret;
237 } 239 }
238 240
@@ -362,7 +364,7 @@ static void guc_stage_desc_init(struct intel_guc *guc,
362 desc->db_id = client->doorbell_id; 364 desc->db_id = client->doorbell_id;
363 365
364 for_each_engine_masked(engine, dev_priv, client->engines, tmp) { 366 for_each_engine_masked(engine, dev_priv, client->engines, tmp) {
365 struct intel_context *ce = &ctx->engine[engine->id]; 367 struct intel_context *ce = to_intel_context(ctx, engine);
366 u32 guc_engine_id = engine->guc_id; 368 u32 guc_engine_id = engine->guc_id;
367 struct guc_execlist_context *lrc = &desc->lrc[guc_engine_id]; 369 struct guc_execlist_context *lrc = &desc->lrc[guc_engine_id];
368 370
@@ -386,8 +388,8 @@ static void guc_stage_desc_init(struct intel_guc *guc,
386 lrc->context_desc = lower_32_bits(ce->lrc_desc); 388 lrc->context_desc = lower_32_bits(ce->lrc_desc);
387 389
388 /* The state page is after PPHWSP */ 390 /* The state page is after PPHWSP */
389 lrc->ring_lrca = 391 lrc->ring_lrca = intel_guc_ggtt_offset(guc, ce->state) +
390 guc_ggtt_offset(ce->state) + LRC_STATE_PN * PAGE_SIZE; 392 LRC_STATE_PN * PAGE_SIZE;
391 393
392 /* XXX: In direct submission, the GuC wants the HW context id 394 /* XXX: In direct submission, the GuC wants the HW context id
393 * here. In proxy submission, it wants the stage id 395 * here. In proxy submission, it wants the stage id
@@ -395,7 +397,7 @@ static void guc_stage_desc_init(struct intel_guc *guc,
395 lrc->context_id = (client->stage_id << GUC_ELC_CTXID_OFFSET) | 397 lrc->context_id = (client->stage_id << GUC_ELC_CTXID_OFFSET) |
396 (guc_engine_id << GUC_ELC_ENGINE_OFFSET); 398 (guc_engine_id << GUC_ELC_ENGINE_OFFSET);
397 399
398 lrc->ring_begin = guc_ggtt_offset(ce->ring->vma); 400 lrc->ring_begin = intel_guc_ggtt_offset(guc, ce->ring->vma);
399 lrc->ring_end = lrc->ring_begin + ce->ring->size - 1; 401 lrc->ring_end = lrc->ring_begin + ce->ring->size - 1;
400 lrc->ring_next_free_location = lrc->ring_begin; 402 lrc->ring_next_free_location = lrc->ring_begin;
401 lrc->ring_current_tail_pointer_value = 0; 403 lrc->ring_current_tail_pointer_value = 0;
@@ -411,7 +413,7 @@ static void guc_stage_desc_init(struct intel_guc *guc,
411 * The doorbell, process descriptor, and workqueue are all parts 413 * The doorbell, process descriptor, and workqueue are all parts
412 * of the client object, which the GuC will reference via the GGTT 414 * of the client object, which the GuC will reference via the GGTT
413 */ 415 */
414 gfx_addr = guc_ggtt_offset(client->vma); 416 gfx_addr = intel_guc_ggtt_offset(guc, client->vma);
415 desc->db_trigger_phy = sg_dma_address(client->vma->pages->sgl) + 417 desc->db_trigger_phy = sg_dma_address(client->vma->pages->sgl) +
416 client->doorbell_offset; 418 client->doorbell_offset;
417 desc->db_trigger_cpu = ptr_to_u64(__get_doorbell(client)); 419 desc->db_trigger_cpu = ptr_to_u64(__get_doorbell(client));
@@ -584,7 +586,7 @@ static void inject_preempt_context(struct work_struct *work)
584 data[3] = engine->guc_id; 586 data[3] = engine->guc_id;
585 data[4] = guc->execbuf_client->priority; 587 data[4] = guc->execbuf_client->priority;
586 data[5] = guc->execbuf_client->stage_id; 588 data[5] = guc->execbuf_client->stage_id;
587 data[6] = guc_ggtt_offset(guc->shared_data); 589 data[6] = intel_guc_ggtt_offset(guc, guc->shared_data);
588 590
589 if (WARN_ON(intel_guc_send(guc, data, ARRAY_SIZE(data)))) { 591 if (WARN_ON(intel_guc_send(guc, data, ARRAY_SIZE(data)))) {
590 execlists_clear_active(&engine->execlists, 592 execlists_clear_active(&engine->execlists,
@@ -657,7 +659,17 @@ static void port_assign(struct execlist_port *port, struct i915_request *rq)
657 port_set(port, i915_request_get(rq)); 659 port_set(port, i915_request_get(rq));
658} 660}
659 661
660static void guc_dequeue(struct intel_engine_cs *engine) 662static inline int rq_prio(const struct i915_request *rq)
663{
664 return rq->sched.attr.priority;
665}
666
667static inline int port_prio(const struct execlist_port *port)
668{
669 return rq_prio(port_request(port));
670}
671
672static bool __guc_dequeue(struct intel_engine_cs *engine)
661{ 673{
662 struct intel_engine_execlists * const execlists = &engine->execlists; 674 struct intel_engine_execlists * const execlists = &engine->execlists;
663 struct execlist_port *port = execlists->port; 675 struct execlist_port *port = execlists->port;
@@ -667,28 +679,29 @@ static void guc_dequeue(struct intel_engine_cs *engine)
667 bool submit = false; 679 bool submit = false;
668 struct rb_node *rb; 680 struct rb_node *rb;
669 681
670 spin_lock_irq(&engine->timeline->lock); 682 lockdep_assert_held(&engine->timeline.lock);
683
671 rb = execlists->first; 684 rb = execlists->first;
672 GEM_BUG_ON(rb_first(&execlists->queue) != rb); 685 GEM_BUG_ON(rb_first(&execlists->queue) != rb);
673 686
674 if (port_isset(port)) { 687 if (port_isset(port)) {
675 if (engine->i915->preempt_context) { 688 if (intel_engine_has_preemption(engine)) {
676 struct guc_preempt_work *preempt_work = 689 struct guc_preempt_work *preempt_work =
677 &engine->i915->guc.preempt_work[engine->id]; 690 &engine->i915->guc.preempt_work[engine->id];
691 int prio = execlists->queue_priority;
678 692
679 if (execlists->queue_priority > 693 if (__execlists_need_preempt(prio, port_prio(port))) {
680 max(port_request(port)->priotree.priority, 0)) {
681 execlists_set_active(execlists, 694 execlists_set_active(execlists,
682 EXECLISTS_ACTIVE_PREEMPT); 695 EXECLISTS_ACTIVE_PREEMPT);
683 queue_work(engine->i915->guc.preempt_wq, 696 queue_work(engine->i915->guc.preempt_wq,
684 &preempt_work->work); 697 &preempt_work->work);
685 goto unlock; 698 return false;
686 } 699 }
687 } 700 }
688 701
689 port++; 702 port++;
690 if (port_isset(port)) 703 if (port_isset(port))
691 goto unlock; 704 return false;
692 } 705 }
693 GEM_BUG_ON(port_isset(port)); 706 GEM_BUG_ON(port_isset(port));
694 707
@@ -696,11 +709,11 @@ static void guc_dequeue(struct intel_engine_cs *engine)
696 struct i915_priolist *p = to_priolist(rb); 709 struct i915_priolist *p = to_priolist(rb);
697 struct i915_request *rq, *rn; 710 struct i915_request *rq, *rn;
698 711
699 list_for_each_entry_safe(rq, rn, &p->requests, priotree.link) { 712 list_for_each_entry_safe(rq, rn, &p->requests, sched.link) {
700 if (last && rq->ctx != last->ctx) { 713 if (last && rq->ctx != last->ctx) {
701 if (port == last_port) { 714 if (port == last_port) {
702 __list_del_many(&p->requests, 715 __list_del_many(&p->requests,
703 &rq->priotree.link); 716 &rq->sched.link);
704 goto done; 717 goto done;
705 } 718 }
706 719
@@ -709,7 +722,7 @@ static void guc_dequeue(struct intel_engine_cs *engine)
709 port++; 722 port++;
710 } 723 }
711 724
712 INIT_LIST_HEAD(&rq->priotree.link); 725 INIT_LIST_HEAD(&rq->sched.link);
713 726
714 __i915_request_submit(rq); 727 __i915_request_submit(rq);
715 trace_i915_request_in(rq, port_index(port, execlists)); 728 trace_i915_request_in(rq, port_index(port, execlists));
@@ -726,19 +739,34 @@ static void guc_dequeue(struct intel_engine_cs *engine)
726done: 739done:
727 execlists->queue_priority = rb ? to_priolist(rb)->priority : INT_MIN; 740 execlists->queue_priority = rb ? to_priolist(rb)->priority : INT_MIN;
728 execlists->first = rb; 741 execlists->first = rb;
729 if (submit) { 742 if (submit)
730 port_assign(port, last); 743 port_assign(port, last);
731 execlists_set_active(execlists, EXECLISTS_ACTIVE_USER); 744 if (last)
732 guc_submit(engine); 745 execlists_user_begin(execlists, execlists->port);
733 }
734 746
735 /* We must always keep the beast fed if we have work piled up */ 747 /* We must always keep the beast fed if we have work piled up */
736 GEM_BUG_ON(port_isset(execlists->port) && 748 GEM_BUG_ON(port_isset(execlists->port) &&
737 !execlists_is_active(execlists, EXECLISTS_ACTIVE_USER)); 749 !execlists_is_active(execlists, EXECLISTS_ACTIVE_USER));
738 GEM_BUG_ON(execlists->first && !port_isset(execlists->port)); 750 GEM_BUG_ON(execlists->first && !port_isset(execlists->port));
739 751
740unlock: 752 return submit;
741 spin_unlock_irq(&engine->timeline->lock); 753}
754
755static void guc_dequeue(struct intel_engine_cs *engine)
756{
757 unsigned long flags;
758 bool submit;
759
760 local_irq_save(flags);
761
762 spin_lock(&engine->timeline.lock);
763 submit = __guc_dequeue(engine);
764 spin_unlock(&engine->timeline.lock);
765
766 if (submit)
767 guc_submit(engine);
768
769 local_irq_restore(flags);
742} 770}
743 771
744static void guc_submission_tasklet(unsigned long data) 772static void guc_submission_tasklet(unsigned long data)
@@ -748,17 +776,20 @@ static void guc_submission_tasklet(unsigned long data)
748 struct execlist_port *port = execlists->port; 776 struct execlist_port *port = execlists->port;
749 struct i915_request *rq; 777 struct i915_request *rq;
750 778
751 rq = port_request(&port[0]); 779 rq = port_request(port);
752 while (rq && i915_request_completed(rq)) { 780 while (rq && i915_request_completed(rq)) {
753 trace_i915_request_out(rq); 781 trace_i915_request_out(rq);
754 i915_request_put(rq); 782 i915_request_put(rq);
755 783
756 execlists_port_complete(execlists, port); 784 port = execlists_port_complete(execlists, port);
757 785 if (port_isset(port)) {
758 rq = port_request(&port[0]); 786 execlists_user_begin(execlists, port);
787 rq = port_request(port);
788 } else {
789 execlists_user_end(execlists);
790 rq = NULL;
791 }
759 } 792 }
760 if (!rq)
761 execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
762 793
763 if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) && 794 if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) &&
764 intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX) == 795 intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX) ==
@@ -977,7 +1008,8 @@ static void guc_fill_preempt_context(struct intel_guc *guc)
977 enum intel_engine_id id; 1008 enum intel_engine_id id;
978 1009
979 for_each_engine(engine, dev_priv, id) { 1010 for_each_engine(engine, dev_priv, id) {
980 struct intel_context *ce = &client->owner->engine[id]; 1011 struct intel_context *ce =
1012 to_intel_context(client->owner, engine);
981 u32 addr = intel_hws_preempt_done_address(engine); 1013 u32 addr = intel_hws_preempt_done_address(engine);
982 u32 *cs; 1014 u32 *cs;
983 1015
diff --git a/drivers/gpu/drm/i915/intel_hangcheck.c b/drivers/gpu/drm/i915/intel_hangcheck.c
index c8ea510629fa..d47e346bd49e 100644
--- a/drivers/gpu/drm/i915/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/intel_hangcheck.c
@@ -246,9 +246,8 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd)
246 */ 246 */
247 tmp = I915_READ_CTL(engine); 247 tmp = I915_READ_CTL(engine);
248 if (tmp & RING_WAIT) { 248 if (tmp & RING_WAIT) {
249 i915_handle_error(dev_priv, BIT(engine->id), 249 i915_handle_error(dev_priv, BIT(engine->id), 0,
250 "Kicking stuck wait on %s", 250 "stuck wait on %s", engine->name);
251 engine->name);
252 I915_WRITE_CTL(engine, tmp); 251 I915_WRITE_CTL(engine, tmp);
253 return ENGINE_WAIT_KICK; 252 return ENGINE_WAIT_KICK;
254 } 253 }
@@ -258,8 +257,8 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd)
258 default: 257 default:
259 return ENGINE_DEAD; 258 return ENGINE_DEAD;
260 case 1: 259 case 1:
261 i915_handle_error(dev_priv, ALL_ENGINES, 260 i915_handle_error(dev_priv, ALL_ENGINES, 0,
262 "Kicking stuck semaphore on %s", 261 "stuck semaphore on %s",
263 engine->name); 262 engine->name);
264 I915_WRITE_CTL(engine, tmp); 263 I915_WRITE_CTL(engine, tmp);
265 return ENGINE_WAIT_KICK; 264 return ENGINE_WAIT_KICK;
@@ -357,7 +356,7 @@ static void hangcheck_accumulate_sample(struct intel_engine_cs *engine,
357 break; 356 break;
358 357
359 case ENGINE_DEAD: 358 case ENGINE_DEAD:
360 if (drm_debug & DRM_UT_DRIVER) { 359 if (GEM_SHOW_DEBUG()) {
361 struct drm_printer p = drm_debug_printer("hangcheck"); 360 struct drm_printer p = drm_debug_printer("hangcheck");
362 intel_engine_dump(engine, &p, "%s\n", engine->name); 361 intel_engine_dump(engine, &p, "%s\n", engine->name);
363 } 362 }
@@ -386,13 +385,13 @@ static void hangcheck_declare_hang(struct drm_i915_private *i915,
386 if (stuck != hung) 385 if (stuck != hung)
387 hung &= ~stuck; 386 hung &= ~stuck;
388 len = scnprintf(msg, sizeof(msg), 387 len = scnprintf(msg, sizeof(msg),
389 "%s on ", stuck == hung ? "No progress" : "Hang"); 388 "%s on ", stuck == hung ? "no progress" : "hang");
390 for_each_engine_masked(engine, i915, hung, tmp) 389 for_each_engine_masked(engine, i915, hung, tmp)
391 len += scnprintf(msg + len, sizeof(msg) - len, 390 len += scnprintf(msg + len, sizeof(msg) - len,
392 "%s, ", engine->name); 391 "%s, ", engine->name);
393 msg[len-2] = '\0'; 392 msg[len-2] = '\0';
394 393
395 return i915_handle_error(i915, hung, "%s", msg); 394 return i915_handle_error(i915, hung, I915_ERROR_CAPTURE, "%s", msg);
396} 395}
397 396
398/* 397/*
@@ -453,6 +452,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work)
453void intel_engine_init_hangcheck(struct intel_engine_cs *engine) 452void intel_engine_init_hangcheck(struct intel_engine_cs *engine)
454{ 453{
455 memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); 454 memset(&engine->hangcheck, 0, sizeof(engine->hangcheck));
455 engine->hangcheck.action_timestamp = jiffies;
456} 456}
457 457
458void intel_hangcheck_init(struct drm_i915_private *i915) 458void intel_hangcheck_init(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 14ca5d3057a7..2db5da550a1c 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -37,6 +37,43 @@ static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port,
37 return 0; 37 return 0;
38} 38}
39 39
40static bool hdcp_key_loadable(struct drm_i915_private *dev_priv)
41{
42 struct i915_power_domains *power_domains = &dev_priv->power_domains;
43 struct i915_power_well *power_well;
44 enum i915_power_well_id id;
45 bool enabled = false;
46
47 /*
48 * On HSW and BDW, Display HW loads the Key as soon as Display resumes.
49 * On all BXT+, SW can load the keys only when the PW#1 is turned on.
50 */
51 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
52 id = HSW_DISP_PW_GLOBAL;
53 else
54 id = SKL_DISP_PW_1;
55
56 mutex_lock(&power_domains->lock);
57
58 /* PG1 (power well #1) needs to be enabled */
59 for_each_power_well(dev_priv, power_well) {
60 if (power_well->id == id) {
61 enabled = power_well->ops->is_enabled(dev_priv,
62 power_well);
63 break;
64 }
65 }
66 mutex_unlock(&power_domains->lock);
67
68 /*
69 * Another req for hdcp key loadability is enabled state of pll for
70 * cdclk. Without active crtc we wont land here. So we are assuming that
71 * cdclk is already on.
72 */
73
74 return enabled;
75}
76
40static void intel_hdcp_clear_keys(struct drm_i915_private *dev_priv) 77static void intel_hdcp_clear_keys(struct drm_i915_private *dev_priv)
41{ 78{
42 I915_WRITE(HDCP_KEY_CONF, HDCP_CLEAR_KEYS_TRIGGER); 79 I915_WRITE(HDCP_KEY_CONF, HDCP_CLEAR_KEYS_TRIGGER);
@@ -142,53 +179,17 @@ bool intel_hdcp_is_ksv_valid(u8 *ksv)
142 return true; 179 return true;
143} 180}
144 181
145/* Implements Part 2 of the HDCP authorization procedure */
146static 182static
147int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port, 183int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
148 const struct intel_hdcp_shim *shim) 184 const struct intel_hdcp_shim *shim,
185 u8 *ksv_fifo, u8 num_downstream, u8 *bstatus)
149{ 186{
150 struct drm_i915_private *dev_priv; 187 struct drm_i915_private *dev_priv;
151 u32 vprime, sha_text, sha_leftovers, rep_ctl; 188 u32 vprime, sha_text, sha_leftovers, rep_ctl;
152 u8 bstatus[2], num_downstream, *ksv_fifo;
153 int ret, i, j, sha_idx; 189 int ret, i, j, sha_idx;
154 190
155 dev_priv = intel_dig_port->base.base.dev->dev_private; 191 dev_priv = intel_dig_port->base.base.dev->dev_private;
156 192
157 ret = intel_hdcp_poll_ksv_fifo(intel_dig_port, shim);
158 if (ret) {
159 DRM_ERROR("KSV list failed to become ready (%d)\n", ret);
160 return ret;
161 }
162
163 ret = shim->read_bstatus(intel_dig_port, bstatus);
164 if (ret)
165 return ret;
166
167 if (DRM_HDCP_MAX_DEVICE_EXCEEDED(bstatus[0]) ||
168 DRM_HDCP_MAX_CASCADE_EXCEEDED(bstatus[1])) {
169 DRM_ERROR("Max Topology Limit Exceeded\n");
170 return -EPERM;
171 }
172
173 /*
174 * When repeater reports 0 device count, HDCP1.4 spec allows disabling
175 * the HDCP encryption. That implies that repeater can't have its own
176 * display. As there is no consumption of encrypted content in the
177 * repeater with 0 downstream devices, we are failing the
178 * authentication.
179 */
180 num_downstream = DRM_HDCP_NUM_DOWNSTREAM(bstatus[0]);
181 if (num_downstream == 0)
182 return -EINVAL;
183
184 ksv_fifo = kzalloc(num_downstream * DRM_HDCP_KSV_LEN, GFP_KERNEL);
185 if (!ksv_fifo)
186 return -ENOMEM;
187
188 ret = shim->read_ksv_fifo(intel_dig_port, num_downstream, ksv_fifo);
189 if (ret)
190 return ret;
191
192 /* Process V' values from the receiver */ 193 /* Process V' values from the receiver */
193 for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++) { 194 for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++) {
194 ret = shim->read_v_prime_part(intel_dig_port, i, &vprime); 195 ret = shim->read_v_prime_part(intel_dig_port, i, &vprime);
@@ -353,7 +354,8 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
353 return ret; 354 return ret;
354 sha_idx += sizeof(sha_text); 355 sha_idx += sizeof(sha_text);
355 } else { 356 } else {
356 DRM_ERROR("Invalid number of leftovers %d\n", sha_leftovers); 357 DRM_DEBUG_KMS("Invalid number of leftovers %d\n",
358 sha_leftovers);
357 return -EINVAL; 359 return -EINVAL;
358 } 360 }
359 361
@@ -381,17 +383,83 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
381 if (intel_wait_for_register(dev_priv, HDCP_REP_CTL, 383 if (intel_wait_for_register(dev_priv, HDCP_REP_CTL,
382 HDCP_SHA1_COMPLETE, 384 HDCP_SHA1_COMPLETE,
383 HDCP_SHA1_COMPLETE, 1)) { 385 HDCP_SHA1_COMPLETE, 1)) {
384 DRM_ERROR("Timed out waiting for SHA1 complete\n"); 386 DRM_DEBUG_KMS("Timed out waiting for SHA1 complete\n");
385 return -ETIMEDOUT; 387 return -ETIMEDOUT;
386 } 388 }
387 if (!(I915_READ(HDCP_REP_CTL) & HDCP_SHA1_V_MATCH)) { 389 if (!(I915_READ(HDCP_REP_CTL) & HDCP_SHA1_V_MATCH)) {
388 DRM_ERROR("SHA-1 mismatch, HDCP failed\n"); 390 DRM_DEBUG_KMS("SHA-1 mismatch, HDCP failed\n");
389 return -ENXIO; 391 return -ENXIO;
390 } 392 }
391 393
394 return 0;
395}
396
397/* Implements Part 2 of the HDCP authorization procedure */
398static
399int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
400 const struct intel_hdcp_shim *shim)
401{
402 u8 bstatus[2], num_downstream, *ksv_fifo;
403 int ret, i, tries = 3;
404
405 ret = intel_hdcp_poll_ksv_fifo(intel_dig_port, shim);
406 if (ret) {
407 DRM_ERROR("KSV list failed to become ready (%d)\n", ret);
408 return ret;
409 }
410
411 ret = shim->read_bstatus(intel_dig_port, bstatus);
412 if (ret)
413 return ret;
414
415 if (DRM_HDCP_MAX_DEVICE_EXCEEDED(bstatus[0]) ||
416 DRM_HDCP_MAX_CASCADE_EXCEEDED(bstatus[1])) {
417 DRM_ERROR("Max Topology Limit Exceeded\n");
418 return -EPERM;
419 }
420
421 /*
422 * When repeater reports 0 device count, HDCP1.4 spec allows disabling
423 * the HDCP encryption. That implies that repeater can't have its own
424 * display. As there is no consumption of encrypted content in the
425 * repeater with 0 downstream devices, we are failing the
426 * authentication.
427 */
428 num_downstream = DRM_HDCP_NUM_DOWNSTREAM(bstatus[0]);
429 if (num_downstream == 0)
430 return -EINVAL;
431
432 ksv_fifo = kzalloc(num_downstream * DRM_HDCP_KSV_LEN, GFP_KERNEL);
433 if (!ksv_fifo)
434 return -ENOMEM;
435
436 ret = shim->read_ksv_fifo(intel_dig_port, num_downstream, ksv_fifo);
437 if (ret)
438 goto err;
439
440 /*
441 * When V prime mismatches, DP Spec mandates re-read of
442 * V prime atleast twice.
443 */
444 for (i = 0; i < tries; i++) {
445 ret = intel_hdcp_validate_v_prime(intel_dig_port, shim,
446 ksv_fifo, num_downstream,
447 bstatus);
448 if (!ret)
449 break;
450 }
451
452 if (i == tries) {
453 DRM_ERROR("V Prime validation failed.(%d)\n", ret);
454 goto err;
455 }
456
392 DRM_DEBUG_KMS("HDCP is enabled (%d downstream devices)\n", 457 DRM_DEBUG_KMS("HDCP is enabled (%d downstream devices)\n",
393 num_downstream); 458 num_downstream);
394 return 0; 459 ret = 0;
460err:
461 kfree(ksv_fifo);
462 return ret;
395} 463}
396 464
397/* Implements Part 1 of the HDCP authorization procedure */ 465/* Implements Part 1 of the HDCP authorization procedure */
@@ -506,15 +574,26 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
506 */ 574 */
507 wait_remaining_ms_from_jiffies(r0_prime_gen_start, 300); 575 wait_remaining_ms_from_jiffies(r0_prime_gen_start, 300);
508 576
509 ri.reg = 0; 577 tries = 3;
510 ret = shim->read_ri_prime(intel_dig_port, ri.shim);
511 if (ret)
512 return ret;
513 I915_WRITE(PORT_HDCP_RPRIME(port), ri.reg);
514 578
515 /* Wait for Ri prime match */ 579 /*
516 if (wait_for(I915_READ(PORT_HDCP_STATUS(port)) & 580 * DP HDCP Spec mandates the two more reattempt to read R0, incase
517 (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) { 581 * of R0 mismatch.
582 */
583 for (i = 0; i < tries; i++) {
584 ri.reg = 0;
585 ret = shim->read_ri_prime(intel_dig_port, ri.shim);
586 if (ret)
587 return ret;
588 I915_WRITE(PORT_HDCP_RPRIME(port), ri.reg);
589
590 /* Wait for Ri prime match */
591 if (!wait_for(I915_READ(PORT_HDCP_STATUS(port)) &
592 (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1))
593 break;
594 }
595
596 if (i == tries) {
518 DRM_ERROR("Timed out waiting for Ri prime match (%x)\n", 597 DRM_ERROR("Timed out waiting for Ri prime match (%x)\n",
519 I915_READ(PORT_HDCP_STATUS(port))); 598 I915_READ(PORT_HDCP_STATUS(port)));
520 return -ETIMEDOUT; 599 return -ETIMEDOUT;
@@ -580,8 +659,8 @@ static int _intel_hdcp_enable(struct intel_connector *connector)
580 DRM_DEBUG_KMS("[%s:%d] HDCP is being enabled...\n", 659 DRM_DEBUG_KMS("[%s:%d] HDCP is being enabled...\n",
581 connector->base.name, connector->base.base.id); 660 connector->base.name, connector->base.base.id);
582 661
583 if (!(I915_READ(SKL_FUSE_STATUS) & SKL_FUSE_PG_DIST_STATUS(1))) { 662 if (!hdcp_key_loadable(dev_priv)) {
584 DRM_ERROR("PG1 is disabled, cannot load keys\n"); 663 DRM_ERROR("HDCP key Load is not possible\n");
585 return -ENXIO; 664 return -ENXIO;
586 } 665 }
587 666
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 1baef4ac7ecb..ee929f31f7db 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2082,41 +2082,33 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
2082 * it enables scrambling. This should be called before enabling the HDMI 2082 * it enables scrambling. This should be called before enabling the HDMI
2083 * 2.0 port, as the sink can choose to disable the scrambling if it doesn't 2083 * 2.0 port, as the sink can choose to disable the scrambling if it doesn't
2084 * detect a scrambled clock within 100 ms. 2084 * detect a scrambled clock within 100 ms.
2085 *
2086 * Returns:
2087 * True on success, false on failure.
2085 */ 2088 */
2086void intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder, 2089bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
2087 struct drm_connector *connector, 2090 struct drm_connector *connector,
2088 bool high_tmds_clock_ratio, 2091 bool high_tmds_clock_ratio,
2089 bool scrambling) 2092 bool scrambling)
2090{ 2093{
2094 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2091 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); 2095 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
2092 struct drm_i915_private *dev_priv = connector->dev->dev_private;
2093 struct drm_scrambling *sink_scrambling = 2096 struct drm_scrambling *sink_scrambling =
2094 &connector->display_info.hdmi.scdc.scrambling; 2097 &connector->display_info.hdmi.scdc.scrambling;
2095 struct i2c_adapter *adptr = intel_gmbus_get_adapter(dev_priv, 2098 struct i2c_adapter *adapter =
2096 intel_hdmi->ddc_bus); 2099 intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
2097 bool ret;
2098 2100
2099 if (!sink_scrambling->supported) 2101 if (!sink_scrambling->supported)
2100 return; 2102 return true;
2101
2102 DRM_DEBUG_KMS("Setting sink scrambling for enc:%s connector:%s\n",
2103 encoder->base.name, connector->name);
2104 2103
2105 /* Set TMDS bit clock ratio to 1/40 or 1/10 */ 2104 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n",
2106 ret = drm_scdc_set_high_tmds_clock_ratio(adptr, high_tmds_clock_ratio); 2105 connector->base.id, connector->name,
2107 if (!ret) { 2106 yesno(scrambling), high_tmds_clock_ratio ? 40 : 10);
2108 DRM_ERROR("Set TMDS ratio failed\n");
2109 return;
2110 }
2111
2112 /* Enable/disable sink scrambling */
2113 ret = drm_scdc_set_scrambling(adptr, scrambling);
2114 if (!ret) {
2115 DRM_ERROR("Set sink scrambling failed\n");
2116 return;
2117 }
2118 2107
2119 DRM_DEBUG_KMS("sink scrambling handled\n"); 2108 /* Set TMDS bit clock ratio to 1/40 or 1/10, and enable/disable scrambling */
2109 return drm_scdc_set_high_tmds_clock_ratio(adapter,
2110 high_tmds_clock_ratio) &&
2111 drm_scdc_set_scrambling(adapter, scrambling);
2120} 2112}
2121 2113
2122static u8 chv_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port) 2114static u8 chv_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 0e3d3e89d66a..43aa92beff2a 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -100,6 +100,8 @@ enum port intel_hpd_pin_to_port(struct drm_i915_private *dev_priv,
100 if (IS_CNL_WITH_PORT_F(dev_priv)) 100 if (IS_CNL_WITH_PORT_F(dev_priv))
101 return PORT_F; 101 return PORT_F;
102 return PORT_E; 102 return PORT_E;
103 case HPD_PORT_F:
104 return PORT_F;
103 default: 105 default:
104 return PORT_NONE; /* no port for this pin */ 106 return PORT_NONE; /* no port for this pin */
105 } 107 }
@@ -132,6 +134,7 @@ enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
132 case PORT_F: 134 case PORT_F:
133 if (IS_CNL_WITH_PORT_F(dev_priv)) 135 if (IS_CNL_WITH_PORT_F(dev_priv))
134 return HPD_PORT_E; 136 return HPD_PORT_E;
137 return HPD_PORT_F;
135 default: 138 default:
136 MISSING_CASE(port); 139 MISSING_CASE(port);
137 return HPD_NONE; 140 return HPD_NONE;
diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c
index 65e2afb9b955..291285277403 100644
--- a/drivers/gpu/drm/i915/intel_huc.c
+++ b/drivers/gpu/drm/i915/intel_huc.c
@@ -55,7 +55,7 @@ int intel_huc_auth(struct intel_huc *huc)
55 return -ENOEXEC; 55 return -ENOEXEC;
56 56
57 vma = i915_gem_object_ggtt_pin(huc->fw.obj, NULL, 0, 0, 57 vma = i915_gem_object_ggtt_pin(huc->fw.obj, NULL, 0, 0,
58 PIN_OFFSET_BIAS | GUC_WOPCM_TOP); 58 PIN_OFFSET_BIAS | guc->ggtt_pin_bias);
59 if (IS_ERR(vma)) { 59 if (IS_ERR(vma)) {
60 ret = PTR_ERR(vma); 60 ret = PTR_ERR(vma);
61 DRM_ERROR("HuC: Failed to pin huc fw object %d\n", ret); 61 DRM_ERROR("HuC: Failed to pin huc fw object %d\n", ret);
@@ -63,7 +63,8 @@ int intel_huc_auth(struct intel_huc *huc)
63 } 63 }
64 64
65 ret = intel_guc_auth_huc(guc, 65 ret = intel_guc_auth_huc(guc,
66 guc_ggtt_offset(vma) + huc->fw.rsa_offset); 66 intel_guc_ggtt_offset(guc, vma) +
67 huc->fw.rsa_offset);
67 if (ret) { 68 if (ret) {
68 DRM_ERROR("HuC: GuC did not ack Auth request %d\n", ret); 69 DRM_ERROR("HuC: GuC did not ack Auth request %d\n", ret);
69 goto fail_unpin; 70 goto fail_unpin;
@@ -91,3 +92,28 @@ fail:
91 DRM_ERROR("HuC: Authentication failed %d\n", ret); 92 DRM_ERROR("HuC: Authentication failed %d\n", ret);
92 return ret; 93 return ret;
93} 94}
95
96/**
97 * intel_huc_check_status() - check HuC status
98 * @huc: intel_huc structure
99 *
100 * This function reads status register to verify if HuC
101 * firmware was successfully loaded.
102 *
103 * Returns positive value if HuC firmware is loaded and verified
104 * and -ENODEV if HuC is not present.
105 */
106int intel_huc_check_status(struct intel_huc *huc)
107{
108 struct drm_i915_private *dev_priv = huc_to_i915(huc);
109 u32 status;
110
111 if (!HAS_HUC(dev_priv))
112 return -ENODEV;
113
114 intel_runtime_pm_get(dev_priv);
115 status = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
116 intel_runtime_pm_put(dev_priv);
117
118 return status;
119}
diff --git a/drivers/gpu/drm/i915/intel_huc.h b/drivers/gpu/drm/i915/intel_huc.h
index 5d6e804f9771..aa854907abac 100644
--- a/drivers/gpu/drm/i915/intel_huc.h
+++ b/drivers/gpu/drm/i915/intel_huc.h
@@ -37,5 +37,12 @@ struct intel_huc {
37 37
38void intel_huc_init_early(struct intel_huc *huc); 38void intel_huc_init_early(struct intel_huc *huc);
39int intel_huc_auth(struct intel_huc *huc); 39int intel_huc_auth(struct intel_huc *huc);
40int intel_huc_check_status(struct intel_huc *huc);
41
42static inline int intel_huc_sanitize(struct intel_huc *huc)
43{
44 intel_uc_fw_sanitize(&huc->fw);
45 return 0;
46}
40 47
41#endif 48#endif
diff --git a/drivers/gpu/drm/i915/intel_huc_fw.c b/drivers/gpu/drm/i915/intel_huc_fw.c
index c66afa9b989a..f93d2384d482 100644
--- a/drivers/gpu/drm/i915/intel_huc_fw.c
+++ b/drivers/gpu/drm/i915/intel_huc_fw.c
@@ -118,7 +118,8 @@ static int huc_fw_xfer(struct intel_uc_fw *huc_fw, struct i915_vma *vma)
118 intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); 118 intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
119 119
120 /* Set the source address for the uCode */ 120 /* Set the source address for the uCode */
121 offset = guc_ggtt_offset(vma) + huc_fw->header_offset; 121 offset = intel_guc_ggtt_offset(&dev_priv->guc, vma) +
122 huc_fw->header_offset;
122 I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset)); 123 I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
123 I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF); 124 I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
124 125
@@ -154,9 +155,8 @@ static int huc_fw_xfer(struct intel_uc_fw *huc_fw, struct i915_vma *vma)
154 * Called from intel_uc_init_hw() during driver load, resume from sleep and 155 * Called from intel_uc_init_hw() during driver load, resume from sleep and
155 * after a GPU reset. Note that HuC must be loaded before GuC. 156 * after a GPU reset. Note that HuC must be loaded before GuC.
156 * 157 *
157 * The firmware image should have already been fetched into memory by the 158 * The firmware image should have already been fetched into memory, so only
158 * earlier call to intel_uc_init_fw(), so here we need to only check that 159 * check that fetch succeeded, and then transfer the image to the h/w.
159 * fetch succeeded, and then transfer the image to the h/w.
160 * 160 *
161 * Return: non-zero code on error 161 * Return: non-zero code on error
162 */ 162 */
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 8704f7f8d072..15434cad5430 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -139,6 +139,7 @@
139#include "i915_gem_render_state.h" 139#include "i915_gem_render_state.h"
140#include "intel_lrc_reg.h" 140#include "intel_lrc_reg.h"
141#include "intel_mocs.h" 141#include "intel_mocs.h"
142#include "intel_workarounds.h"
142 143
143#define RING_EXECLIST_QFULL (1 << 0x2) 144#define RING_EXECLIST_QFULL (1 << 0x2)
144#define RING_EXECLIST1_VALID (1 << 0x3) 145#define RING_EXECLIST1_VALID (1 << 0x3)
@@ -176,14 +177,16 @@ static inline struct i915_priolist *to_priolist(struct rb_node *rb)
176 177
177static inline int rq_prio(const struct i915_request *rq) 178static inline int rq_prio(const struct i915_request *rq)
178{ 179{
179 return rq->priotree.priority; 180 return rq->sched.attr.priority;
180} 181}
181 182
182static inline bool need_preempt(const struct intel_engine_cs *engine, 183static inline bool need_preempt(const struct intel_engine_cs *engine,
183 const struct i915_request *last, 184 const struct i915_request *last,
184 int prio) 185 int prio)
185{ 186{
186 return engine->i915->preempt_context && prio > max(rq_prio(last), 0); 187 return (intel_engine_has_preemption(engine) &&
188 __execlists_need_preempt(prio, rq_prio(last)) &&
189 !i915_request_completed(last));
187} 190}
188 191
189/** 192/**
@@ -221,7 +224,7 @@ static void
221intel_lr_context_descriptor_update(struct i915_gem_context *ctx, 224intel_lr_context_descriptor_update(struct i915_gem_context *ctx,
222 struct intel_engine_cs *engine) 225 struct intel_engine_cs *engine)
223{ 226{
224 struct intel_context *ce = &ctx->engine[engine->id]; 227 struct intel_context *ce = to_intel_context(ctx, engine);
225 u64 desc; 228 u64 desc;
226 229
227 BUILD_BUG_ON(MAX_CONTEXT_HW_ID > (BIT(GEN8_CTX_ID_WIDTH))); 230 BUILD_BUG_ON(MAX_CONTEXT_HW_ID > (BIT(GEN8_CTX_ID_WIDTH)));
@@ -255,9 +258,7 @@ intel_lr_context_descriptor_update(struct i915_gem_context *ctx,
255} 258}
256 259
257static struct i915_priolist * 260static struct i915_priolist *
258lookup_priolist(struct intel_engine_cs *engine, 261lookup_priolist(struct intel_engine_cs *engine, int prio)
259 struct i915_priotree *pt,
260 int prio)
261{ 262{
262 struct intel_engine_execlists * const execlists = &engine->execlists; 263 struct intel_engine_execlists * const execlists = &engine->execlists;
263 struct i915_priolist *p; 264 struct i915_priolist *p;
@@ -328,10 +329,10 @@ static void __unwind_incomplete_requests(struct intel_engine_cs *engine)
328 struct i915_priolist *uninitialized_var(p); 329 struct i915_priolist *uninitialized_var(p);
329 int last_prio = I915_PRIORITY_INVALID; 330 int last_prio = I915_PRIORITY_INVALID;
330 331
331 lockdep_assert_held(&engine->timeline->lock); 332 lockdep_assert_held(&engine->timeline.lock);
332 333
333 list_for_each_entry_safe_reverse(rq, rn, 334 list_for_each_entry_safe_reverse(rq, rn,
334 &engine->timeline->requests, 335 &engine->timeline.requests,
335 link) { 336 link) {
336 if (i915_request_completed(rq)) 337 if (i915_request_completed(rq))
337 return; 338 return;
@@ -342,10 +343,11 @@ static void __unwind_incomplete_requests(struct intel_engine_cs *engine)
342 GEM_BUG_ON(rq_prio(rq) == I915_PRIORITY_INVALID); 343 GEM_BUG_ON(rq_prio(rq) == I915_PRIORITY_INVALID);
343 if (rq_prio(rq) != last_prio) { 344 if (rq_prio(rq) != last_prio) {
344 last_prio = rq_prio(rq); 345 last_prio = rq_prio(rq);
345 p = lookup_priolist(engine, &rq->priotree, last_prio); 346 p = lookup_priolist(engine, last_prio);
346 } 347 }
347 348
348 list_add(&rq->priotree.link, &p->requests); 349 GEM_BUG_ON(p->priority != rq_prio(rq));
350 list_add(&rq->sched.link, &p->requests);
349 } 351 }
350} 352}
351 353
@@ -354,10 +356,13 @@ execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists)
354{ 356{
355 struct intel_engine_cs *engine = 357 struct intel_engine_cs *engine =
356 container_of(execlists, typeof(*engine), execlists); 358 container_of(execlists, typeof(*engine), execlists);
359 unsigned long flags;
360
361 spin_lock_irqsave(&engine->timeline.lock, flags);
357 362
358 spin_lock_irq(&engine->timeline->lock);
359 __unwind_incomplete_requests(engine); 363 __unwind_incomplete_requests(engine);
360 spin_unlock_irq(&engine->timeline->lock); 364
365 spin_unlock_irqrestore(&engine->timeline.lock, flags);
361} 366}
362 367
363static inline void 368static inline void
@@ -374,6 +379,19 @@ execlists_context_status_change(struct i915_request *rq, unsigned long status)
374 status, rq); 379 status, rq);
375} 380}
376 381
382inline void
383execlists_user_begin(struct intel_engine_execlists *execlists,
384 const struct execlist_port *port)
385{
386 execlists_set_active_once(execlists, EXECLISTS_ACTIVE_USER);
387}
388
389inline void
390execlists_user_end(struct intel_engine_execlists *execlists)
391{
392 execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
393}
394
377static inline void 395static inline void
378execlists_context_schedule_in(struct i915_request *rq) 396execlists_context_schedule_in(struct i915_request *rq)
379{ 397{
@@ -382,10 +400,11 @@ execlists_context_schedule_in(struct i915_request *rq)
382} 400}
383 401
384static inline void 402static inline void
385execlists_context_schedule_out(struct i915_request *rq) 403execlists_context_schedule_out(struct i915_request *rq, unsigned long status)
386{ 404{
387 intel_engine_context_out(rq->engine); 405 intel_engine_context_out(rq->engine);
388 execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); 406 execlists_context_status_change(rq, status);
407 trace_i915_request_out(rq);
389} 408}
390 409
391static void 410static void
@@ -399,7 +418,7 @@ execlists_update_context_pdps(struct i915_hw_ppgtt *ppgtt, u32 *reg_state)
399 418
400static u64 execlists_update_context(struct i915_request *rq) 419static u64 execlists_update_context(struct i915_request *rq)
401{ 420{
402 struct intel_context *ce = &rq->ctx->engine[rq->engine->id]; 421 struct intel_context *ce = to_intel_context(rq->ctx, rq->engine);
403 struct i915_hw_ppgtt *ppgtt = 422 struct i915_hw_ppgtt *ppgtt =
404 rq->ctx->ppgtt ?: rq->i915->mm.aliasing_ppgtt; 423 rq->ctx->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
405 u32 *reg_state = ce->lrc_reg_state; 424 u32 *reg_state = ce->lrc_reg_state;
@@ -454,10 +473,12 @@ static void execlists_submit_ports(struct intel_engine_cs *engine)
454 desc = execlists_update_context(rq); 473 desc = execlists_update_context(rq);
455 GEM_DEBUG_EXEC(port[n].context_id = upper_32_bits(desc)); 474 GEM_DEBUG_EXEC(port[n].context_id = upper_32_bits(desc));
456 475
457 GEM_TRACE("%s in[%d]: ctx=%d.%d, seqno=%x, prio=%d\n", 476 GEM_TRACE("%s in[%d]: ctx=%d.%d, global=%d (fence %llx:%d) (current %d), prio=%d\n",
458 engine->name, n, 477 engine->name, n,
459 port[n].context_id, count, 478 port[n].context_id, count,
460 rq->global_seqno, 479 rq->global_seqno,
480 rq->fence.context, rq->fence.seqno,
481 intel_engine_get_seqno(engine),
461 rq_prio(rq)); 482 rq_prio(rq));
462 } else { 483 } else {
463 GEM_BUG_ON(!n); 484 GEM_BUG_ON(!n);
@@ -506,7 +527,7 @@ static void inject_preempt_context(struct intel_engine_cs *engine)
506{ 527{
507 struct intel_engine_execlists *execlists = &engine->execlists; 528 struct intel_engine_execlists *execlists = &engine->execlists;
508 struct intel_context *ce = 529 struct intel_context *ce =
509 &engine->i915->preempt_context->engine[engine->id]; 530 to_intel_context(engine->i915->preempt_context, engine);
510 unsigned int n; 531 unsigned int n;
511 532
512 GEM_BUG_ON(execlists->preempt_complete_status != 533 GEM_BUG_ON(execlists->preempt_complete_status !=
@@ -535,7 +556,7 @@ static void inject_preempt_context(struct intel_engine_cs *engine)
535 execlists_set_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT); 556 execlists_set_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT);
536} 557}
537 558
538static void execlists_dequeue(struct intel_engine_cs *engine) 559static bool __execlists_dequeue(struct intel_engine_cs *engine)
539{ 560{
540 struct intel_engine_execlists * const execlists = &engine->execlists; 561 struct intel_engine_execlists * const execlists = &engine->execlists;
541 struct execlist_port *port = execlists->port; 562 struct execlist_port *port = execlists->port;
@@ -545,6 +566,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
545 struct rb_node *rb; 566 struct rb_node *rb;
546 bool submit = false; 567 bool submit = false;
547 568
569 lockdep_assert_held(&engine->timeline.lock);
570
548 /* Hardware submission is through 2 ports. Conceptually each port 571 /* Hardware submission is through 2 ports. Conceptually each port
549 * has a (RING_START, RING_HEAD, RING_TAIL) tuple. RING_START is 572 * has a (RING_START, RING_HEAD, RING_TAIL) tuple. RING_START is
550 * static for a context, and unique to each, so we only execute 573 * static for a context, and unique to each, so we only execute
@@ -566,7 +589,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
566 * and context switches) submission. 589 * and context switches) submission.
567 */ 590 */
568 591
569 spin_lock_irq(&engine->timeline->lock);
570 rb = execlists->first; 592 rb = execlists->first;
571 GEM_BUG_ON(rb_first(&execlists->queue) != rb); 593 GEM_BUG_ON(rb_first(&execlists->queue) != rb);
572 594
@@ -581,7 +603,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
581 EXECLISTS_ACTIVE_USER)); 603 EXECLISTS_ACTIVE_USER));
582 GEM_BUG_ON(!port_count(&port[0])); 604 GEM_BUG_ON(!port_count(&port[0]));
583 if (port_count(&port[0]) > 1) 605 if (port_count(&port[0]) > 1)
584 goto unlock; 606 return false;
585 607
586 /* 608 /*
587 * If we write to ELSP a second time before the HW has had 609 * If we write to ELSP a second time before the HW has had
@@ -591,11 +613,11 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
591 * the HW to indicate that it has had a chance to respond. 613 * the HW to indicate that it has had a chance to respond.
592 */ 614 */
593 if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_HWACK)) 615 if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_HWACK))
594 goto unlock; 616 return false;
595 617
596 if (need_preempt(engine, last, execlists->queue_priority)) { 618 if (need_preempt(engine, last, execlists->queue_priority)) {
597 inject_preempt_context(engine); 619 inject_preempt_context(engine);
598 goto unlock; 620 return false;
599 } 621 }
600 622
601 /* 623 /*
@@ -620,7 +642,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
620 * priorities of the ports haven't been switch. 642 * priorities of the ports haven't been switch.
621 */ 643 */
622 if (port_count(&port[1])) 644 if (port_count(&port[1]))
623 goto unlock; 645 return false;
624 646
625 /* 647 /*
626 * WaIdleLiteRestore:bdw,skl 648 * WaIdleLiteRestore:bdw,skl
@@ -637,7 +659,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
637 struct i915_priolist *p = to_priolist(rb); 659 struct i915_priolist *p = to_priolist(rb);
638 struct i915_request *rq, *rn; 660 struct i915_request *rq, *rn;
639 661
640 list_for_each_entry_safe(rq, rn, &p->requests, priotree.link) { 662 list_for_each_entry_safe(rq, rn, &p->requests, sched.link) {
641 /* 663 /*
642 * Can we combine this request with the current port? 664 * Can we combine this request with the current port?
643 * It has to be the same context/ringbuffer and not 665 * It has to be the same context/ringbuffer and not
@@ -657,7 +679,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
657 */ 679 */
658 if (port == last_port) { 680 if (port == last_port) {
659 __list_del_many(&p->requests, 681 __list_del_many(&p->requests,
660 &rq->priotree.link); 682 &rq->sched.link);
661 goto done; 683 goto done;
662 } 684 }
663 685
@@ -671,7 +693,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
671 if (ctx_single_port_submission(last->ctx) || 693 if (ctx_single_port_submission(last->ctx) ||
672 ctx_single_port_submission(rq->ctx)) { 694 ctx_single_port_submission(rq->ctx)) {
673 __list_del_many(&p->requests, 695 __list_del_many(&p->requests,
674 &rq->priotree.link); 696 &rq->sched.link);
675 goto done; 697 goto done;
676 } 698 }
677 699
@@ -684,7 +706,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
684 GEM_BUG_ON(port_isset(port)); 706 GEM_BUG_ON(port_isset(port));
685 } 707 }
686 708
687 INIT_LIST_HEAD(&rq->priotree.link); 709 INIT_LIST_HEAD(&rq->sched.link);
688 __i915_request_submit(rq); 710 __i915_request_submit(rq);
689 trace_i915_request_in(rq, port_index(port, execlists)); 711 trace_i915_request_in(rq, port_index(port, execlists));
690 last = rq; 712 last = rq;
@@ -697,8 +719,27 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
697 if (p->priority != I915_PRIORITY_NORMAL) 719 if (p->priority != I915_PRIORITY_NORMAL)
698 kmem_cache_free(engine->i915->priorities, p); 720 kmem_cache_free(engine->i915->priorities, p);
699 } 721 }
722
700done: 723done:
701 execlists->queue_priority = rb ? to_priolist(rb)->priority : INT_MIN; 724 /*
725 * Here be a bit of magic! Or sleight-of-hand, whichever you prefer.
726 *
727 * We choose queue_priority such that if we add a request of greater
728 * priority than this, we kick the submission tasklet to decide on
729 * the right order of submitting the requests to hardware. We must
730 * also be prepared to reorder requests as they are in-flight on the
731 * HW. We derive the queue_priority then as the first "hole" in
732 * the HW submission ports and if there are no available slots,
733 * the priority of the lowest executing request, i.e. last.
734 *
735 * When we do receive a higher priority request ready to run from the
736 * user, see queue_request(), the queue_priority is bumped to that
737 * request triggering preemption on the next dequeue (or subsequent
738 * interrupt for secondary ports).
739 */
740 execlists->queue_priority =
741 port != execlists->port ? rq_prio(last) : INT_MIN;
742
702 execlists->first = rb; 743 execlists->first = rb;
703 if (submit) 744 if (submit)
704 port_assign(port, last); 745 port_assign(port, last);
@@ -706,13 +747,25 @@ done:
706 /* We must always keep the beast fed if we have work piled up */ 747 /* We must always keep the beast fed if we have work piled up */
707 GEM_BUG_ON(execlists->first && !port_isset(execlists->port)); 748 GEM_BUG_ON(execlists->first && !port_isset(execlists->port));
708 749
709unlock: 750 /* Re-evaluate the executing context setup after each preemptive kick */
710 spin_unlock_irq(&engine->timeline->lock); 751 if (last)
752 execlists_user_begin(execlists, execlists->port);
711 753
712 if (submit) { 754 return submit;
713 execlists_set_active(execlists, EXECLISTS_ACTIVE_USER); 755}
756
757static void execlists_dequeue(struct intel_engine_cs *engine)
758{
759 struct intel_engine_execlists * const execlists = &engine->execlists;
760 unsigned long flags;
761 bool submit;
762
763 spin_lock_irqsave(&engine->timeline.lock, flags);
764 submit = __execlists_dequeue(engine);
765 spin_unlock_irqrestore(&engine->timeline.lock, flags);
766
767 if (submit)
714 execlists_submit_ports(engine); 768 execlists_submit_ports(engine);
715 }
716 769
717 GEM_BUG_ON(port_isset(execlists->port) && 770 GEM_BUG_ON(port_isset(execlists->port) &&
718 !execlists_is_active(execlists, EXECLISTS_ACTIVE_USER)); 771 !execlists_is_active(execlists, EXECLISTS_ACTIVE_USER));
@@ -727,13 +780,18 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
727 while (num_ports-- && port_isset(port)) { 780 while (num_ports-- && port_isset(port)) {
728 struct i915_request *rq = port_request(port); 781 struct i915_request *rq = port_request(port);
729 782
730 GEM_BUG_ON(!execlists->active); 783 GEM_TRACE("%s:port%u global=%d (fence %llx:%d), (current %d)\n",
731 intel_engine_context_out(rq->engine); 784 rq->engine->name,
785 (unsigned int)(port - execlists->port),
786 rq->global_seqno,
787 rq->fence.context, rq->fence.seqno,
788 intel_engine_get_seqno(rq->engine));
732 789
733 execlists_context_status_change(rq, 790 GEM_BUG_ON(!execlists->active);
734 i915_request_completed(rq) ? 791 execlists_context_schedule_out(rq,
735 INTEL_CONTEXT_SCHEDULE_OUT : 792 i915_request_completed(rq) ?
736 INTEL_CONTEXT_SCHEDULE_PREEMPTED); 793 INTEL_CONTEXT_SCHEDULE_OUT :
794 INTEL_CONTEXT_SCHEDULE_PREEMPTED);
737 795
738 i915_request_put(rq); 796 i915_request_put(rq);
739 797
@@ -741,7 +799,82 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
741 port++; 799 port++;
742 } 800 }
743 801
744 execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER); 802 execlists_user_end(execlists);
803}
804
805static void clear_gtiir(struct intel_engine_cs *engine)
806{
807 struct drm_i915_private *dev_priv = engine->i915;
808 int i;
809
810 /*
811 * Clear any pending interrupt state.
812 *
813 * We do it twice out of paranoia that some of the IIR are
814 * double buffered, and so if we only reset it once there may
815 * still be an interrupt pending.
816 */
817 if (INTEL_GEN(dev_priv) >= 11) {
818 static const struct {
819 u8 bank;
820 u8 bit;
821 } gen11_gtiir[] = {
822 [RCS] = {0, GEN11_RCS0},
823 [BCS] = {0, GEN11_BCS},
824 [_VCS(0)] = {1, GEN11_VCS(0)},
825 [_VCS(1)] = {1, GEN11_VCS(1)},
826 [_VCS(2)] = {1, GEN11_VCS(2)},
827 [_VCS(3)] = {1, GEN11_VCS(3)},
828 [_VECS(0)] = {1, GEN11_VECS(0)},
829 [_VECS(1)] = {1, GEN11_VECS(1)},
830 };
831 unsigned long irqflags;
832
833 GEM_BUG_ON(engine->id >= ARRAY_SIZE(gen11_gtiir));
834
835 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
836 for (i = 0; i < 2; i++) {
837 gen11_reset_one_iir(dev_priv,
838 gen11_gtiir[engine->id].bank,
839 gen11_gtiir[engine->id].bit);
840 }
841 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
842 } else {
843 static const u8 gtiir[] = {
844 [RCS] = 0,
845 [BCS] = 0,
846 [VCS] = 1,
847 [VCS2] = 1,
848 [VECS] = 3,
849 };
850
851 GEM_BUG_ON(engine->id >= ARRAY_SIZE(gtiir));
852
853 for (i = 0; i < 2; i++) {
854 I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
855 engine->irq_keep_mask);
856 POSTING_READ(GEN8_GT_IIR(gtiir[engine->id]));
857 }
858 GEM_BUG_ON(I915_READ(GEN8_GT_IIR(gtiir[engine->id])) &
859 engine->irq_keep_mask);
860 }
861}
862
863static void reset_irq(struct intel_engine_cs *engine)
864{
865 /* Mark all CS interrupts as complete */
866 smp_store_mb(engine->execlists.active, 0);
867 synchronize_hardirq(engine->i915->drm.irq);
868
869 clear_gtiir(engine);
870
871 /*
872 * The port is checked prior to scheduling a tasklet, but
873 * just in case we have suspended the tasklet to do the
874 * wedging make sure that when it wakes, it decides there
875 * is no work to do by clearing the irq_posted bit.
876 */
877 clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
745} 878}
746 879
747static void execlists_cancel_requests(struct intel_engine_cs *engine) 880static void execlists_cancel_requests(struct intel_engine_cs *engine)
@@ -751,7 +884,8 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
751 struct rb_node *rb; 884 struct rb_node *rb;
752 unsigned long flags; 885 unsigned long flags;
753 886
754 GEM_TRACE("%s\n", engine->name); 887 GEM_TRACE("%s current %d\n",
888 engine->name, intel_engine_get_seqno(engine));
755 889
756 /* 890 /*
757 * Before we call engine->cancel_requests(), we should have exclusive 891 * Before we call engine->cancel_requests(), we should have exclusive
@@ -771,11 +905,12 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
771 905
772 /* Cancel the requests on the HW and clear the ELSP tracker. */ 906 /* Cancel the requests on the HW and clear the ELSP tracker. */
773 execlists_cancel_port_requests(execlists); 907 execlists_cancel_port_requests(execlists);
908 reset_irq(engine);
774 909
775 spin_lock(&engine->timeline->lock); 910 spin_lock(&engine->timeline.lock);
776 911
777 /* Mark all executing requests as skipped. */ 912 /* Mark all executing requests as skipped. */
778 list_for_each_entry(rq, &engine->timeline->requests, link) { 913 list_for_each_entry(rq, &engine->timeline.requests, link) {
779 GEM_BUG_ON(!rq->global_seqno); 914 GEM_BUG_ON(!rq->global_seqno);
780 if (!i915_request_completed(rq)) 915 if (!i915_request_completed(rq))
781 dma_fence_set_error(&rq->fence, -EIO); 916 dma_fence_set_error(&rq->fence, -EIO);
@@ -786,8 +921,8 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
786 while (rb) { 921 while (rb) {
787 struct i915_priolist *p = to_priolist(rb); 922 struct i915_priolist *p = to_priolist(rb);
788 923
789 list_for_each_entry_safe(rq, rn, &p->requests, priotree.link) { 924 list_for_each_entry_safe(rq, rn, &p->requests, sched.link) {
790 INIT_LIST_HEAD(&rq->priotree.link); 925 INIT_LIST_HEAD(&rq->sched.link);
791 926
792 dma_fence_set_error(&rq->fence, -EIO); 927 dma_fence_set_error(&rq->fence, -EIO);
793 __i915_request_submit(rq); 928 __i915_request_submit(rq);
@@ -807,18 +942,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
807 execlists->first = NULL; 942 execlists->first = NULL;
808 GEM_BUG_ON(port_isset(execlists->port)); 943 GEM_BUG_ON(port_isset(execlists->port));
809 944
810 spin_unlock(&engine->timeline->lock); 945 spin_unlock(&engine->timeline.lock);
811
812 /*
813 * The port is checked prior to scheduling a tasklet, but
814 * just in case we have suspended the tasklet to do the
815 * wedging make sure that when it wakes, it decides there
816 * is no work to do by clearing the irq_posted bit.
817 */
818 clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
819
820 /* Mark all CS interrupts as complete */
821 execlists->active = 0;
822 946
823 local_irq_restore(flags); 947 local_irq_restore(flags);
824} 948}
@@ -831,7 +955,7 @@ static void execlists_submission_tasklet(unsigned long data)
831{ 955{
832 struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; 956 struct intel_engine_cs * const engine = (struct intel_engine_cs *)data;
833 struct intel_engine_execlists * const execlists = &engine->execlists; 957 struct intel_engine_execlists * const execlists = &engine->execlists;
834 struct execlist_port * const port = execlists->port; 958 struct execlist_port *port = execlists->port;
835 struct drm_i915_private *dev_priv = engine->i915; 959 struct drm_i915_private *dev_priv = engine->i915;
836 bool fw = false; 960 bool fw = false;
837 961
@@ -959,10 +1083,13 @@ static void execlists_submission_tasklet(unsigned long data)
959 EXECLISTS_ACTIVE_USER)); 1083 EXECLISTS_ACTIVE_USER));
960 1084
961 rq = port_unpack(port, &count); 1085 rq = port_unpack(port, &count);
962 GEM_TRACE("%s out[0]: ctx=%d.%d, seqno=%x, prio=%d\n", 1086 GEM_TRACE("%s out[0]: ctx=%d.%d, global=%d (fence %llx:%d) (current %d), prio=%d\n",
963 engine->name, 1087 engine->name,
964 port->context_id, count, 1088 port->context_id, count,
965 rq ? rq->global_seqno : 0, 1089 rq ? rq->global_seqno : 0,
1090 rq ? rq->fence.context : 0,
1091 rq ? rq->fence.seqno : 0,
1092 intel_engine_get_seqno(engine),
966 rq ? rq_prio(rq) : 0); 1093 rq ? rq_prio(rq) : 0);
967 1094
968 /* Check the context/desc id for this event matches */ 1095 /* Check the context/desc id for this event matches */
@@ -970,28 +1097,43 @@ static void execlists_submission_tasklet(unsigned long data)
970 1097
971 GEM_BUG_ON(count == 0); 1098 GEM_BUG_ON(count == 0);
972 if (--count == 0) { 1099 if (--count == 0) {
1100 /*
1101 * On the final event corresponding to the
1102 * submission of this context, we expect either
1103 * an element-switch event or a completion
1104 * event (and on completion, the active-idle
1105 * marker). No more preemptions, lite-restore
1106 * or otherwise.
1107 */
973 GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED); 1108 GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED);
974 GEM_BUG_ON(port_isset(&port[1]) && 1109 GEM_BUG_ON(port_isset(&port[1]) &&
975 !(status & GEN8_CTX_STATUS_ELEMENT_SWITCH)); 1110 !(status & GEN8_CTX_STATUS_ELEMENT_SWITCH));
1111 GEM_BUG_ON(!port_isset(&port[1]) &&
1112 !(status & GEN8_CTX_STATUS_ACTIVE_IDLE));
1113
1114 /*
1115 * We rely on the hardware being strongly
1116 * ordered, that the breadcrumb write is
1117 * coherent (visible from the CPU) before the
1118 * user interrupt and CSB is processed.
1119 */
976 GEM_BUG_ON(!i915_request_completed(rq)); 1120 GEM_BUG_ON(!i915_request_completed(rq));
977 execlists_context_schedule_out(rq); 1121
978 trace_i915_request_out(rq); 1122 execlists_context_schedule_out(rq,
1123 INTEL_CONTEXT_SCHEDULE_OUT);
979 i915_request_put(rq); 1124 i915_request_put(rq);
980 1125
981 GEM_TRACE("%s completed ctx=%d\n", 1126 GEM_TRACE("%s completed ctx=%d\n",
982 engine->name, port->context_id); 1127 engine->name, port->context_id);
983 1128
984 execlists_port_complete(execlists, port); 1129 port = execlists_port_complete(execlists, port);
1130 if (port_isset(port))
1131 execlists_user_begin(execlists, port);
1132 else
1133 execlists_user_end(execlists);
985 } else { 1134 } else {
986 port_set(port, port_pack(rq, count)); 1135 port_set(port, port_pack(rq, count));
987 } 1136 }
988
989 /* After the final element, the hw should be idle */
990 GEM_BUG_ON(port_count(port) == 0 &&
991 !(status & GEN8_CTX_STATUS_ACTIVE_IDLE));
992 if (port_count(port) == 0)
993 execlists_clear_active(execlists,
994 EXECLISTS_ACTIVE_USER);
995 } 1137 }
996 1138
997 if (head != execlists->csb_head) { 1139 if (head != execlists->csb_head) {
@@ -1014,18 +1156,23 @@ static void execlists_submission_tasklet(unsigned long data)
1014} 1156}
1015 1157
1016static void queue_request(struct intel_engine_cs *engine, 1158static void queue_request(struct intel_engine_cs *engine,
1017 struct i915_priotree *pt, 1159 struct i915_sched_node *node,
1018 int prio) 1160 int prio)
1019{ 1161{
1020 list_add_tail(&pt->link, &lookup_priolist(engine, pt, prio)->requests); 1162 list_add_tail(&node->link,
1163 &lookup_priolist(engine, prio)->requests);
1164}
1165
1166static void __submit_queue(struct intel_engine_cs *engine, int prio)
1167{
1168 engine->execlists.queue_priority = prio;
1169 tasklet_hi_schedule(&engine->execlists.tasklet);
1021} 1170}
1022 1171
1023static void submit_queue(struct intel_engine_cs *engine, int prio) 1172static void submit_queue(struct intel_engine_cs *engine, int prio)
1024{ 1173{
1025 if (prio > engine->execlists.queue_priority) { 1174 if (prio > engine->execlists.queue_priority)
1026 engine->execlists.queue_priority = prio; 1175 __submit_queue(engine, prio);
1027 tasklet_hi_schedule(&engine->execlists.tasklet);
1028 }
1029} 1176}
1030 1177
1031static void execlists_submit_request(struct i915_request *request) 1178static void execlists_submit_request(struct i915_request *request)
@@ -1034,42 +1181,45 @@ static void execlists_submit_request(struct i915_request *request)
1034 unsigned long flags; 1181 unsigned long flags;
1035 1182
1036 /* Will be called from irq-context when using foreign fences. */ 1183 /* Will be called from irq-context when using foreign fences. */
1037 spin_lock_irqsave(&engine->timeline->lock, flags); 1184 spin_lock_irqsave(&engine->timeline.lock, flags);
1038 1185
1039 queue_request(engine, &request->priotree, rq_prio(request)); 1186 queue_request(engine, &request->sched, rq_prio(request));
1040 submit_queue(engine, rq_prio(request)); 1187 submit_queue(engine, rq_prio(request));
1041 1188
1042 GEM_BUG_ON(!engine->execlists.first); 1189 GEM_BUG_ON(!engine->execlists.first);
1043 GEM_BUG_ON(list_empty(&request->priotree.link)); 1190 GEM_BUG_ON(list_empty(&request->sched.link));
1044 1191
1045 spin_unlock_irqrestore(&engine->timeline->lock, flags); 1192 spin_unlock_irqrestore(&engine->timeline.lock, flags);
1046} 1193}
1047 1194
1048static struct i915_request *pt_to_request(struct i915_priotree *pt) 1195static struct i915_request *sched_to_request(struct i915_sched_node *node)
1049{ 1196{
1050 return container_of(pt, struct i915_request, priotree); 1197 return container_of(node, struct i915_request, sched);
1051} 1198}
1052 1199
1053static struct intel_engine_cs * 1200static struct intel_engine_cs *
1054pt_lock_engine(struct i915_priotree *pt, struct intel_engine_cs *locked) 1201sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked)
1055{ 1202{
1056 struct intel_engine_cs *engine = pt_to_request(pt)->engine; 1203 struct intel_engine_cs *engine = sched_to_request(node)->engine;
1057 1204
1058 GEM_BUG_ON(!locked); 1205 GEM_BUG_ON(!locked);
1059 1206
1060 if (engine != locked) { 1207 if (engine != locked) {
1061 spin_unlock(&locked->timeline->lock); 1208 spin_unlock(&locked->timeline.lock);
1062 spin_lock(&engine->timeline->lock); 1209 spin_lock(&engine->timeline.lock);
1063 } 1210 }
1064 1211
1065 return engine; 1212 return engine;
1066} 1213}
1067 1214
1068static void execlists_schedule(struct i915_request *request, int prio) 1215static void execlists_schedule(struct i915_request *request,
1216 const struct i915_sched_attr *attr)
1069{ 1217{
1070 struct intel_engine_cs *engine; 1218 struct i915_priolist *uninitialized_var(pl);
1219 struct intel_engine_cs *engine, *last;
1071 struct i915_dependency *dep, *p; 1220 struct i915_dependency *dep, *p;
1072 struct i915_dependency stack; 1221 struct i915_dependency stack;
1222 const int prio = attr->priority;
1073 LIST_HEAD(dfs); 1223 LIST_HEAD(dfs);
1074 1224
1075 GEM_BUG_ON(prio == I915_PRIORITY_INVALID); 1225 GEM_BUG_ON(prio == I915_PRIORITY_INVALID);
@@ -1077,23 +1227,23 @@ static void execlists_schedule(struct i915_request *request, int prio)
1077 if (i915_request_completed(request)) 1227 if (i915_request_completed(request))
1078 return; 1228 return;
1079 1229
1080 if (prio <= READ_ONCE(request->priotree.priority)) 1230 if (prio <= READ_ONCE(request->sched.attr.priority))
1081 return; 1231 return;
1082 1232
1083 /* Need BKL in order to use the temporary link inside i915_dependency */ 1233 /* Need BKL in order to use the temporary link inside i915_dependency */
1084 lockdep_assert_held(&request->i915->drm.struct_mutex); 1234 lockdep_assert_held(&request->i915->drm.struct_mutex);
1085 1235
1086 stack.signaler = &request->priotree; 1236 stack.signaler = &request->sched;
1087 list_add(&stack.dfs_link, &dfs); 1237 list_add(&stack.dfs_link, &dfs);
1088 1238
1089 /* 1239 /*
1090 * Recursively bump all dependent priorities to match the new request. 1240 * Recursively bump all dependent priorities to match the new request.
1091 * 1241 *
1092 * A naive approach would be to use recursion: 1242 * A naive approach would be to use recursion:
1093 * static void update_priorities(struct i915_priotree *pt, prio) { 1243 * static void update_priorities(struct i915_sched_node *node, prio) {
1094 * list_for_each_entry(dep, &pt->signalers_list, signal_link) 1244 * list_for_each_entry(dep, &node->signalers_list, signal_link)
1095 * update_priorities(dep->signal, prio) 1245 * update_priorities(dep->signal, prio)
1096 * queue_request(pt); 1246 * queue_request(node);
1097 * } 1247 * }
1098 * but that may have unlimited recursion depth and so runs a very 1248 * but that may have unlimited recursion depth and so runs a very
1099 * real risk of overunning the kernel stack. Instead, we build 1249 * real risk of overunning the kernel stack. Instead, we build
@@ -1105,7 +1255,7 @@ static void execlists_schedule(struct i915_request *request, int prio)
1105 * last element in the list is the request we must execute first. 1255 * last element in the list is the request we must execute first.
1106 */ 1256 */
1107 list_for_each_entry(dep, &dfs, dfs_link) { 1257 list_for_each_entry(dep, &dfs, dfs_link) {
1108 struct i915_priotree *pt = dep->signaler; 1258 struct i915_sched_node *node = dep->signaler;
1109 1259
1110 /* 1260 /*
1111 * Within an engine, there can be no cycle, but we may 1261 * Within an engine, there can be no cycle, but we may
@@ -1113,14 +1263,14 @@ static void execlists_schedule(struct i915_request *request, int prio)
1113 * (redundant dependencies are not eliminated) and across 1263 * (redundant dependencies are not eliminated) and across
1114 * engines. 1264 * engines.
1115 */ 1265 */
1116 list_for_each_entry(p, &pt->signalers_list, signal_link) { 1266 list_for_each_entry(p, &node->signalers_list, signal_link) {
1117 GEM_BUG_ON(p == dep); /* no cycles! */ 1267 GEM_BUG_ON(p == dep); /* no cycles! */
1118 1268
1119 if (i915_priotree_signaled(p->signaler)) 1269 if (i915_sched_node_signaled(p->signaler))
1120 continue; 1270 continue;
1121 1271
1122 GEM_BUG_ON(p->signaler->priority < pt->priority); 1272 GEM_BUG_ON(p->signaler->attr.priority < node->attr.priority);
1123 if (prio > READ_ONCE(p->signaler->priority)) 1273 if (prio > READ_ONCE(p->signaler->attr.priority))
1124 list_move_tail(&p->dfs_link, &dfs); 1274 list_move_tail(&p->dfs_link, &dfs);
1125 } 1275 }
1126 } 1276 }
@@ -1131,37 +1281,45 @@ static void execlists_schedule(struct i915_request *request, int prio)
1131 * execlists_submit_request()), we can set our own priority and skip 1281 * execlists_submit_request()), we can set our own priority and skip
1132 * acquiring the engine locks. 1282 * acquiring the engine locks.
1133 */ 1283 */
1134 if (request->priotree.priority == I915_PRIORITY_INVALID) { 1284 if (request->sched.attr.priority == I915_PRIORITY_INVALID) {
1135 GEM_BUG_ON(!list_empty(&request->priotree.link)); 1285 GEM_BUG_ON(!list_empty(&request->sched.link));
1136 request->priotree.priority = prio; 1286 request->sched.attr = *attr;
1137 if (stack.dfs_link.next == stack.dfs_link.prev) 1287 if (stack.dfs_link.next == stack.dfs_link.prev)
1138 return; 1288 return;
1139 __list_del_entry(&stack.dfs_link); 1289 __list_del_entry(&stack.dfs_link);
1140 } 1290 }
1141 1291
1292 last = NULL;
1142 engine = request->engine; 1293 engine = request->engine;
1143 spin_lock_irq(&engine->timeline->lock); 1294 spin_lock_irq(&engine->timeline.lock);
1144 1295
1145 /* Fifo and depth-first replacement ensure our deps execute before us */ 1296 /* Fifo and depth-first replacement ensure our deps execute before us */
1146 list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) { 1297 list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) {
1147 struct i915_priotree *pt = dep->signaler; 1298 struct i915_sched_node *node = dep->signaler;
1148 1299
1149 INIT_LIST_HEAD(&dep->dfs_link); 1300 INIT_LIST_HEAD(&dep->dfs_link);
1150 1301
1151 engine = pt_lock_engine(pt, engine); 1302 engine = sched_lock_engine(node, engine);
1152 1303
1153 if (prio <= pt->priority) 1304 if (prio <= node->attr.priority)
1154 continue; 1305 continue;
1155 1306
1156 pt->priority = prio; 1307 node->attr.priority = prio;
1157 if (!list_empty(&pt->link)) { 1308 if (!list_empty(&node->link)) {
1158 __list_del_entry(&pt->link); 1309 if (last != engine) {
1159 queue_request(engine, pt, prio); 1310 pl = lookup_priolist(engine, prio);
1311 last = engine;
1312 }
1313 GEM_BUG_ON(pl->priority != prio);
1314 list_move_tail(&node->link, &pl->requests);
1160 } 1315 }
1161 submit_queue(engine, prio); 1316
1317 if (prio > engine->execlists.queue_priority &&
1318 i915_sw_fence_done(&sched_to_request(node)->submit))
1319 __submit_queue(engine, prio);
1162 } 1320 }
1163 1321
1164 spin_unlock_irq(&engine->timeline->lock); 1322 spin_unlock_irq(&engine->timeline.lock);
1165} 1323}
1166 1324
1167static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma) 1325static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma)
@@ -1191,7 +1349,7 @@ static struct intel_ring *
1191execlists_context_pin(struct intel_engine_cs *engine, 1349execlists_context_pin(struct intel_engine_cs *engine,
1192 struct i915_gem_context *ctx) 1350 struct i915_gem_context *ctx)
1193{ 1351{
1194 struct intel_context *ce = &ctx->engine[engine->id]; 1352 struct intel_context *ce = to_intel_context(ctx, engine);
1195 void *vaddr; 1353 void *vaddr;
1196 int ret; 1354 int ret;
1197 1355
@@ -1225,6 +1383,7 @@ execlists_context_pin(struct intel_engine_cs *engine,
1225 ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE; 1383 ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
1226 ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = 1384 ce->lrc_reg_state[CTX_RING_BUFFER_START+1] =
1227 i915_ggtt_offset(ce->ring->vma); 1385 i915_ggtt_offset(ce->ring->vma);
1386 ce->lrc_reg_state[CTX_RING_HEAD+1] = ce->ring->head;
1228 1387
1229 ce->state->obj->pin_global++; 1388 ce->state->obj->pin_global++;
1230 i915_gem_context_get(ctx); 1389 i915_gem_context_get(ctx);
@@ -1243,7 +1402,7 @@ err:
1243static void execlists_context_unpin(struct intel_engine_cs *engine, 1402static void execlists_context_unpin(struct intel_engine_cs *engine,
1244 struct i915_gem_context *ctx) 1403 struct i915_gem_context *ctx)
1245{ 1404{
1246 struct intel_context *ce = &ctx->engine[engine->id]; 1405 struct intel_context *ce = to_intel_context(ctx, engine);
1247 1406
1248 lockdep_assert_held(&ctx->i915->drm.struct_mutex); 1407 lockdep_assert_held(&ctx->i915->drm.struct_mutex);
1249 GEM_BUG_ON(ce->pin_count == 0); 1408 GEM_BUG_ON(ce->pin_count == 0);
@@ -1262,8 +1421,8 @@ static void execlists_context_unpin(struct intel_engine_cs *engine,
1262 1421
1263static int execlists_request_alloc(struct i915_request *request) 1422static int execlists_request_alloc(struct i915_request *request)
1264{ 1423{
1265 struct intel_engine_cs *engine = request->engine; 1424 struct intel_context *ce =
1266 struct intel_context *ce = &request->ctx->engine[engine->id]; 1425 to_intel_context(request->ctx, request->engine);
1267 int ret; 1426 int ret;
1268 1427
1269 GEM_BUG_ON(!ce->pin_count); 1428 GEM_BUG_ON(!ce->pin_count);
@@ -1523,6 +1682,8 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
1523 return -EINVAL; 1682 return -EINVAL;
1524 1683
1525 switch (INTEL_GEN(engine->i915)) { 1684 switch (INTEL_GEN(engine->i915)) {
1685 case 11:
1686 return 0;
1526 case 10: 1687 case 10:
1527 wa_bb_fn[0] = gen10_init_indirectctx_bb; 1688 wa_bb_fn[0] = gen10_init_indirectctx_bb;
1528 wa_bb_fn[1] = NULL; 1689 wa_bb_fn[1] = NULL;
@@ -1575,14 +1736,6 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
1575 return ret; 1736 return ret;
1576} 1737}
1577 1738
1578static u8 gtiir[] = {
1579 [RCS] = 0,
1580 [BCS] = 0,
1581 [VCS] = 1,
1582 [VCS2] = 1,
1583 [VECS] = 3,
1584};
1585
1586static void enable_execlists(struct intel_engine_cs *engine) 1739static void enable_execlists(struct intel_engine_cs *engine)
1587{ 1740{
1588 struct drm_i915_private *dev_priv = engine->i915; 1741 struct drm_i915_private *dev_priv = engine->i915;
@@ -1642,6 +1795,8 @@ static int gen8_init_render_ring(struct intel_engine_cs *engine)
1642 if (ret) 1795 if (ret)
1643 return ret; 1796 return ret;
1644 1797
1798 intel_whitelist_workarounds_apply(engine);
1799
1645 /* We need to disable the AsyncFlip performance optimisations in order 1800 /* We need to disable the AsyncFlip performance optimisations in order
1646 * to use MI_WAIT_FOR_EVENT within the CS. It should already be 1801 * to use MI_WAIT_FOR_EVENT within the CS. It should already be
1647 * programmed to '1' on all products. 1802 * programmed to '1' on all products.
@@ -1652,7 +1807,7 @@ static int gen8_init_render_ring(struct intel_engine_cs *engine)
1652 1807
1653 I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); 1808 I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
1654 1809
1655 return init_workarounds_ring(engine); 1810 return 0;
1656} 1811}
1657 1812
1658static int gen9_init_render_ring(struct intel_engine_cs *engine) 1813static int gen9_init_render_ring(struct intel_engine_cs *engine)
@@ -1663,49 +1818,25 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine)
1663 if (ret) 1818 if (ret)
1664 return ret; 1819 return ret;
1665 1820
1666 return init_workarounds_ring(engine); 1821 intel_whitelist_workarounds_apply(engine);
1667}
1668
1669static void reset_irq(struct intel_engine_cs *engine)
1670{
1671 struct drm_i915_private *dev_priv = engine->i915;
1672 int i;
1673
1674 GEM_BUG_ON(engine->id >= ARRAY_SIZE(gtiir));
1675
1676 /*
1677 * Clear any pending interrupt state.
1678 *
1679 * We do it twice out of paranoia that some of the IIR are double
1680 * buffered, and if we only reset it once there may still be
1681 * an interrupt pending.
1682 */
1683 for (i = 0; i < 2; i++) {
1684 I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
1685 GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
1686 POSTING_READ(GEN8_GT_IIR(gtiir[engine->id]));
1687 }
1688 GEM_BUG_ON(I915_READ(GEN8_GT_IIR(gtiir[engine->id])) &
1689 (GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift));
1690 1822
1691 clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); 1823 return 0;
1692} 1824}
1693 1825
1694static void reset_common_ring(struct intel_engine_cs *engine, 1826static void reset_common_ring(struct intel_engine_cs *engine,
1695 struct i915_request *request) 1827 struct i915_request *request)
1696{ 1828{
1697 struct intel_engine_execlists * const execlists = &engine->execlists; 1829 struct intel_engine_execlists * const execlists = &engine->execlists;
1698 struct intel_context *ce;
1699 unsigned long flags; 1830 unsigned long flags;
1831 u32 *regs;
1700 1832
1701 GEM_TRACE("%s seqno=%x\n", 1833 GEM_TRACE("%s request global=%x, current=%d\n",
1702 engine->name, request ? request->global_seqno : 0); 1834 engine->name, request ? request->global_seqno : 0,
1835 intel_engine_get_seqno(engine));
1703 1836
1704 /* See execlists_cancel_requests() for the irq/spinlock split. */ 1837 /* See execlists_cancel_requests() for the irq/spinlock split. */
1705 local_irq_save(flags); 1838 local_irq_save(flags);
1706 1839
1707 reset_irq(engine);
1708
1709 /* 1840 /*
1710 * Catch up with any missed context-switch interrupts. 1841 * Catch up with any missed context-switch interrupts.
1711 * 1842 *
@@ -1716,14 +1847,12 @@ static void reset_common_ring(struct intel_engine_cs *engine,
1716 * requests were completed. 1847 * requests were completed.
1717 */ 1848 */
1718 execlists_cancel_port_requests(execlists); 1849 execlists_cancel_port_requests(execlists);
1850 reset_irq(engine);
1719 1851
1720 /* Push back any incomplete requests for replay after the reset. */ 1852 /* Push back any incomplete requests for replay after the reset. */
1721 spin_lock(&engine->timeline->lock); 1853 spin_lock(&engine->timeline.lock);
1722 __unwind_incomplete_requests(engine); 1854 __unwind_incomplete_requests(engine);
1723 spin_unlock(&engine->timeline->lock); 1855 spin_unlock(&engine->timeline.lock);
1724
1725 /* Mark all CS interrupts as complete */
1726 execlists->active = 0;
1727 1856
1728 local_irq_restore(flags); 1857 local_irq_restore(flags);
1729 1858
@@ -1749,14 +1878,24 @@ static void reset_common_ring(struct intel_engine_cs *engine,
1749 * future request will be after userspace has had the opportunity 1878 * future request will be after userspace has had the opportunity
1750 * to recreate its own state. 1879 * to recreate its own state.
1751 */ 1880 */
1752 ce = &request->ctx->engine[engine->id]; 1881 regs = to_intel_context(request->ctx, engine)->lrc_reg_state;
1753 execlists_init_reg_state(ce->lrc_reg_state, 1882 if (engine->default_state) {
1754 request->ctx, engine, ce->ring); 1883 void *defaults;
1884
1885 defaults = i915_gem_object_pin_map(engine->default_state,
1886 I915_MAP_WB);
1887 if (!IS_ERR(defaults)) {
1888 memcpy(regs, /* skip restoring the vanilla PPHWSP */
1889 defaults + LRC_STATE_PN * PAGE_SIZE,
1890 engine->context_size - PAGE_SIZE);
1891 i915_gem_object_unpin_map(engine->default_state);
1892 }
1893 }
1894 execlists_init_reg_state(regs, request->ctx, engine, request->ring);
1755 1895
1756 /* Move the RING_HEAD onto the breadcrumb, past the hanging batch */ 1896 /* Move the RING_HEAD onto the breadcrumb, past the hanging batch */
1757 ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = 1897 regs[CTX_RING_BUFFER_START + 1] = i915_ggtt_offset(request->ring->vma);
1758 i915_ggtt_offset(ce->ring->vma); 1898 regs[CTX_RING_HEAD + 1] = request->postfix;
1759 ce->lrc_reg_state[CTX_RING_HEAD+1] = request->postfix;
1760 1899
1761 request->ring->head = request->postfix; 1900 request->ring->head = request->postfix;
1762 intel_ring_update_space(request->ring); 1901 intel_ring_update_space(request->ring);
@@ -1817,7 +1956,7 @@ static int gen8_emit_bb_start(struct i915_request *rq,
1817 rq->ctx->ppgtt->pd_dirty_rings &= ~intel_engine_flag(rq->engine); 1956 rq->ctx->ppgtt->pd_dirty_rings &= ~intel_engine_flag(rq->engine);
1818 } 1957 }
1819 1958
1820 cs = intel_ring_begin(rq, 4); 1959 cs = intel_ring_begin(rq, 6);
1821 if (IS_ERR(cs)) 1960 if (IS_ERR(cs))
1822 return PTR_ERR(cs); 1961 return PTR_ERR(cs);
1823 1962
@@ -1846,6 +1985,9 @@ static int gen8_emit_bb_start(struct i915_request *rq,
1846 (flags & I915_DISPATCH_RS ? MI_BATCH_RESOURCE_STREAMER : 0); 1985 (flags & I915_DISPATCH_RS ? MI_BATCH_RESOURCE_STREAMER : 0);
1847 *cs++ = lower_32_bits(offset); 1986 *cs++ = lower_32_bits(offset);
1848 *cs++ = upper_32_bits(offset); 1987 *cs++ = upper_32_bits(offset);
1988
1989 *cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE;
1990 *cs++ = MI_NOOP;
1849 intel_ring_advance(rq, cs); 1991 intel_ring_advance(rq, cs);
1850 1992
1851 return 0; 1993 return 0;
@@ -1988,7 +2130,7 @@ static void gen8_emit_breadcrumb(struct i915_request *request, u32 *cs)
1988 cs = gen8_emit_ggtt_write(cs, request->global_seqno, 2130 cs = gen8_emit_ggtt_write(cs, request->global_seqno,
1989 intel_hws_seqno_address(request->engine)); 2131 intel_hws_seqno_address(request->engine));
1990 *cs++ = MI_USER_INTERRUPT; 2132 *cs++ = MI_USER_INTERRUPT;
1991 *cs++ = MI_NOOP; 2133 *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
1992 request->tail = intel_ring_offset(request, cs); 2134 request->tail = intel_ring_offset(request, cs);
1993 assert_ring_tail_valid(request->ring, request->tail); 2135 assert_ring_tail_valid(request->ring, request->tail);
1994 2136
@@ -2004,7 +2146,7 @@ static void gen8_emit_breadcrumb_rcs(struct i915_request *request, u32 *cs)
2004 cs = gen8_emit_ggtt_write_rcs(cs, request->global_seqno, 2146 cs = gen8_emit_ggtt_write_rcs(cs, request->global_seqno,
2005 intel_hws_seqno_address(request->engine)); 2147 intel_hws_seqno_address(request->engine));
2006 *cs++ = MI_USER_INTERRUPT; 2148 *cs++ = MI_USER_INTERRUPT;
2007 *cs++ = MI_NOOP; 2149 *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
2008 request->tail = intel_ring_offset(request, cs); 2150 request->tail = intel_ring_offset(request, cs);
2009 assert_ring_tail_valid(request->ring, request->tail); 2151 assert_ring_tail_valid(request->ring, request->tail);
2010 2152
@@ -2016,7 +2158,7 @@ static int gen8_init_rcs_context(struct i915_request *rq)
2016{ 2158{
2017 int ret; 2159 int ret;
2018 2160
2019 ret = intel_ring_workarounds_emit(rq); 2161 ret = intel_ctx_workarounds_emit(rq);
2020 if (ret) 2162 if (ret)
2021 return ret; 2163 return ret;
2022 2164
@@ -2076,11 +2218,13 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine)
2076 engine->unpark = NULL; 2218 engine->unpark = NULL;
2077 2219
2078 engine->flags |= I915_ENGINE_SUPPORTS_STATS; 2220 engine->flags |= I915_ENGINE_SUPPORTS_STATS;
2221 if (engine->i915->preempt_context)
2222 engine->flags |= I915_ENGINE_HAS_PREEMPTION;
2079 2223
2080 engine->i915->caps.scheduler = 2224 engine->i915->caps.scheduler =
2081 I915_SCHEDULER_CAP_ENABLED | 2225 I915_SCHEDULER_CAP_ENABLED |
2082 I915_SCHEDULER_CAP_PRIORITY; 2226 I915_SCHEDULER_CAP_PRIORITY;
2083 if (engine->i915->preempt_context) 2227 if (intel_engine_has_preemption(engine))
2084 engine->i915->caps.scheduler |= I915_SCHEDULER_CAP_PREEMPTION; 2228 engine->i915->caps.scheduler |= I915_SCHEDULER_CAP_PREEMPTION;
2085} 2229}
2086 2230
@@ -2119,7 +2263,20 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
2119static inline void 2263static inline void
2120logical_ring_default_irqs(struct intel_engine_cs *engine) 2264logical_ring_default_irqs(struct intel_engine_cs *engine)
2121{ 2265{
2122 unsigned shift = engine->irq_shift; 2266 unsigned int shift = 0;
2267
2268 if (INTEL_GEN(engine->i915) < 11) {
2269 const u8 irq_shifts[] = {
2270 [RCS] = GEN8_RCS_IRQ_SHIFT,
2271 [BCS] = GEN8_BCS_IRQ_SHIFT,
2272 [VCS] = GEN8_VCS1_IRQ_SHIFT,
2273 [VCS2] = GEN8_VCS2_IRQ_SHIFT,
2274 [VECS] = GEN8_VECS_IRQ_SHIFT,
2275 };
2276
2277 shift = irq_shifts[engine->id];
2278 }
2279
2123 engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift; 2280 engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift;
2124 engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; 2281 engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift;
2125} 2282}
@@ -2175,9 +2332,13 @@ static int logical_ring_init(struct intel_engine_cs *engine)
2175 } 2332 }
2176 2333
2177 engine->execlists.preempt_complete_status = ~0u; 2334 engine->execlists.preempt_complete_status = ~0u;
2178 if (engine->i915->preempt_context) 2335 if (engine->i915->preempt_context) {
2336 struct intel_context *ce =
2337 to_intel_context(engine->i915->preempt_context, engine);
2338
2179 engine->execlists.preempt_complete_status = 2339 engine->execlists.preempt_complete_status =
2180 upper_32_bits(engine->i915->preempt_context->engine[engine->id].lrc_desc); 2340 upper_32_bits(ce->lrc_desc);
2341 }
2181 2342
2182 return 0; 2343 return 0;
2183 2344
@@ -2431,8 +2592,10 @@ populate_lr_context(struct i915_gem_context *ctx,
2431 2592
2432 defaults = i915_gem_object_pin_map(engine->default_state, 2593 defaults = i915_gem_object_pin_map(engine->default_state,
2433 I915_MAP_WB); 2594 I915_MAP_WB);
2434 if (IS_ERR(defaults)) 2595 if (IS_ERR(defaults)) {
2435 return PTR_ERR(defaults); 2596 ret = PTR_ERR(defaults);
2597 goto err_unpin_ctx;
2598 }
2436 2599
2437 memcpy(vaddr + start, defaults + start, engine->context_size); 2600 memcpy(vaddr + start, defaults + start, engine->context_size);
2438 i915_gem_object_unpin_map(engine->default_state); 2601 i915_gem_object_unpin_map(engine->default_state);
@@ -2450,19 +2613,20 @@ populate_lr_context(struct i915_gem_context *ctx,
2450 _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT | 2613 _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT |
2451 CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT); 2614 CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT);
2452 2615
2616err_unpin_ctx:
2453 i915_gem_object_unpin_map(ctx_obj); 2617 i915_gem_object_unpin_map(ctx_obj);
2454 2618 return ret;
2455 return 0;
2456} 2619}
2457 2620
2458static int execlists_context_deferred_alloc(struct i915_gem_context *ctx, 2621static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
2459 struct intel_engine_cs *engine) 2622 struct intel_engine_cs *engine)
2460{ 2623{
2461 struct drm_i915_gem_object *ctx_obj; 2624 struct drm_i915_gem_object *ctx_obj;
2462 struct intel_context *ce = &ctx->engine[engine->id]; 2625 struct intel_context *ce = to_intel_context(ctx, engine);
2463 struct i915_vma *vma; 2626 struct i915_vma *vma;
2464 uint32_t context_size; 2627 uint32_t context_size;
2465 struct intel_ring *ring; 2628 struct intel_ring *ring;
2629 struct i915_timeline *timeline;
2466 int ret; 2630 int ret;
2467 2631
2468 if (ce->state) 2632 if (ce->state)
@@ -2478,8 +2642,8 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
2478 2642
2479 ctx_obj = i915_gem_object_create(ctx->i915, context_size); 2643 ctx_obj = i915_gem_object_create(ctx->i915, context_size);
2480 if (IS_ERR(ctx_obj)) { 2644 if (IS_ERR(ctx_obj)) {
2481 DRM_DEBUG_DRIVER("Alloc LRC backing obj failed.\n"); 2645 ret = PTR_ERR(ctx_obj);
2482 return PTR_ERR(ctx_obj); 2646 goto error_deref_obj;
2483 } 2647 }
2484 2648
2485 vma = i915_vma_instance(ctx_obj, &ctx->i915->ggtt.base, NULL); 2649 vma = i915_vma_instance(ctx_obj, &ctx->i915->ggtt.base, NULL);
@@ -2488,7 +2652,14 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
2488 goto error_deref_obj; 2652 goto error_deref_obj;
2489 } 2653 }
2490 2654
2491 ring = intel_engine_create_ring(engine, ctx->ring_size); 2655 timeline = i915_timeline_create(ctx->i915, ctx->name);
2656 if (IS_ERR(timeline)) {
2657 ret = PTR_ERR(timeline);
2658 goto error_deref_obj;
2659 }
2660
2661 ring = intel_engine_create_ring(engine, timeline, ctx->ring_size);
2662 i915_timeline_put(timeline);
2492 if (IS_ERR(ring)) { 2663 if (IS_ERR(ring)) {
2493 ret = PTR_ERR(ring); 2664 ret = PTR_ERR(ring);
2494 goto error_deref_obj; 2665 goto error_deref_obj;
@@ -2530,7 +2701,8 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv)
2530 */ 2701 */
2531 list_for_each_entry(ctx, &dev_priv->contexts.list, link) { 2702 list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
2532 for_each_engine(engine, dev_priv, id) { 2703 for_each_engine(engine, dev_priv, id) {
2533 struct intel_context *ce = &ctx->engine[engine->id]; 2704 struct intel_context *ce =
2705 to_intel_context(ctx, engine);
2534 u32 *reg; 2706 u32 *reg;
2535 2707
2536 if (!ce->state) 2708 if (!ce->state)
@@ -2552,3 +2724,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv)
2552 } 2724 }
2553 } 2725 }
2554} 2726}
2727
2728#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
2729#include "selftests/intel_lrc.c"
2730#endif
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 59d7b86012e9..4ec7d8dd13c8 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -108,7 +108,7 @@ static inline uint64_t
108intel_lr_context_descriptor(struct i915_gem_context *ctx, 108intel_lr_context_descriptor(struct i915_gem_context *ctx,
109 struct intel_engine_cs *engine) 109 struct intel_engine_cs *engine)
110{ 110{
111 return ctx->engine[engine->id].lrc_desc; 111 return to_intel_context(ctx, engine)->lrc_desc;
112} 112}
113 113
114#endif /* _INTEL_LRC_H_ */ 114#endif /* _INTEL_LRC_H_ */
diff --git a/drivers/gpu/drm/i915/intel_mocs.c b/drivers/gpu/drm/i915/intel_mocs.c
index c0b34b7943b9..9f0bd6a4cb79 100644
--- a/drivers/gpu/drm/i915/intel_mocs.c
+++ b/drivers/gpu/drm/i915/intel_mocs.c
@@ -178,7 +178,8 @@ static bool get_mocs_settings(struct drm_i915_private *dev_priv,
178{ 178{
179 bool result = false; 179 bool result = false;
180 180
181 if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { 181 if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv) ||
182 IS_ICELAKE(dev_priv)) {
182 table->size = ARRAY_SIZE(skylake_mocs_table); 183 table->size = ARRAY_SIZE(skylake_mocs_table);
183 table->table = skylake_mocs_table; 184 table->table = skylake_mocs_table;
184 result = true; 185 result = true;
@@ -217,6 +218,8 @@ static i915_reg_t mocs_register(enum intel_engine_id engine_id, int index)
217 return GEN9_VEBOX_MOCS(index); 218 return GEN9_VEBOX_MOCS(index);
218 case VCS2: 219 case VCS2:
219 return GEN9_MFX1_MOCS(index); 220 return GEN9_MFX1_MOCS(index);
221 case VCS3:
222 return GEN11_MFX2_MOCS(index);
220 default: 223 default:
221 MISSING_CASE(engine_id); 224 MISSING_CASE(engine_id);
222 return INVALID_MMIO_REG; 225 return INVALID_MMIO_REG;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 36671a937fa4..c2f10d899329 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -807,6 +807,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
807 ret = PTR_ERR(vma); 807 ret = PTR_ERR(vma);
808 goto out_pin_section; 808 goto out_pin_section;
809 } 809 }
810 intel_fb_obj_flush(new_bo, ORIGIN_DIRTYFB);
810 811
811 ret = i915_vma_put_fence(vma); 812 ret = i915_vma_put_fence(vma);
812 if (ret) 813 if (ret)
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c
index 1f5cd572a7ff..39a4e4edda07 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -569,7 +569,8 @@ unlock:
569static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, 569static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
570 enum pipe pipe, 570 enum pipe pipe,
571 enum intel_pipe_crc_source *source, 571 enum intel_pipe_crc_source *source,
572 uint32_t *val) 572 uint32_t *val,
573 bool set_wa)
573{ 574{
574 if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) 575 if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
575 *source = INTEL_PIPE_CRC_SOURCE_PF; 576 *source = INTEL_PIPE_CRC_SOURCE_PF;
@@ -582,7 +583,7 @@ static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
582 *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB; 583 *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB;
583 break; 584 break;
584 case INTEL_PIPE_CRC_SOURCE_PF: 585 case INTEL_PIPE_CRC_SOURCE_PF:
585 if ((IS_HASWELL(dev_priv) || 586 if (set_wa && (IS_HASWELL(dev_priv) ||
586 IS_BROADWELL(dev_priv)) && pipe == PIPE_A) 587 IS_BROADWELL(dev_priv)) && pipe == PIPE_A)
587 hsw_pipe_A_crc_wa(dev_priv, true); 588 hsw_pipe_A_crc_wa(dev_priv, true);
588 589
@@ -600,7 +601,8 @@ static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
600 601
601static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv, 602static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv,
602 enum pipe pipe, 603 enum pipe pipe,
603 enum intel_pipe_crc_source *source, u32 *val) 604 enum intel_pipe_crc_source *source, u32 *val,
605 bool set_wa)
604{ 606{
605 if (IS_GEN2(dev_priv)) 607 if (IS_GEN2(dev_priv))
606 return i8xx_pipe_crc_ctl_reg(source, val); 608 return i8xx_pipe_crc_ctl_reg(source, val);
@@ -611,7 +613,7 @@ static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv,
611 else if (IS_GEN5(dev_priv) || IS_GEN6(dev_priv)) 613 else if (IS_GEN5(dev_priv) || IS_GEN6(dev_priv))
612 return ilk_pipe_crc_ctl_reg(source, val); 614 return ilk_pipe_crc_ctl_reg(source, val);
613 else 615 else
614 return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val); 616 return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val, set_wa);
615} 617}
616 618
617static int pipe_crc_set_source(struct drm_i915_private *dev_priv, 619static int pipe_crc_set_source(struct drm_i915_private *dev_priv,
@@ -636,7 +638,7 @@ static int pipe_crc_set_source(struct drm_i915_private *dev_priv,
636 return -EIO; 638 return -EIO;
637 } 639 }
638 640
639 ret = get_new_crc_ctl_reg(dev_priv, pipe, &source, &val); 641 ret = get_new_crc_ctl_reg(dev_priv, pipe, &source, &val, true);
640 if (ret != 0) 642 if (ret != 0)
641 goto out; 643 goto out;
642 644
@@ -764,13 +766,12 @@ display_crc_ctl_parse_object(const char *buf, enum intel_pipe_crc_object *o)
764{ 766{
765 int i; 767 int i;
766 768
767 for (i = 0; i < ARRAY_SIZE(pipe_crc_objects); i++) 769 i = match_string(pipe_crc_objects, ARRAY_SIZE(pipe_crc_objects), buf);
768 if (!strcmp(buf, pipe_crc_objects[i])) { 770 if (i < 0)
769 *o = i; 771 return i;
770 return 0;
771 }
772 772
773 return -EINVAL; 773 *o = i;
774 return 0;
774} 775}
775 776
776static int display_crc_ctl_parse_pipe(struct drm_i915_private *dev_priv, 777static int display_crc_ctl_parse_pipe(struct drm_i915_private *dev_priv,
@@ -796,13 +797,12 @@ display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s)
796 return 0; 797 return 0;
797 } 798 }
798 799
799 for (i = 0; i < ARRAY_SIZE(pipe_crc_sources); i++) 800 i = match_string(pipe_crc_sources, ARRAY_SIZE(pipe_crc_sources), buf);
800 if (!strcmp(buf, pipe_crc_sources[i])) { 801 if (i < 0)
801 *s = i; 802 return i;
802 return 0;
803 }
804 803
805 return -EINVAL; 804 *s = i;
805 return 0;
806} 806}
807 807
808static int display_crc_ctl_parse(struct drm_i915_private *dev_priv, 808static int display_crc_ctl_parse(struct drm_i915_private *dev_priv,
@@ -916,7 +916,7 @@ int intel_pipe_crc_create(struct drm_minor *minor)
916int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name, 916int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
917 size_t *values_cnt) 917 size_t *values_cnt)
918{ 918{
919 struct drm_i915_private *dev_priv = crtc->dev->dev_private; 919 struct drm_i915_private *dev_priv = to_i915(crtc->dev);
920 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[crtc->index]; 920 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[crtc->index];
921 enum intel_display_power_domain power_domain; 921 enum intel_display_power_domain power_domain;
922 enum intel_pipe_crc_source source; 922 enum intel_pipe_crc_source source;
@@ -934,10 +934,11 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
934 return -EIO; 934 return -EIO;
935 } 935 }
936 936
937 ret = get_new_crc_ctl_reg(dev_priv, crtc->index, &source, &val); 937 ret = get_new_crc_ctl_reg(dev_priv, crtc->index, &source, &val, true);
938 if (ret != 0) 938 if (ret != 0)
939 goto out; 939 goto out;
940 940
941 pipe_crc->source = source;
941 I915_WRITE(PIPE_CRC_CTL(crtc->index), val); 942 I915_WRITE(PIPE_CRC_CTL(crtc->index), val);
942 POSTING_READ(PIPE_CRC_CTL(crtc->index)); 943 POSTING_READ(PIPE_CRC_CTL(crtc->index));
943 944
@@ -959,3 +960,39 @@ out:
959 960
960 return ret; 961 return ret;
961} 962}
963
964void intel_crtc_enable_pipe_crc(struct intel_crtc *intel_crtc)
965{
966 struct drm_crtc *crtc = &intel_crtc->base;
967 struct drm_i915_private *dev_priv = to_i915(crtc->dev);
968 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[crtc->index];
969 u32 val = 0;
970
971 if (!crtc->crc.opened)
972 return;
973
974 if (get_new_crc_ctl_reg(dev_priv, crtc->index, &pipe_crc->source, &val, false) < 0)
975 return;
976
977 /* Don't need pipe_crc->lock here, IRQs are not generated. */
978 pipe_crc->skipped = 0;
979
980 I915_WRITE(PIPE_CRC_CTL(crtc->index), val);
981 POSTING_READ(PIPE_CRC_CTL(crtc->index));
982}
983
984void intel_crtc_disable_pipe_crc(struct intel_crtc *intel_crtc)
985{
986 struct drm_crtc *crtc = &intel_crtc->base;
987 struct drm_i915_private *dev_priv = to_i915(crtc->dev);
988 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[crtc->index];
989
990 /* Swallow crc's until we stop generating them. */
991 spin_lock_irq(&pipe_crc->lock);
992 pipe_crc->skipped = INT_MIN;
993 spin_unlock_irq(&pipe_crc->lock);
994
995 I915_WRITE(PIPE_CRC_CTL(crtc->index), 0);
996 POSTING_READ(PIPE_CRC_CTL(crtc->index));
997 synchronize_irq(dev_priv->drm.irq);
998}
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b8da4dcdd584..b85229e153c4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3567,6 +3567,23 @@ bool ilk_disable_lp_wm(struct drm_device *dev)
3567 return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); 3567 return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
3568} 3568}
3569 3569
3570static u8 intel_enabled_dbuf_slices_num(struct drm_i915_private *dev_priv)
3571{
3572 u8 enabled_slices;
3573
3574 /* Slice 1 will always be enabled */
3575 enabled_slices = 1;
3576
3577 /* Gen prior to GEN11 have only one DBuf slice */
3578 if (INTEL_GEN(dev_priv) < 11)
3579 return enabled_slices;
3580
3581 if (I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE)
3582 enabled_slices++;
3583
3584 return enabled_slices;
3585}
3586
3570/* 3587/*
3571 * FIXME: We still don't have the proper code detect if we need to apply the WA, 3588 * FIXME: We still don't have the proper code detect if we need to apply the WA,
3572 * so assume we'll always need it in order to avoid underruns. 3589 * so assume we'll always need it in order to avoid underruns.
@@ -3754,9 +3771,42 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
3754 return true; 3771 return true;
3755} 3772}
3756 3773
3774static unsigned int intel_get_ddb_size(struct drm_i915_private *dev_priv,
3775 const struct intel_crtc_state *cstate,
3776 const unsigned int total_data_rate,
3777 const int num_active,
3778 struct skl_ddb_allocation *ddb)
3779{
3780 const struct drm_display_mode *adjusted_mode;
3781 u64 total_data_bw;
3782 u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size;
3783
3784 WARN_ON(ddb_size == 0);
3785
3786 if (INTEL_GEN(dev_priv) < 11)
3787 return ddb_size - 4; /* 4 blocks for bypass path allocation */
3788
3789 adjusted_mode = &cstate->base.adjusted_mode;
3790 total_data_bw = (u64)total_data_rate * drm_mode_vrefresh(adjusted_mode);
3791
3792 /*
3793 * 12GB/s is maximum BW supported by single DBuf slice.
3794 */
3795 if (total_data_bw >= GBps(12) || num_active > 1) {
3796 ddb->enabled_slices = 2;
3797 } else {
3798 ddb->enabled_slices = 1;
3799 ddb_size /= 2;
3800 }
3801
3802 return ddb_size;
3803}
3804
3757static void 3805static void
3758skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, 3806skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
3759 const struct intel_crtc_state *cstate, 3807 const struct intel_crtc_state *cstate,
3808 const unsigned int total_data_rate,
3809 struct skl_ddb_allocation *ddb,
3760 struct skl_ddb_entry *alloc, /* out */ 3810 struct skl_ddb_entry *alloc, /* out */
3761 int *num_active /* out */) 3811 int *num_active /* out */)
3762{ 3812{
@@ -3779,11 +3829,8 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
3779 else 3829 else
3780 *num_active = hweight32(dev_priv->active_crtcs); 3830 *num_active = hweight32(dev_priv->active_crtcs);
3781 3831
3782 ddb_size = INTEL_INFO(dev_priv)->ddb_size; 3832 ddb_size = intel_get_ddb_size(dev_priv, cstate, total_data_rate,
3783 WARN_ON(ddb_size == 0); 3833 *num_active, ddb);
3784
3785 if (INTEL_GEN(dev_priv) < 11)
3786 ddb_size -= 4; /* 4 blocks for bypass path allocation */
3787 3834
3788 /* 3835 /*
3789 * If the state doesn't change the active CRTC's, then there's 3836 * If the state doesn't change the active CRTC's, then there's
@@ -3817,14 +3864,64 @@ static unsigned int skl_cursor_allocation(int num_active)
3817 return 8; 3864 return 8;
3818} 3865}
3819 3866
3820static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg) 3867static void skl_ddb_entry_init_from_hw(struct drm_i915_private *dev_priv,
3868 struct skl_ddb_entry *entry, u32 reg)
3821{ 3869{
3822 entry->start = reg & 0x3ff; 3870 u16 mask;
3823 entry->end = (reg >> 16) & 0x3ff; 3871
3872 if (INTEL_GEN(dev_priv) >= 11)
3873 mask = ICL_DDB_ENTRY_MASK;
3874 else
3875 mask = SKL_DDB_ENTRY_MASK;
3876 entry->start = reg & mask;
3877 entry->end = (reg >> DDB_ENTRY_END_SHIFT) & mask;
3878
3824 if (entry->end) 3879 if (entry->end)
3825 entry->end += 1; 3880 entry->end += 1;
3826} 3881}
3827 3882
3883static void
3884skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv,
3885 const enum pipe pipe,
3886 const enum plane_id plane_id,
3887 struct skl_ddb_allocation *ddb /* out */)
3888{
3889 u32 val, val2 = 0;
3890 int fourcc, pixel_format;
3891
3892 /* Cursor doesn't support NV12/planar, so no extra calculation needed */
3893 if (plane_id == PLANE_CURSOR) {
3894 val = I915_READ(CUR_BUF_CFG(pipe));
3895 skl_ddb_entry_init_from_hw(dev_priv,
3896 &ddb->plane[pipe][plane_id], val);
3897 return;
3898 }
3899
3900 val = I915_READ(PLANE_CTL(pipe, plane_id));
3901
3902 /* No DDB allocated for disabled planes */
3903 if (!(val & PLANE_CTL_ENABLE))
3904 return;
3905
3906 pixel_format = val & PLANE_CTL_FORMAT_MASK;
3907 fourcc = skl_format_to_fourcc(pixel_format,
3908 val & PLANE_CTL_ORDER_RGBX,
3909 val & PLANE_CTL_ALPHA_MASK);
3910
3911 val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
3912 val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
3913
3914 if (fourcc == DRM_FORMAT_NV12) {
3915 skl_ddb_entry_init_from_hw(dev_priv,
3916 &ddb->plane[pipe][plane_id], val2);
3917 skl_ddb_entry_init_from_hw(dev_priv,
3918 &ddb->uv_plane[pipe][plane_id], val);
3919 } else {
3920 skl_ddb_entry_init_from_hw(dev_priv,
3921 &ddb->plane[pipe][plane_id], val);
3922 }
3923}
3924
3828void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, 3925void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
3829 struct skl_ddb_allocation *ddb /* out */) 3926 struct skl_ddb_allocation *ddb /* out */)
3830{ 3927{
@@ -3832,6 +3929,8 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
3832 3929
3833 memset(ddb, 0, sizeof(*ddb)); 3930 memset(ddb, 0, sizeof(*ddb));
3834 3931
3932 ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);
3933
3835 for_each_intel_crtc(&dev_priv->drm, crtc) { 3934 for_each_intel_crtc(&dev_priv->drm, crtc) {
3836 enum intel_display_power_domain power_domain; 3935 enum intel_display_power_domain power_domain;
3837 enum plane_id plane_id; 3936 enum plane_id plane_id;
@@ -3841,16 +3940,9 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
3841 if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) 3940 if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
3842 continue; 3941 continue;
3843 3942
3844 for_each_plane_id_on_crtc(crtc, plane_id) { 3943 for_each_plane_id_on_crtc(crtc, plane_id)
3845 u32 val; 3944 skl_ddb_get_hw_plane_state(dev_priv, pipe,
3846 3945 plane_id, ddb);
3847 if (plane_id != PLANE_CURSOR)
3848 val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
3849 else
3850 val = I915_READ(CUR_BUF_CFG(pipe));
3851
3852 skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane_id], val);
3853 }
3854 3946
3855 intel_display_power_put(dev_priv, power_domain); 3947 intel_display_power_put(dev_priv, power_domain);
3856 } 3948 }
@@ -4009,9 +4101,9 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
4009static unsigned int 4101static unsigned int
4010skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, 4102skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
4011 const struct drm_plane_state *pstate, 4103 const struct drm_plane_state *pstate,
4012 int y) 4104 const int plane)
4013{ 4105{
4014 struct intel_plane *plane = to_intel_plane(pstate->plane); 4106 struct intel_plane *intel_plane = to_intel_plane(pstate->plane);
4015 struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); 4107 struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
4016 uint32_t data_rate; 4108 uint32_t data_rate;
4017 uint32_t width = 0, height = 0; 4109 uint32_t width = 0, height = 0;
@@ -4025,9 +4117,9 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
4025 fb = pstate->fb; 4117 fb = pstate->fb;
4026 format = fb->format->format; 4118 format = fb->format->format;
4027 4119
4028 if (plane->id == PLANE_CURSOR) 4120 if (intel_plane->id == PLANE_CURSOR)
4029 return 0; 4121 return 0;
4030 if (y && format != DRM_FORMAT_NV12) 4122 if (plane == 1 && format != DRM_FORMAT_NV12)
4031 return 0; 4123 return 0;
4032 4124
4033 /* 4125 /*
@@ -4038,19 +4130,14 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
4038 width = drm_rect_width(&intel_pstate->base.src) >> 16; 4130 width = drm_rect_width(&intel_pstate->base.src) >> 16;
4039 height = drm_rect_height(&intel_pstate->base.src) >> 16; 4131 height = drm_rect_height(&intel_pstate->base.src) >> 16;
4040 4132
4041 /* for planar format */ 4133 /* UV plane does 1/2 pixel sub-sampling */
4042 if (format == DRM_FORMAT_NV12) { 4134 if (plane == 1 && format == DRM_FORMAT_NV12) {
4043 if (y) /* y-plane data rate */ 4135 width /= 2;
4044 data_rate = width * height * 4136 height /= 2;
4045 fb->format->cpp[0];
4046 else /* uv-plane data rate */
4047 data_rate = (width / 2) * (height / 2) *
4048 fb->format->cpp[1];
4049 } else {
4050 /* for packed formats */
4051 data_rate = width * height * fb->format->cpp[0];
4052 } 4137 }
4053 4138
4139 data_rate = width * height * fb->format->cpp[plane];
4140
4054 down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate); 4141 down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate);
4055 4142
4056 return mul_round_up_u32_fixed16(data_rate, down_scale_amount); 4143 return mul_round_up_u32_fixed16(data_rate, down_scale_amount);
@@ -4063,8 +4150,8 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
4063 */ 4150 */
4064static unsigned int 4151static unsigned int
4065skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate, 4152skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
4066 unsigned *plane_data_rate, 4153 unsigned int *plane_data_rate,
4067 unsigned *plane_y_data_rate) 4154 unsigned int *uv_plane_data_rate)
4068{ 4155{
4069 struct drm_crtc_state *cstate = &intel_cstate->base; 4156 struct drm_crtc_state *cstate = &intel_cstate->base;
4070 struct drm_atomic_state *state = cstate->state; 4157 struct drm_atomic_state *state = cstate->state;
@@ -4080,17 +4167,17 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
4080 enum plane_id plane_id = to_intel_plane(plane)->id; 4167 enum plane_id plane_id = to_intel_plane(plane)->id;
4081 unsigned int rate; 4168 unsigned int rate;
4082 4169
4083 /* packed/uv */ 4170 /* packed/y */
4084 rate = skl_plane_relative_data_rate(intel_cstate, 4171 rate = skl_plane_relative_data_rate(intel_cstate,
4085 pstate, 0); 4172 pstate, 0);
4086 plane_data_rate[plane_id] = rate; 4173 plane_data_rate[plane_id] = rate;
4087 4174
4088 total_data_rate += rate; 4175 total_data_rate += rate;
4089 4176
4090 /* y-plane */ 4177 /* uv-plane */
4091 rate = skl_plane_relative_data_rate(intel_cstate, 4178 rate = skl_plane_relative_data_rate(intel_cstate,
4092 pstate, 1); 4179 pstate, 1);
4093 plane_y_data_rate[plane_id] = rate; 4180 uv_plane_data_rate[plane_id] = rate;
4094 4181
4095 total_data_rate += rate; 4182 total_data_rate += rate;
4096 } 4183 }
@@ -4099,8 +4186,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
4099} 4186}
4100 4187
4101static uint16_t 4188static uint16_t
4102skl_ddb_min_alloc(const struct drm_plane_state *pstate, 4189skl_ddb_min_alloc(const struct drm_plane_state *pstate, const int plane)
4103 const int y)
4104{ 4190{
4105 struct drm_framebuffer *fb = pstate->fb; 4191 struct drm_framebuffer *fb = pstate->fb;
4106 struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); 4192 struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
@@ -4111,8 +4197,8 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
4111 if (WARN_ON(!fb)) 4197 if (WARN_ON(!fb))
4112 return 0; 4198 return 0;
4113 4199
4114 /* For packed formats, no y-plane, return 0 */ 4200 /* For packed formats, and uv-plane, return 0 */
4115 if (y && fb->format->format != DRM_FORMAT_NV12) 4201 if (plane == 1 && fb->format->format != DRM_FORMAT_NV12)
4116 return 0; 4202 return 0;
4117 4203
4118 /* For Non Y-tile return 8-blocks */ 4204 /* For Non Y-tile return 8-blocks */
@@ -4131,15 +4217,12 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
4131 src_h = drm_rect_height(&intel_pstate->base.src) >> 16; 4217 src_h = drm_rect_height(&intel_pstate->base.src) >> 16;
4132 4218
4133 /* Halve UV plane width and height for NV12 */ 4219 /* Halve UV plane width and height for NV12 */
4134 if (fb->format->format == DRM_FORMAT_NV12 && !y) { 4220 if (plane == 1) {
4135 src_w /= 2; 4221 src_w /= 2;
4136 src_h /= 2; 4222 src_h /= 2;
4137 } 4223 }
4138 4224
4139 if (fb->format->format == DRM_FORMAT_NV12 && !y) 4225 plane_bpp = fb->format->cpp[plane];
4140 plane_bpp = fb->format->cpp[1];
4141 else
4142 plane_bpp = fb->format->cpp[0];
4143 4226
4144 if (drm_rotation_90_or_270(pstate->rotation)) { 4227 if (drm_rotation_90_or_270(pstate->rotation)) {
4145 switch (plane_bpp) { 4228 switch (plane_bpp) {
@@ -4167,7 +4250,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
4167 4250
4168static void 4251static void
4169skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active, 4252skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active,
4170 uint16_t *minimum, uint16_t *y_minimum) 4253 uint16_t *minimum, uint16_t *uv_minimum)
4171{ 4254{
4172 const struct drm_plane_state *pstate; 4255 const struct drm_plane_state *pstate;
4173 struct drm_plane *plane; 4256 struct drm_plane *plane;
@@ -4182,7 +4265,7 @@ skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active,
4182 continue; 4265 continue;
4183 4266
4184 minimum[plane_id] = skl_ddb_min_alloc(pstate, 0); 4267 minimum[plane_id] = skl_ddb_min_alloc(pstate, 0);
4185 y_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1); 4268 uv_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
4186 } 4269 }
4187 4270
4188 minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active); 4271 minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active);
@@ -4200,17 +4283,17 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
4200 struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb; 4283 struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb;
4201 uint16_t alloc_size, start; 4284 uint16_t alloc_size, start;
4202 uint16_t minimum[I915_MAX_PLANES] = {}; 4285 uint16_t minimum[I915_MAX_PLANES] = {};
4203 uint16_t y_minimum[I915_MAX_PLANES] = {}; 4286 uint16_t uv_minimum[I915_MAX_PLANES] = {};
4204 unsigned int total_data_rate; 4287 unsigned int total_data_rate;
4205 enum plane_id plane_id; 4288 enum plane_id plane_id;
4206 int num_active; 4289 int num_active;
4207 unsigned plane_data_rate[I915_MAX_PLANES] = {}; 4290 unsigned int plane_data_rate[I915_MAX_PLANES] = {};
4208 unsigned plane_y_data_rate[I915_MAX_PLANES] = {}; 4291 unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {};
4209 uint16_t total_min_blocks = 0; 4292 uint16_t total_min_blocks = 0;
4210 4293
4211 /* Clear the partitioning for disabled planes. */ 4294 /* Clear the partitioning for disabled planes. */
4212 memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); 4295 memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
4213 memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); 4296 memset(ddb->uv_plane[pipe], 0, sizeof(ddb->uv_plane[pipe]));
4214 4297
4215 if (WARN_ON(!state)) 4298 if (WARN_ON(!state))
4216 return 0; 4299 return 0;
@@ -4220,12 +4303,16 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
4220 return 0; 4303 return 0;
4221 } 4304 }
4222 4305
4223 skl_ddb_get_pipe_allocation_limits(dev, cstate, alloc, &num_active); 4306 total_data_rate = skl_get_total_relative_data_rate(cstate,
4307 plane_data_rate,
4308 uv_plane_data_rate);
4309 skl_ddb_get_pipe_allocation_limits(dev, cstate, total_data_rate, ddb,
4310 alloc, &num_active);
4224 alloc_size = skl_ddb_entry_size(alloc); 4311 alloc_size = skl_ddb_entry_size(alloc);
4225 if (alloc_size == 0) 4312 if (alloc_size == 0)
4226 return 0; 4313 return 0;
4227 4314
4228 skl_ddb_calc_min(cstate, num_active, minimum, y_minimum); 4315 skl_ddb_calc_min(cstate, num_active, minimum, uv_minimum);
4229 4316
4230 /* 4317 /*
4231 * 1. Allocate the mininum required blocks for each active plane 4318 * 1. Allocate the mininum required blocks for each active plane
@@ -4235,7 +4322,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
4235 4322
4236 for_each_plane_id_on_crtc(intel_crtc, plane_id) { 4323 for_each_plane_id_on_crtc(intel_crtc, plane_id) {
4237 total_min_blocks += minimum[plane_id]; 4324 total_min_blocks += minimum[plane_id];
4238 total_min_blocks += y_minimum[plane_id]; 4325 total_min_blocks += uv_minimum[plane_id];
4239 } 4326 }
4240 4327
4241 if (total_min_blocks > alloc_size) { 4328 if (total_min_blocks > alloc_size) {
@@ -4255,16 +4342,13 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
4255 * 4342 *
4256 * FIXME: we may not allocate every single block here. 4343 * FIXME: we may not allocate every single block here.
4257 */ 4344 */
4258 total_data_rate = skl_get_total_relative_data_rate(cstate,
4259 plane_data_rate,
4260 plane_y_data_rate);
4261 if (total_data_rate == 0) 4345 if (total_data_rate == 0)
4262 return 0; 4346 return 0;
4263 4347
4264 start = alloc->start; 4348 start = alloc->start;
4265 for_each_plane_id_on_crtc(intel_crtc, plane_id) { 4349 for_each_plane_id_on_crtc(intel_crtc, plane_id) {
4266 unsigned int data_rate, y_data_rate; 4350 unsigned int data_rate, uv_data_rate;
4267 uint16_t plane_blocks, y_plane_blocks = 0; 4351 uint16_t plane_blocks, uv_plane_blocks;
4268 4352
4269 if (plane_id == PLANE_CURSOR) 4353 if (plane_id == PLANE_CURSOR)
4270 continue; 4354 continue;
@@ -4288,21 +4372,20 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
4288 4372
4289 start += plane_blocks; 4373 start += plane_blocks;
4290 4374
4291 /* 4375 /* Allocate DDB for UV plane for planar format/NV12 */
4292 * allocation for y_plane part of planar format: 4376 uv_data_rate = uv_plane_data_rate[plane_id];
4293 */
4294 y_data_rate = plane_y_data_rate[plane_id];
4295 4377
4296 y_plane_blocks = y_minimum[plane_id]; 4378 uv_plane_blocks = uv_minimum[plane_id];
4297 y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, 4379 uv_plane_blocks += div_u64((uint64_t)alloc_size * uv_data_rate,
4298 total_data_rate); 4380 total_data_rate);
4299 4381
4300 if (y_data_rate) { 4382 if (uv_data_rate) {
4301 ddb->y_plane[pipe][plane_id].start = start; 4383 ddb->uv_plane[pipe][plane_id].start = start;
4302 ddb->y_plane[pipe][plane_id].end = start + y_plane_blocks; 4384 ddb->uv_plane[pipe][plane_id].end =
4385 start + uv_plane_blocks;
4303 } 4386 }
4304 4387
4305 start += y_plane_blocks; 4388 start += uv_plane_blocks;
4306 } 4389 }
4307 4390
4308 return 0; 4391 return 0;
@@ -4398,7 +4481,7 @@ static int
4398skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv, 4481skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
4399 struct intel_crtc_state *cstate, 4482 struct intel_crtc_state *cstate,
4400 const struct intel_plane_state *intel_pstate, 4483 const struct intel_plane_state *intel_pstate,
4401 struct skl_wm_params *wp) 4484 struct skl_wm_params *wp, int plane_id)
4402{ 4485{
4403 struct intel_plane *plane = to_intel_plane(intel_pstate->base.plane); 4486 struct intel_plane *plane = to_intel_plane(intel_pstate->base.plane);
4404 const struct drm_plane_state *pstate = &intel_pstate->base; 4487 const struct drm_plane_state *pstate = &intel_pstate->base;
@@ -4411,6 +4494,12 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
4411 if (!intel_wm_plane_visible(cstate, intel_pstate)) 4494 if (!intel_wm_plane_visible(cstate, intel_pstate))
4412 return 0; 4495 return 0;
4413 4496
4497 /* only NV12 format has two planes */
4498 if (plane_id == 1 && fb->format->format != DRM_FORMAT_NV12) {
4499 DRM_DEBUG_KMS("Non NV12 format have single plane\n");
4500 return -EINVAL;
4501 }
4502
4414 wp->y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED || 4503 wp->y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED ||
4415 fb->modifier == I915_FORMAT_MOD_Yf_TILED || 4504 fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
4416 fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || 4505 fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
@@ -4418,6 +4507,7 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
4418 wp->x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED; 4507 wp->x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED;
4419 wp->rc_surface = fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || 4508 wp->rc_surface = fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
4420 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS; 4509 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
4510 wp->is_planar = fb->format->format == DRM_FORMAT_NV12;
4421 4511
4422 if (plane->id == PLANE_CURSOR) { 4512 if (plane->id == PLANE_CURSOR) {
4423 wp->width = intel_pstate->base.crtc_w; 4513 wp->width = intel_pstate->base.crtc_w;
@@ -4430,8 +4520,10 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
4430 wp->width = drm_rect_width(&intel_pstate->base.src) >> 16; 4520 wp->width = drm_rect_width(&intel_pstate->base.src) >> 16;
4431 } 4521 }
4432 4522
4433 wp->cpp = (fb->format->format == DRM_FORMAT_NV12) ? fb->format->cpp[1] : 4523 if (plane_id == 1 && wp->is_planar)
4434 fb->format->cpp[0]; 4524 wp->width /= 2;
4525
4526 wp->cpp = fb->format->cpp[plane_id];
4435 wp->plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, 4527 wp->plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate,
4436 intel_pstate); 4528 intel_pstate);
4437 4529
@@ -4499,9 +4591,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
4499 uint16_t ddb_allocation, 4591 uint16_t ddb_allocation,
4500 int level, 4592 int level,
4501 const struct skl_wm_params *wp, 4593 const struct skl_wm_params *wp,
4502 uint16_t *out_blocks, /* out */ 4594 const struct skl_wm_level *result_prev,
4503 uint8_t *out_lines, /* out */ 4595 struct skl_wm_level *result /* out */)
4504 bool *enabled /* out */)
4505{ 4596{
4506 const struct drm_plane_state *pstate = &intel_pstate->base; 4597 const struct drm_plane_state *pstate = &intel_pstate->base;
4507 uint32_t latency = dev_priv->wm.skl_latency[level]; 4598 uint32_t latency = dev_priv->wm.skl_latency[level];
@@ -4515,7 +4606,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
4515 4606
4516 if (latency == 0 || 4607 if (latency == 0 ||
4517 !intel_wm_plane_visible(cstate, intel_pstate)) { 4608 !intel_wm_plane_visible(cstate, intel_pstate)) {
4518 *enabled = false; 4609 result->plane_en = false;
4519 return 0; 4610 return 0;
4520 } 4611 }
4521 4612
@@ -4568,6 +4659,15 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
4568 } else { 4659 } else {
4569 res_blocks++; 4660 res_blocks++;
4570 } 4661 }
4662
4663 /*
4664 * Make sure result blocks for higher latency levels are atleast
4665 * as high as level below the current level.
4666 * Assumption in DDB algorithm optimization for special cases.
4667 * Also covers Display WA #1125 for RC.
4668 */
4669 if (result_prev->plane_res_b > res_blocks)
4670 res_blocks = result_prev->plane_res_b;
4571 } 4671 }
4572 4672
4573 if (INTEL_GEN(dev_priv) >= 11) { 4673 if (INTEL_GEN(dev_priv) >= 11) {
@@ -4596,7 +4696,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
4596 if ((level > 0 && res_lines > 31) || 4696 if ((level > 0 && res_lines > 31) ||
4597 res_blocks >= ddb_allocation || 4697 res_blocks >= ddb_allocation ||
4598 min_disp_buf_needed >= ddb_allocation) { 4698 min_disp_buf_needed >= ddb_allocation) {
4599 *enabled = false; 4699 result->plane_en = false;
4600 4700
4601 /* 4701 /*
4602 * If there are no valid level 0 watermarks, then we can't 4702 * If there are no valid level 0 watermarks, then we can't
@@ -4615,10 +4715,21 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
4615 } 4715 }
4616 } 4716 }
4617 4717
4718 /*
4719 * Display WA #826 (SKL:ALL, BXT:ALL) & #1059 (CNL:A)
4720 * disable wm level 1-7 on NV12 planes
4721 */
4722 if (wp->is_planar && level >= 1 &&
4723 (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) ||
4724 IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0))) {
4725 result->plane_en = false;
4726 return 0;
4727 }
4728
4618 /* The number of lines are ignored for the level 0 watermark. */ 4729 /* The number of lines are ignored for the level 0 watermark. */
4619 *out_lines = level ? res_lines : 0; 4730 result->plane_res_b = res_blocks;
4620 *out_blocks = res_blocks; 4731 result->plane_res_l = res_lines;
4621 *enabled = true; 4732 result->plane_en = true;
4622 4733
4623 return 0; 4734 return 0;
4624} 4735}
@@ -4629,7 +4740,8 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
4629 struct intel_crtc_state *cstate, 4740 struct intel_crtc_state *cstate,
4630 const struct intel_plane_state *intel_pstate, 4741 const struct intel_plane_state *intel_pstate,
4631 const struct skl_wm_params *wm_params, 4742 const struct skl_wm_params *wm_params,
4632 struct skl_plane_wm *wm) 4743 struct skl_plane_wm *wm,
4744 int plane_id)
4633{ 4745{
4634 struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); 4746 struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
4635 struct drm_plane *plane = intel_pstate->base.plane; 4747 struct drm_plane *plane = intel_pstate->base.plane;
@@ -4637,15 +4749,26 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
4637 uint16_t ddb_blocks; 4749 uint16_t ddb_blocks;
4638 enum pipe pipe = intel_crtc->pipe; 4750 enum pipe pipe = intel_crtc->pipe;
4639 int level, max_level = ilk_wm_max_level(dev_priv); 4751 int level, max_level = ilk_wm_max_level(dev_priv);
4752 enum plane_id intel_plane_id = intel_plane->id;
4640 int ret; 4753 int ret;
4641 4754
4642 if (WARN_ON(!intel_pstate->base.fb)) 4755 if (WARN_ON(!intel_pstate->base.fb))
4643 return -EINVAL; 4756 return -EINVAL;
4644 4757
4645 ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][intel_plane->id]); 4758 ddb_blocks = plane_id ?
4759 skl_ddb_entry_size(&ddb->uv_plane[pipe][intel_plane_id]) :
4760 skl_ddb_entry_size(&ddb->plane[pipe][intel_plane_id]);
4646 4761
4647 for (level = 0; level <= max_level; level++) { 4762 for (level = 0; level <= max_level; level++) {
4648 struct skl_wm_level *result = &wm->wm[level]; 4763 struct skl_wm_level *result = plane_id ? &wm->uv_wm[level] :
4764 &wm->wm[level];
4765 struct skl_wm_level *result_prev;
4766
4767 if (level)
4768 result_prev = plane_id ? &wm->uv_wm[level - 1] :
4769 &wm->wm[level - 1];
4770 else
4771 result_prev = plane_id ? &wm->uv_wm[0] : &wm->wm[0];
4649 4772
4650 ret = skl_compute_plane_wm(dev_priv, 4773 ret = skl_compute_plane_wm(dev_priv,
4651 cstate, 4774 cstate,
@@ -4653,13 +4776,15 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
4653 ddb_blocks, 4776 ddb_blocks,
4654 level, 4777 level,
4655 wm_params, 4778 wm_params,
4656 &result->plane_res_b, 4779 result_prev,
4657 &result->plane_res_l, 4780 result);
4658 &result->plane_en);
4659 if (ret) 4781 if (ret)
4660 return ret; 4782 return ret;
4661 } 4783 }
4662 4784
4785 if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
4786 wm->is_planar = true;
4787
4663 return 0; 4788 return 0;
4664} 4789}
4665 4790
@@ -4769,20 +4894,39 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
4769 4894
4770 wm = &pipe_wm->planes[plane_id]; 4895 wm = &pipe_wm->planes[plane_id];
4771 ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]); 4896 ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
4772 memset(&wm_params, 0, sizeof(struct skl_wm_params));
4773 4897
4774 ret = skl_compute_plane_wm_params(dev_priv, cstate, 4898 ret = skl_compute_plane_wm_params(dev_priv, cstate,
4775 intel_pstate, &wm_params); 4899 intel_pstate, &wm_params, 0);
4776 if (ret) 4900 if (ret)
4777 return ret; 4901 return ret;
4778 4902
4779 ret = skl_compute_wm_levels(dev_priv, ddb, cstate, 4903 ret = skl_compute_wm_levels(dev_priv, ddb, cstate,
4780 intel_pstate, &wm_params, wm); 4904 intel_pstate, &wm_params, wm, 0);
4781 if (ret) 4905 if (ret)
4782 return ret; 4906 return ret;
4907
4783 skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0], 4908 skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0],
4784 ddb_blocks, &wm->trans_wm); 4909 ddb_blocks, &wm->trans_wm);
4910
4911 /* uv plane watermarks must also be validated for NV12/Planar */
4912 if (wm_params.is_planar) {
4913 memset(&wm_params, 0, sizeof(struct skl_wm_params));
4914 wm->is_planar = true;
4915
4916 ret = skl_compute_plane_wm_params(dev_priv, cstate,
4917 intel_pstate,
4918 &wm_params, 1);
4919 if (ret)
4920 return ret;
4921
4922 ret = skl_compute_wm_levels(dev_priv, ddb, cstate,
4923 intel_pstate, &wm_params,
4924 wm, 1);
4925 if (ret)
4926 return ret;
4927 }
4785 } 4928 }
4929
4786 pipe_wm->linetime = skl_compute_linetime_wm(cstate); 4930 pipe_wm->linetime = skl_compute_linetime_wm(cstate);
4787 4931
4788 return 0; 4932 return 0;
@@ -4833,10 +4977,21 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
4833 4977
4834 skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id), 4978 skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
4835 &ddb->plane[pipe][plane_id]); 4979 &ddb->plane[pipe][plane_id]);
4836 if (INTEL_GEN(dev_priv) < 11) 4980 if (INTEL_GEN(dev_priv) >= 11)
4981 return skl_ddb_entry_write(dev_priv,
4982 PLANE_BUF_CFG(pipe, plane_id),
4983 &ddb->plane[pipe][plane_id]);
4984 if (wm->is_planar) {
4985 skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
4986 &ddb->uv_plane[pipe][plane_id]);
4837 skl_ddb_entry_write(dev_priv, 4987 skl_ddb_entry_write(dev_priv,
4838 PLANE_NV12_BUF_CFG(pipe, plane_id), 4988 PLANE_NV12_BUF_CFG(pipe, plane_id),
4839 &ddb->y_plane[pipe][plane_id]); 4989 &ddb->plane[pipe][plane_id]);
4990 } else {
4991 skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
4992 &ddb->plane[pipe][plane_id]);
4993 I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
4994 }
4840} 4995}
4841 4996
4842static void skl_write_cursor_wm(struct intel_crtc *intel_crtc, 4997static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
@@ -4944,15 +5099,13 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
4944 struct drm_plane *plane; 5099 struct drm_plane *plane;
4945 enum pipe pipe = intel_crtc->pipe; 5100 enum pipe pipe = intel_crtc->pipe;
4946 5101
4947 WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc));
4948
4949 drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) { 5102 drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
4950 enum plane_id plane_id = to_intel_plane(plane)->id; 5103 enum plane_id plane_id = to_intel_plane(plane)->id;
4951 5104
4952 if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id], 5105 if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
4953 &new_ddb->plane[pipe][plane_id]) && 5106 &new_ddb->plane[pipe][plane_id]) &&
4954 skl_ddb_entry_equal(&cur_ddb->y_plane[pipe][plane_id], 5107 skl_ddb_entry_equal(&cur_ddb->uv_plane[pipe][plane_id],
4955 &new_ddb->y_plane[pipe][plane_id])) 5108 &new_ddb->uv_plane[pipe][plane_id]))
4956 continue; 5109 continue;
4957 5110
4958 plane_state = drm_atomic_get_plane_state(state, plane); 5111 plane_state = drm_atomic_get_plane_state(state, plane);
@@ -4966,69 +5119,16 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
4966static int 5119static int
4967skl_compute_ddb(struct drm_atomic_state *state) 5120skl_compute_ddb(struct drm_atomic_state *state)
4968{ 5121{
4969 struct drm_device *dev = state->dev; 5122 const struct drm_i915_private *dev_priv = to_i915(state->dev);
4970 struct drm_i915_private *dev_priv = to_i915(dev);
4971 struct intel_atomic_state *intel_state = to_intel_atomic_state(state); 5123 struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
4972 struct intel_crtc *intel_crtc;
4973 struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb; 5124 struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb;
4974 uint32_t realloc_pipes = pipes_modified(state); 5125 struct intel_crtc *crtc;
4975 int ret; 5126 struct intel_crtc_state *cstate;
4976 5127 int ret, i;
4977 /*
4978 * If this is our first atomic update following hardware readout,
4979 * we can't trust the DDB that the BIOS programmed for us. Let's
4980 * pretend that all pipes switched active status so that we'll
4981 * ensure a full DDB recompute.
4982 */
4983 if (dev_priv->wm.distrust_bios_wm) {
4984 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
4985 state->acquire_ctx);
4986 if (ret)
4987 return ret;
4988
4989 intel_state->active_pipe_changes = ~0;
4990
4991 /*
4992 * We usually only initialize intel_state->active_crtcs if we
4993 * we're doing a modeset; make sure this field is always
4994 * initialized during the sanitization process that happens
4995 * on the first commit too.
4996 */
4997 if (!intel_state->modeset)
4998 intel_state->active_crtcs = dev_priv->active_crtcs;
4999 }
5000
5001 /*
5002 * If the modeset changes which CRTC's are active, we need to
5003 * recompute the DDB allocation for *all* active pipes, even
5004 * those that weren't otherwise being modified in any way by this
5005 * atomic commit. Due to the shrinking of the per-pipe allocations
5006 * when new active CRTC's are added, it's possible for a pipe that
5007 * we were already using and aren't changing at all here to suddenly
5008 * become invalid if its DDB needs exceeds its new allocation.
5009 *
5010 * Note that if we wind up doing a full DDB recompute, we can't let
5011 * any other display updates race with this transaction, so we need
5012 * to grab the lock on *all* CRTC's.
5013 */
5014 if (intel_state->active_pipe_changes) {
5015 realloc_pipes = ~0;
5016 intel_state->wm_results.dirty_pipes = ~0;
5017 }
5018 5128
5019 /*
5020 * We're not recomputing for the pipes not included in the commit, so
5021 * make sure we start with the current state.
5022 */
5023 memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb)); 5129 memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb));
5024 5130
5025 for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) { 5131 for_each_new_intel_crtc_in_state(intel_state, crtc, cstate, i) {
5026 struct intel_crtc_state *cstate;
5027
5028 cstate = intel_atomic_get_crtc_state(state, intel_crtc);
5029 if (IS_ERR(cstate))
5030 return PTR_ERR(cstate);
5031
5032 ret = skl_allocate_pipe_ddb(cstate, ddb); 5132 ret = skl_allocate_pipe_ddb(cstate, ddb);
5033 if (ret) 5133 if (ret)
5034 return ret; 5134 return ret;
@@ -5042,14 +5142,15 @@ skl_compute_ddb(struct drm_atomic_state *state)
5042} 5142}
5043 5143
5044static void 5144static void
5045skl_copy_wm_for_pipe(struct skl_wm_values *dst, 5145skl_copy_ddb_for_pipe(struct skl_ddb_values *dst,
5046 struct skl_wm_values *src, 5146 struct skl_ddb_values *src,
5047 enum pipe pipe) 5147 enum pipe pipe)
5048{ 5148{
5049 memcpy(dst->ddb.y_plane[pipe], src->ddb.y_plane[pipe], 5149 memcpy(dst->ddb.uv_plane[pipe], src->ddb.uv_plane[pipe],
5050 sizeof(dst->ddb.y_plane[pipe])); 5150 sizeof(dst->ddb.uv_plane[pipe]));
5051 memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe], 5151 memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe],
5052 sizeof(dst->ddb.plane[pipe])); 5152 sizeof(dst->ddb.plane[pipe]));
5153 dst->ddb.enabled_slices = src->ddb.enabled_slices;
5053} 5154}
5054 5155
5055static void 5156static void
@@ -5090,23 +5191,23 @@ skl_print_wm_changes(const struct drm_atomic_state *state)
5090} 5191}
5091 5192
5092static int 5193static int
5093skl_compute_wm(struct drm_atomic_state *state) 5194skl_ddb_add_affected_pipes(struct drm_atomic_state *state, bool *changed)
5094{ 5195{
5095 struct drm_crtc *crtc;
5096 struct drm_crtc_state *cstate;
5097 struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
5098 struct skl_wm_values *results = &intel_state->wm_results;
5099 struct drm_device *dev = state->dev; 5196 struct drm_device *dev = state->dev;
5100 struct skl_pipe_wm *pipe_wm; 5197 const struct drm_i915_private *dev_priv = to_i915(dev);
5101 bool changed = false; 5198 const struct drm_crtc *crtc;
5199 const struct drm_crtc_state *cstate;
5200 struct intel_crtc *intel_crtc;
5201 struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
5202 uint32_t realloc_pipes = pipes_modified(state);
5102 int ret, i; 5203 int ret, i;
5103 5204
5104 /* 5205 /*
5105 * When we distrust bios wm we always need to recompute to set the 5206 * When we distrust bios wm we always need to recompute to set the
5106 * expected DDB allocations for each CRTC. 5207 * expected DDB allocations for each CRTC.
5107 */ 5208 */
5108 if (to_i915(dev)->wm.distrust_bios_wm) 5209 if (dev_priv->wm.distrust_bios_wm)
5109 changed = true; 5210 (*changed) = true;
5110 5211
5111 /* 5212 /*
5112 * If this transaction isn't actually touching any CRTC's, don't 5213 * If this transaction isn't actually touching any CRTC's, don't
@@ -5117,14 +5218,86 @@ skl_compute_wm(struct drm_atomic_state *state)
5117 * hold _all_ CRTC state mutexes. 5218 * hold _all_ CRTC state mutexes.
5118 */ 5219 */
5119 for_each_new_crtc_in_state(state, crtc, cstate, i) 5220 for_each_new_crtc_in_state(state, crtc, cstate, i)
5120 changed = true; 5221 (*changed) = true;
5121 5222
5122 if (!changed) 5223 if (!*changed)
5123 return 0; 5224 return 0;
5124 5225
5226 /*
5227 * If this is our first atomic update following hardware readout,
5228 * we can't trust the DDB that the BIOS programmed for us. Let's
5229 * pretend that all pipes switched active status so that we'll
5230 * ensure a full DDB recompute.
5231 */
5232 if (dev_priv->wm.distrust_bios_wm) {
5233 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
5234 state->acquire_ctx);
5235 if (ret)
5236 return ret;
5237
5238 intel_state->active_pipe_changes = ~0;
5239
5240 /*
5241 * We usually only initialize intel_state->active_crtcs if we
5242 * we're doing a modeset; make sure this field is always
5243 * initialized during the sanitization process that happens
5244 * on the first commit too.
5245 */
5246 if (!intel_state->modeset)
5247 intel_state->active_crtcs = dev_priv->active_crtcs;
5248 }
5249
5250 /*
5251 * If the modeset changes which CRTC's are active, we need to
5252 * recompute the DDB allocation for *all* active pipes, even
5253 * those that weren't otherwise being modified in any way by this
5254 * atomic commit. Due to the shrinking of the per-pipe allocations
5255 * when new active CRTC's are added, it's possible for a pipe that
5256 * we were already using and aren't changing at all here to suddenly
5257 * become invalid if its DDB needs exceeds its new allocation.
5258 *
5259 * Note that if we wind up doing a full DDB recompute, we can't let
5260 * any other display updates race with this transaction, so we need
5261 * to grab the lock on *all* CRTC's.
5262 */
5263 if (intel_state->active_pipe_changes) {
5264 realloc_pipes = ~0;
5265 intel_state->wm_results.dirty_pipes = ~0;
5266 }
5267
5268 /*
5269 * We're not recomputing for the pipes not included in the commit, so
5270 * make sure we start with the current state.
5271 */
5272 for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
5273 struct intel_crtc_state *cstate;
5274
5275 cstate = intel_atomic_get_crtc_state(state, intel_crtc);
5276 if (IS_ERR(cstate))
5277 return PTR_ERR(cstate);
5278 }
5279
5280 return 0;
5281}
5282
5283static int
5284skl_compute_wm(struct drm_atomic_state *state)
5285{
5286 struct drm_crtc *crtc;
5287 struct drm_crtc_state *cstate;
5288 struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
5289 struct skl_ddb_values *results = &intel_state->wm_results;
5290 struct skl_pipe_wm *pipe_wm;
5291 bool changed = false;
5292 int ret, i;
5293
5125 /* Clear all dirty flags */ 5294 /* Clear all dirty flags */
5126 results->dirty_pipes = 0; 5295 results->dirty_pipes = 0;
5127 5296
5297 ret = skl_ddb_add_affected_pipes(state, &changed);
5298 if (ret || !changed)
5299 return ret;
5300
5128 ret = skl_compute_ddb(state); 5301 ret = skl_compute_ddb(state);
5129 if (ret) 5302 if (ret)
5130 return ret; 5303 return ret;
@@ -5197,8 +5370,8 @@ static void skl_initial_wm(struct intel_atomic_state *state,
5197 struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); 5370 struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
5198 struct drm_device *dev = intel_crtc->base.dev; 5371 struct drm_device *dev = intel_crtc->base.dev;
5199 struct drm_i915_private *dev_priv = to_i915(dev); 5372 struct drm_i915_private *dev_priv = to_i915(dev);
5200 struct skl_wm_values *results = &state->wm_results; 5373 struct skl_ddb_values *results = &state->wm_results;
5201 struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw; 5374 struct skl_ddb_values *hw_vals = &dev_priv->wm.skl_hw;
5202 enum pipe pipe = intel_crtc->pipe; 5375 enum pipe pipe = intel_crtc->pipe;
5203 5376
5204 if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0) 5377 if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0)
@@ -5209,7 +5382,7 @@ static void skl_initial_wm(struct intel_atomic_state *state,
5209 if (cstate->base.active_changed) 5382 if (cstate->base.active_changed)
5210 skl_atomic_update_crtc_wm(state, cstate); 5383 skl_atomic_update_crtc_wm(state, cstate);
5211 5384
5212 skl_copy_wm_for_pipe(hw_vals, results, pipe); 5385 skl_copy_ddb_for_pipe(hw_vals, results, pipe);
5213 5386
5214 mutex_unlock(&dev_priv->wm.wm_mutex); 5387 mutex_unlock(&dev_priv->wm.wm_mutex);
5215} 5388}
@@ -5341,7 +5514,7 @@ void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
5341void skl_wm_get_hw_state(struct drm_device *dev) 5514void skl_wm_get_hw_state(struct drm_device *dev)
5342{ 5515{
5343 struct drm_i915_private *dev_priv = to_i915(dev); 5516 struct drm_i915_private *dev_priv = to_i915(dev);
5344 struct skl_wm_values *hw = &dev_priv->wm.skl_hw; 5517 struct skl_ddb_values *hw = &dev_priv->wm.skl_hw;
5345 struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb; 5518 struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb;
5346 struct drm_crtc *crtc; 5519 struct drm_crtc *crtc;
5347 struct intel_crtc *intel_crtc; 5520 struct intel_crtc *intel_crtc;
@@ -5362,8 +5535,12 @@ void skl_wm_get_hw_state(struct drm_device *dev)
5362 /* Fully recompute DDB on first atomic commit */ 5535 /* Fully recompute DDB on first atomic commit */
5363 dev_priv->wm.distrust_bios_wm = true; 5536 dev_priv->wm.distrust_bios_wm = true;
5364 } else { 5537 } else {
5365 /* Easy/common case; just sanitize DDB now if everything off */ 5538 /*
5366 memset(ddb, 0, sizeof(*ddb)); 5539 * Easy/common case; just sanitize DDB now if everything off
5540 * Keep dbuf slice info intact
5541 */
5542 memset(ddb->plane, 0, sizeof(ddb->plane));
5543 memset(ddb->uv_plane, 0, sizeof(ddb->uv_plane));
5367 } 5544 }
5368} 5545}
5369 5546
@@ -6572,7 +6749,7 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
6572 6749
6573 rps->efficient_freq = rps->rp1_freq; 6750 rps->efficient_freq = rps->rp1_freq;
6574 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) || 6751 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
6575 IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { 6752 IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
6576 u32 ddcc_status = 0; 6753 u32 ddcc_status = 0;
6577 6754
6578 if (sandybridge_pcode_read(dev_priv, 6755 if (sandybridge_pcode_read(dev_priv,
@@ -6585,7 +6762,7 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
6585 rps->max_freq); 6762 rps->max_freq);
6586 } 6763 }
6587 6764
6588 if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { 6765 if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
6589 /* Store the frequency values in 16.66 MHZ units, which is 6766 /* Store the frequency values in 16.66 MHZ units, which is
6590 * the natural hardware unit for SKL 6767 * the natural hardware unit for SKL
6591 */ 6768 */
@@ -6890,15 +7067,18 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv)
6890static void gen6_update_ring_freq(struct drm_i915_private *dev_priv) 7067static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
6891{ 7068{
6892 struct intel_rps *rps = &dev_priv->gt_pm.rps; 7069 struct intel_rps *rps = &dev_priv->gt_pm.rps;
6893 int min_freq = 15; 7070 const int min_freq = 15;
7071 const int scaling_factor = 180;
6894 unsigned int gpu_freq; 7072 unsigned int gpu_freq;
6895 unsigned int max_ia_freq, min_ring_freq; 7073 unsigned int max_ia_freq, min_ring_freq;
6896 unsigned int max_gpu_freq, min_gpu_freq; 7074 unsigned int max_gpu_freq, min_gpu_freq;
6897 int scaling_factor = 180;
6898 struct cpufreq_policy *policy; 7075 struct cpufreq_policy *policy;
6899 7076
6900 WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); 7077 WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
6901 7078
7079 if (rps->max_freq <= rps->min_freq)
7080 return;
7081
6902 policy = cpufreq_cpu_get(0); 7082 policy = cpufreq_cpu_get(0);
6903 if (policy) { 7083 if (policy) {
6904 max_ia_freq = policy->cpuinfo.max_freq; 7084 max_ia_freq = policy->cpuinfo.max_freq;
@@ -6918,13 +7098,12 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
6918 /* convert DDR frequency from units of 266.6MHz to bandwidth */ 7098 /* convert DDR frequency from units of 266.6MHz to bandwidth */
6919 min_ring_freq = mult_frac(min_ring_freq, 8, 3); 7099 min_ring_freq = mult_frac(min_ring_freq, 8, 3);
6920 7100
6921 if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { 7101 min_gpu_freq = rps->min_freq;
7102 max_gpu_freq = rps->max_freq;
7103 if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
6922 /* Convert GT frequency to 50 HZ units */ 7104 /* Convert GT frequency to 50 HZ units */
6923 min_gpu_freq = rps->min_freq / GEN9_FREQ_SCALER; 7105 min_gpu_freq /= GEN9_FREQ_SCALER;
6924 max_gpu_freq = rps->max_freq / GEN9_FREQ_SCALER; 7106 max_gpu_freq /= GEN9_FREQ_SCALER;
6925 } else {
6926 min_gpu_freq = rps->min_freq;
6927 max_gpu_freq = rps->max_freq;
6928 } 7107 }
6929 7108
6930 /* 7109 /*
@@ -6933,10 +7112,10 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
6933 * the PCU should use as a reference to determine the ring frequency. 7112 * the PCU should use as a reference to determine the ring frequency.
6934 */ 7113 */
6935 for (gpu_freq = max_gpu_freq; gpu_freq >= min_gpu_freq; gpu_freq--) { 7114 for (gpu_freq = max_gpu_freq; gpu_freq >= min_gpu_freq; gpu_freq--) {
6936 int diff = max_gpu_freq - gpu_freq; 7115 const int diff = max_gpu_freq - gpu_freq;
6937 unsigned int ia_freq = 0, ring_freq = 0; 7116 unsigned int ia_freq = 0, ring_freq = 0;
6938 7117
6939 if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { 7118 if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
6940 /* 7119 /*
6941 * ring_freq = 2 * GT. ring_freq is in 100MHz units 7120 * ring_freq = 2 * GT. ring_freq is in 100MHz units
6942 * No floor required for ring frequency on SKL. 7121 * No floor required for ring frequency on SKL.
@@ -8026,10 +8205,10 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
8026 dev_priv->gt_pm.rc6.enabled = true; /* force RC6 disabling */ 8205 dev_priv->gt_pm.rc6.enabled = true; /* force RC6 disabling */
8027 intel_disable_gt_powersave(dev_priv); 8206 intel_disable_gt_powersave(dev_priv);
8028 8207
8029 if (INTEL_GEN(dev_priv) < 11) 8208 if (INTEL_GEN(dev_priv) >= 11)
8030 gen6_reset_rps_interrupts(dev_priv); 8209 gen11_reset_rps_interrupts(dev_priv);
8031 else 8210 else
8032 WARN_ON_ONCE(1); 8211 gen6_reset_rps_interrupts(dev_priv);
8033} 8212}
8034 8213
8035static inline void intel_disable_llc_pstate(struct drm_i915_private *i915) 8214static inline void intel_disable_llc_pstate(struct drm_i915_private *i915)
@@ -8142,8 +8321,6 @@ static void intel_enable_rps(struct drm_i915_private *dev_priv)
8142 cherryview_enable_rps(dev_priv); 8321 cherryview_enable_rps(dev_priv);
8143 } else if (IS_VALLEYVIEW(dev_priv)) { 8322 } else if (IS_VALLEYVIEW(dev_priv)) {
8144 valleyview_enable_rps(dev_priv); 8323 valleyview_enable_rps(dev_priv);
8145 } else if (WARN_ON_ONCE(INTEL_GEN(dev_priv) >= 11)) {
8146 /* TODO */
8147 } else if (INTEL_GEN(dev_priv) >= 9) { 8324 } else if (INTEL_GEN(dev_priv) >= 9) {
8148 gen9_enable_rps(dev_priv); 8325 gen9_enable_rps(dev_priv);
8149 } else if (IS_BROADWELL(dev_priv)) { 8326 } else if (IS_BROADWELL(dev_priv)) {
@@ -8487,6 +8664,13 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
8487 I915_WRITE(GEN7_MISCCPCTL, misccpctl); 8664 I915_WRITE(GEN7_MISCCPCTL, misccpctl);
8488} 8665}
8489 8666
8667static void icl_init_clock_gating(struct drm_i915_private *dev_priv)
8668{
8669 /* This is not an Wa. Enable to reduce Sampler power */
8670 I915_WRITE(GEN10_DFR_RATIO_EN_AND_CHICKEN,
8671 I915_READ(GEN10_DFR_RATIO_EN_AND_CHICKEN) & ~DFR_DISABLE);
8672}
8673
8490static void cnp_init_clock_gating(struct drm_i915_private *dev_priv) 8674static void cnp_init_clock_gating(struct drm_i915_private *dev_priv)
8491{ 8675{
8492 if (!HAS_PCH_CNP(dev_priv)) 8676 if (!HAS_PCH_CNP(dev_priv))
@@ -9013,7 +9197,9 @@ static void nop_init_clock_gating(struct drm_i915_private *dev_priv)
9013 */ 9197 */
9014void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) 9198void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
9015{ 9199{
9016 if (IS_CANNONLAKE(dev_priv)) 9200 if (IS_ICELAKE(dev_priv))
9201 dev_priv->display.init_clock_gating = icl_init_clock_gating;
9202 else if (IS_CANNONLAKE(dev_priv))
9017 dev_priv->display.init_clock_gating = cnl_init_clock_gating; 9203 dev_priv->display.init_clock_gating = cnl_init_clock_gating;
9018 else if (IS_COFFEELAKE(dev_priv)) 9204 else if (IS_COFFEELAKE(dev_priv))
9019 dev_priv->display.init_clock_gating = cfl_init_clock_gating; 9205 dev_priv->display.init_clock_gating = cfl_init_clock_gating;
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 23175c5c4a50..db27f2faa1de 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -93,7 +93,115 @@ static void psr_aux_io_power_put(struct intel_dp *intel_dp)
93 intel_display_power_put(dev_priv, psr_aux_domain(intel_dp)); 93 intel_display_power_put(dev_priv, psr_aux_domain(intel_dp));
94} 94}
95 95
96static bool intel_dp_get_y_cord_status(struct intel_dp *intel_dp) 96void intel_psr_irq_control(struct drm_i915_private *dev_priv, bool debug)
97{
98 u32 debug_mask, mask;
99
100 /* No PSR interrupts on VLV/CHV */
101 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
102 return;
103
104 mask = EDP_PSR_ERROR(TRANSCODER_EDP);
105 debug_mask = EDP_PSR_POST_EXIT(TRANSCODER_EDP) |
106 EDP_PSR_PRE_ENTRY(TRANSCODER_EDP);
107
108 if (INTEL_GEN(dev_priv) >= 8) {
109 mask |= EDP_PSR_ERROR(TRANSCODER_A) |
110 EDP_PSR_ERROR(TRANSCODER_B) |
111 EDP_PSR_ERROR(TRANSCODER_C);
112
113 debug_mask |= EDP_PSR_POST_EXIT(TRANSCODER_A) |
114 EDP_PSR_PRE_ENTRY(TRANSCODER_A) |
115 EDP_PSR_POST_EXIT(TRANSCODER_B) |
116 EDP_PSR_PRE_ENTRY(TRANSCODER_B) |
117 EDP_PSR_POST_EXIT(TRANSCODER_C) |
118 EDP_PSR_PRE_ENTRY(TRANSCODER_C);
119 }
120
121 if (debug)
122 mask |= debug_mask;
123
124 WRITE_ONCE(dev_priv->psr.debug, debug);
125 I915_WRITE(EDP_PSR_IMR, ~mask);
126}
127
128static void psr_event_print(u32 val, bool psr2_enabled)
129{
130 DRM_DEBUG_KMS("PSR exit events: 0x%x\n", val);
131 if (val & PSR_EVENT_PSR2_WD_TIMER_EXPIRE)
132 DRM_DEBUG_KMS("\tPSR2 watchdog timer expired\n");
133 if ((val & PSR_EVENT_PSR2_DISABLED) && psr2_enabled)
134 DRM_DEBUG_KMS("\tPSR2 disabled\n");
135 if (val & PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN)
136 DRM_DEBUG_KMS("\tSU dirty FIFO underrun\n");
137 if (val & PSR_EVENT_SU_CRC_FIFO_UNDERRUN)
138 DRM_DEBUG_KMS("\tSU CRC FIFO underrun\n");
139 if (val & PSR_EVENT_GRAPHICS_RESET)
140 DRM_DEBUG_KMS("\tGraphics reset\n");
141 if (val & PSR_EVENT_PCH_INTERRUPT)
142 DRM_DEBUG_KMS("\tPCH interrupt\n");
143 if (val & PSR_EVENT_MEMORY_UP)
144 DRM_DEBUG_KMS("\tMemory up\n");
145 if (val & PSR_EVENT_FRONT_BUFFER_MODIFY)
146 DRM_DEBUG_KMS("\tFront buffer modification\n");
147 if (val & PSR_EVENT_WD_TIMER_EXPIRE)
148 DRM_DEBUG_KMS("\tPSR watchdog timer expired\n");
149 if (val & PSR_EVENT_PIPE_REGISTERS_UPDATE)
150 DRM_DEBUG_KMS("\tPIPE registers updated\n");
151 if (val & PSR_EVENT_REGISTER_UPDATE)
152 DRM_DEBUG_KMS("\tRegister updated\n");
153 if (val & PSR_EVENT_HDCP_ENABLE)
154 DRM_DEBUG_KMS("\tHDCP enabled\n");
155 if (val & PSR_EVENT_KVMR_SESSION_ENABLE)
156 DRM_DEBUG_KMS("\tKVMR session enabled\n");
157 if (val & PSR_EVENT_VBI_ENABLE)
158 DRM_DEBUG_KMS("\tVBI enabled\n");
159 if (val & PSR_EVENT_LPSP_MODE_EXIT)
160 DRM_DEBUG_KMS("\tLPSP mode exited\n");
161 if ((val & PSR_EVENT_PSR_DISABLE) && !psr2_enabled)
162 DRM_DEBUG_KMS("\tPSR disabled\n");
163}
164
165void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
166{
167 u32 transcoders = BIT(TRANSCODER_EDP);
168 enum transcoder cpu_transcoder;
169 ktime_t time_ns = ktime_get();
170
171 if (INTEL_GEN(dev_priv) >= 8)
172 transcoders |= BIT(TRANSCODER_A) |
173 BIT(TRANSCODER_B) |
174 BIT(TRANSCODER_C);
175
176 for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) {
177 /* FIXME: Exit PSR and link train manually when this happens. */
178 if (psr_iir & EDP_PSR_ERROR(cpu_transcoder))
179 DRM_DEBUG_KMS("[transcoder %s] PSR aux error\n",
180 transcoder_name(cpu_transcoder));
181
182 if (psr_iir & EDP_PSR_PRE_ENTRY(cpu_transcoder)) {
183 dev_priv->psr.last_entry_attempt = time_ns;
184 DRM_DEBUG_KMS("[transcoder %s] PSR entry attempt in 2 vblanks\n",
185 transcoder_name(cpu_transcoder));
186 }
187
188 if (psr_iir & EDP_PSR_POST_EXIT(cpu_transcoder)) {
189 dev_priv->psr.last_exit = time_ns;
190 DRM_DEBUG_KMS("[transcoder %s] PSR exit completed\n",
191 transcoder_name(cpu_transcoder));
192
193 if (INTEL_GEN(dev_priv) >= 9) {
194 u32 val = I915_READ(PSR_EVENT(cpu_transcoder));
195 bool psr2_enabled = dev_priv->psr.psr2_enabled;
196
197 I915_WRITE(PSR_EVENT(cpu_transcoder), val);
198 psr_event_print(val, psr2_enabled);
199 }
200 }
201 }
202}
203
204static bool intel_dp_get_y_coord_required(struct intel_dp *intel_dp)
97{ 205{
98 uint8_t psr_caps = 0; 206 uint8_t psr_caps = 0;
99 207
@@ -122,6 +230,18 @@ static bool intel_dp_get_alpm_status(struct intel_dp *intel_dp)
122 return alpm_caps & DP_ALPM_CAP; 230 return alpm_caps & DP_ALPM_CAP;
123} 231}
124 232
233static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
234{
235 u8 val = 0;
236
237 if (drm_dp_dpcd_readb(&intel_dp->aux,
238 DP_SYNCHRONIZATION_LATENCY_IN_SINK, &val) == 1)
239 val &= DP_MAX_RESYNC_FRAME_COUNT_MASK;
240 else
241 DRM_ERROR("Unable to get sink synchronization latency\n");
242 return val;
243}
244
125void intel_psr_init_dpcd(struct intel_dp *intel_dp) 245void intel_psr_init_dpcd(struct intel_dp *intel_dp)
126{ 246{
127 struct drm_i915_private *dev_priv = 247 struct drm_i915_private *dev_priv =
@@ -130,33 +250,36 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
130 drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd, 250 drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd,
131 sizeof(intel_dp->psr_dpcd)); 251 sizeof(intel_dp->psr_dpcd));
132 252
133 if (intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED) { 253 if (intel_dp->psr_dpcd[0]) {
134 dev_priv->psr.sink_support = true; 254 dev_priv->psr.sink_support = true;
135 DRM_DEBUG_KMS("Detected EDP PSR Panel.\n"); 255 DRM_DEBUG_KMS("Detected EDP PSR Panel.\n");
136 } 256 }
137 257
138 if (INTEL_GEN(dev_priv) >= 9 && 258 if (INTEL_GEN(dev_priv) >= 9 &&
139 (intel_dp->psr_dpcd[0] & DP_PSR2_IS_SUPPORTED)) { 259 (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)) {
140 uint8_t frame_sync_cap; 260 /*
261 * All panels that supports PSR version 03h (PSR2 +
262 * Y-coordinate) can handle Y-coordinates in VSC but we are
263 * only sure that it is going to be used when required by the
264 * panel. This way panel is capable to do selective update
265 * without a aux frame sync.
266 *
267 * To support PSR version 02h and PSR version 03h without
268 * Y-coordinate requirement panels we would need to enable
269 * GTC first.
270 */
271 dev_priv->psr.sink_psr2_support =
272 intel_dp_get_y_coord_required(intel_dp);
273 DRM_DEBUG_KMS("PSR2 %s on sink", dev_priv->psr.sink_psr2_support
274 ? "supported" : "not supported");
141 275
142 dev_priv->psr.sink_support = true; 276 if (dev_priv->psr.sink_psr2_support) {
143 if (drm_dp_dpcd_readb(&intel_dp->aux,
144 DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP,
145 &frame_sync_cap) != 1)
146 frame_sync_cap = 0;
147 dev_priv->psr.aux_frame_sync = frame_sync_cap & DP_AUX_FRAME_SYNC_CAP;
148 /* PSR2 needs frame sync as well */
149 dev_priv->psr.psr2_support = dev_priv->psr.aux_frame_sync;
150 DRM_DEBUG_KMS("PSR2 %s on sink",
151 dev_priv->psr.psr2_support ? "supported" : "not supported");
152
153 if (dev_priv->psr.psr2_support) {
154 dev_priv->psr.y_cord_support =
155 intel_dp_get_y_cord_status(intel_dp);
156 dev_priv->psr.colorimetry_support = 277 dev_priv->psr.colorimetry_support =
157 intel_dp_get_colorimetry_status(intel_dp); 278 intel_dp_get_colorimetry_status(intel_dp);
158 dev_priv->psr.alpm = 279 dev_priv->psr.alpm =
159 intel_dp_get_alpm_status(intel_dp); 280 intel_dp_get_alpm_status(intel_dp);
281 dev_priv->psr.sink_sync_latency =
282 intel_dp_get_sink_sync_latency(intel_dp);
160 } 283 }
161 } 284 }
162} 285}
@@ -193,21 +316,17 @@ static void hsw_psr_setup_vsc(struct intel_dp *intel_dp,
193 struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); 316 struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
194 struct edp_vsc_psr psr_vsc; 317 struct edp_vsc_psr psr_vsc;
195 318
196 if (dev_priv->psr.psr2_support) { 319 if (dev_priv->psr.psr2_enabled) {
197 /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */ 320 /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */
198 memset(&psr_vsc, 0, sizeof(psr_vsc)); 321 memset(&psr_vsc, 0, sizeof(psr_vsc));
199 psr_vsc.sdp_header.HB0 = 0; 322 psr_vsc.sdp_header.HB0 = 0;
200 psr_vsc.sdp_header.HB1 = 0x7; 323 psr_vsc.sdp_header.HB1 = 0x7;
201 if (dev_priv->psr.colorimetry_support && 324 if (dev_priv->psr.colorimetry_support) {
202 dev_priv->psr.y_cord_support) {
203 psr_vsc.sdp_header.HB2 = 0x5; 325 psr_vsc.sdp_header.HB2 = 0x5;
204 psr_vsc.sdp_header.HB3 = 0x13; 326 psr_vsc.sdp_header.HB3 = 0x13;
205 } else if (dev_priv->psr.y_cord_support) { 327 } else {
206 psr_vsc.sdp_header.HB2 = 0x4; 328 psr_vsc.sdp_header.HB2 = 0x4;
207 psr_vsc.sdp_header.HB3 = 0xe; 329 psr_vsc.sdp_header.HB3 = 0xe;
208 } else {
209 psr_vsc.sdp_header.HB2 = 0x3;
210 psr_vsc.sdp_header.HB3 = 0xc;
211 } 330 }
212 } else { 331 } else {
213 /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ 332 /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */
@@ -228,31 +347,12 @@ static void vlv_psr_enable_sink(struct intel_dp *intel_dp)
228 DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE); 347 DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
229} 348}
230 349
231static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv, 350static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
232 enum port port)
233{
234 if (INTEL_GEN(dev_priv) >= 9)
235 return DP_AUX_CH_CTL(port);
236 else
237 return EDP_PSR_AUX_CTL;
238}
239
240static i915_reg_t psr_aux_data_reg(struct drm_i915_private *dev_priv,
241 enum port port, int index)
242{
243 if (INTEL_GEN(dev_priv) >= 9)
244 return DP_AUX_CH_DATA(port, index);
245 else
246 return EDP_PSR_AUX_DATA(index);
247}
248
249static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
250{ 351{
251 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 352 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
252 struct drm_device *dev = dig_port->base.base.dev; 353 struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
253 struct drm_i915_private *dev_priv = to_i915(dev); 354 u32 aux_clock_divider, aux_ctl;
254 uint32_t aux_clock_divider; 355 int i;
255 i915_reg_t aux_ctl_reg;
256 static const uint8_t aux_msg[] = { 356 static const uint8_t aux_msg[] = {
257 [0] = DP_AUX_NATIVE_WRITE << 4, 357 [0] = DP_AUX_NATIVE_WRITE << 4,
258 [1] = DP_SET_POWER >> 8, 358 [1] = DP_SET_POWER >> 8,
@@ -260,41 +360,47 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
260 [3] = 1 - 1, 360 [3] = 1 - 1,
261 [4] = DP_SET_POWER_D0, 361 [4] = DP_SET_POWER_D0,
262 }; 362 };
263 enum port port = dig_port->base.port; 363 u32 psr_aux_mask = EDP_PSR_AUX_CTL_TIME_OUT_MASK |
264 u32 aux_ctl; 364 EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK |
265 int i; 365 EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK |
366 EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK;
266 367
267 BUILD_BUG_ON(sizeof(aux_msg) > 20); 368 BUILD_BUG_ON(sizeof(aux_msg) > 20);
369 for (i = 0; i < sizeof(aux_msg); i += 4)
370 I915_WRITE(EDP_PSR_AUX_DATA(i >> 2),
371 intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i));
268 372
269 aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0); 373 aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
270 374
271 /* Enable AUX frame sync at sink */ 375 /* Start with bits set for DDI_AUX_CTL register */
272 if (dev_priv->psr.aux_frame_sync) 376 aux_ctl = intel_dp->get_aux_send_ctl(intel_dp, 0, sizeof(aux_msg),
273 drm_dp_dpcd_writeb(&intel_dp->aux, 377 aux_clock_divider);
274 DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF, 378
275 DP_AUX_FRAME_SYNC_ENABLE); 379 /* Select only valid bits for SRD_AUX_CTL */
380 aux_ctl &= psr_aux_mask;
381 I915_WRITE(EDP_PSR_AUX_CTL, aux_ctl);
382}
383
384static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
385{
386 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
387 struct drm_device *dev = dig_port->base.base.dev;
388 struct drm_i915_private *dev_priv = to_i915(dev);
389 u8 dpcd_val = DP_PSR_ENABLE;
390
276 /* Enable ALPM at sink for psr2 */ 391 /* Enable ALPM at sink for psr2 */
277 if (dev_priv->psr.psr2_support && dev_priv->psr.alpm) 392 if (dev_priv->psr.psr2_enabled && dev_priv->psr.alpm)
278 drm_dp_dpcd_writeb(&intel_dp->aux, 393 drm_dp_dpcd_writeb(&intel_dp->aux,
279 DP_RECEIVER_ALPM_CONFIG, 394 DP_RECEIVER_ALPM_CONFIG,
280 DP_ALPM_ENABLE); 395 DP_ALPM_ENABLE);
281 if (dev_priv->psr.link_standby)
282 drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
283 DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
284 else
285 drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
286 DP_PSR_ENABLE);
287
288 aux_ctl_reg = psr_aux_ctl_reg(dev_priv, port);
289 396
290 /* Setup AUX registers */ 397 if (dev_priv->psr.psr2_enabled)
291 for (i = 0; i < sizeof(aux_msg); i += 4) 398 dpcd_val |= DP_PSR_ENABLE_PSR2;
292 I915_WRITE(psr_aux_data_reg(dev_priv, port, i >> 2), 399 if (dev_priv->psr.link_standby)
293 intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); 400 dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
401 drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, dpcd_val);
294 402
295 aux_ctl = intel_dp->get_aux_send_ctl(intel_dp, 0, sizeof(aux_msg), 403 drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
296 aux_clock_divider);
297 I915_WRITE(aux_ctl_reg, aux_ctl);
298} 404}
299 405
300static void vlv_psr_enable_source(struct intel_dp *intel_dp, 406static void vlv_psr_enable_source(struct intel_dp *intel_dp,
@@ -396,25 +502,16 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
396 * with the 5 or 6 idle patterns. 502 * with the 5 or 6 idle patterns.
397 */ 503 */
398 uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames); 504 uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
399 uint32_t val; 505 u32 val = idle_frames << EDP_PSR2_IDLE_FRAME_SHIFT;
400 uint8_t sink_latency;
401
402 val = idle_frames << EDP_PSR_IDLE_FRAME_SHIFT;
403 506
404 /* FIXME: selective update is probably totally broken because it doesn't 507 /* FIXME: selective update is probably totally broken because it doesn't
405 * mesh at all with our frontbuffer tracking. And the hw alone isn't 508 * mesh at all with our frontbuffer tracking. And the hw alone isn't
406 * good enough. */ 509 * good enough. */
407 val |= EDP_PSR2_ENABLE | 510 val |= EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
408 EDP_SU_TRACK_ENABLE; 511 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
512 val |= EDP_Y_COORDINATE_ENABLE;
409 513
410 if (drm_dp_dpcd_readb(&intel_dp->aux, 514 val |= EDP_PSR2_FRAME_BEFORE_SU(dev_priv->psr.sink_sync_latency + 1);
411 DP_SYNCHRONIZATION_LATENCY_IN_SINK,
412 &sink_latency) == 1) {
413 sink_latency &= DP_MAX_RESYNC_FRAME_COUNT_MASK;
414 } else {
415 sink_latency = 0;
416 }
417 val |= EDP_PSR2_FRAME_BEFORE_SU(sink_latency + 1);
418 515
419 if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5) 516 if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
420 val |= EDP_PSR2_TP2_TIME_2500; 517 val |= EDP_PSR2_TP2_TIME_2500;
@@ -440,7 +537,7 @@ static void hsw_psr_activate(struct intel_dp *intel_dp)
440 */ 537 */
441 538
442 /* psr1 and psr2 are mutually exclusive.*/ 539 /* psr1 and psr2 are mutually exclusive.*/
443 if (dev_priv->psr.psr2_support) 540 if (dev_priv->psr.psr2_enabled)
444 hsw_activate_psr2(intel_dp); 541 hsw_activate_psr2(intel_dp);
445 else 542 else
446 hsw_activate_psr1(intel_dp); 543 hsw_activate_psr1(intel_dp);
@@ -460,7 +557,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
460 * dynamically during PSR enable, and extracted from sink 557 * dynamically during PSR enable, and extracted from sink
461 * caps during eDP detection. 558 * caps during eDP detection.
462 */ 559 */
463 if (!dev_priv->psr.psr2_support) 560 if (!dev_priv->psr.sink_psr2_support)
464 return false; 561 return false;
465 562
466 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { 563 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
@@ -478,15 +575,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
478 return false; 575 return false;
479 } 576 }
480 577
481 /*
482 * FIXME:enable psr2 only for y-cordinate psr2 panels
483 * After gtc implementation , remove this restriction.
484 */
485 if (!dev_priv->psr.y_cord_support) {
486 DRM_DEBUG_KMS("PSR2 not enabled, panel does not support Y coordinate\n");
487 return false;
488 }
489
490 return true; 578 return true;
491} 579}
492 580
@@ -568,7 +656,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
568 struct drm_device *dev = intel_dig_port->base.base.dev; 656 struct drm_device *dev = intel_dig_port->base.base.dev;
569 struct drm_i915_private *dev_priv = to_i915(dev); 657 struct drm_i915_private *dev_priv = to_i915(dev);
570 658
571 if (dev_priv->psr.psr2_support) 659 if (dev_priv->psr.psr2_enabled)
572 WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE); 660 WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE);
573 else 661 else
574 WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE); 662 WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
@@ -586,14 +674,24 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp,
586 struct drm_device *dev = dig_port->base.base.dev; 674 struct drm_device *dev = dig_port->base.base.dev;
587 struct drm_i915_private *dev_priv = to_i915(dev); 675 struct drm_i915_private *dev_priv = to_i915(dev);
588 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 676 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
589 u32 chicken;
590 677
591 psr_aux_io_power_get(intel_dp); 678 psr_aux_io_power_get(intel_dp);
592 679
593 if (dev_priv->psr.psr2_support) { 680 /* Only HSW and BDW have PSR AUX registers that need to be setup. SKL+
594 chicken = PSR2_VSC_ENABLE_PROG_HEADER; 681 * use hardcoded values PSR AUX transactions
595 if (dev_priv->psr.y_cord_support) 682 */
596 chicken |= PSR2_ADD_VERTICAL_LINE_COUNT; 683 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
684 hsw_psr_setup_aux(intel_dp);
685
686 if (dev_priv->psr.psr2_enabled) {
687 u32 chicken = I915_READ(CHICKEN_TRANS(cpu_transcoder));
688
689 if (INTEL_GEN(dev_priv) == 9 && !IS_GEMINILAKE(dev_priv))
690 chicken |= (PSR2_VSC_ENABLE_PROG_HEADER
691 | PSR2_ADD_VERTICAL_LINE_COUNT);
692
693 else
694 chicken &= ~VSC_DATA_SEL_SOFTWARE_CONTROL;
597 I915_WRITE(CHICKEN_TRANS(cpu_transcoder), chicken); 695 I915_WRITE(CHICKEN_TRANS(cpu_transcoder), chicken);
598 696
599 I915_WRITE(EDP_PSR_DEBUG, 697 I915_WRITE(EDP_PSR_DEBUG,
@@ -613,7 +711,8 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp,
613 I915_WRITE(EDP_PSR_DEBUG, 711 I915_WRITE(EDP_PSR_DEBUG,
614 EDP_PSR_DEBUG_MASK_MEMUP | 712 EDP_PSR_DEBUG_MASK_MEMUP |
615 EDP_PSR_DEBUG_MASK_HPD | 713 EDP_PSR_DEBUG_MASK_HPD |
616 EDP_PSR_DEBUG_MASK_LPSP); 714 EDP_PSR_DEBUG_MASK_LPSP |
715 EDP_PSR_DEBUG_MASK_DISP_REG_WRITE);
617 } 716 }
618} 717}
619 718
@@ -644,7 +743,7 @@ void intel_psr_enable(struct intel_dp *intel_dp,
644 goto unlock; 743 goto unlock;
645 } 744 }
646 745
647 dev_priv->psr.psr2_support = crtc_state->has_psr2; 746 dev_priv->psr.psr2_enabled = crtc_state->has_psr2;
648 dev_priv->psr.busy_frontbuffer_bits = 0; 747 dev_priv->psr.busy_frontbuffer_bits = 0;
649 748
650 dev_priv->psr.setup_vsc(intel_dp, crtc_state); 749 dev_priv->psr.setup_vsc(intel_dp, crtc_state);
@@ -714,12 +813,7 @@ static void hsw_psr_disable(struct intel_dp *intel_dp,
714 i915_reg_t psr_status; 813 i915_reg_t psr_status;
715 u32 psr_status_mask; 814 u32 psr_status_mask;
716 815
717 if (dev_priv->psr.aux_frame_sync) 816 if (dev_priv->psr.psr2_enabled) {
718 drm_dp_dpcd_writeb(&intel_dp->aux,
719 DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF,
720 0);
721
722 if (dev_priv->psr.psr2_support) {
723 psr_status = EDP_PSR2_STATUS; 817 psr_status = EDP_PSR2_STATUS;
724 psr_status_mask = EDP_PSR2_STATUS_STATE_MASK; 818 psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
725 819
@@ -743,7 +837,7 @@ static void hsw_psr_disable(struct intel_dp *intel_dp,
743 837
744 dev_priv->psr.active = false; 838 dev_priv->psr.active = false;
745 } else { 839 } else {
746 if (dev_priv->psr.psr2_support) 840 if (dev_priv->psr.psr2_enabled)
747 WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE); 841 WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE);
748 else 842 else
749 WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE); 843 WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
@@ -789,53 +883,59 @@ void intel_psr_disable(struct intel_dp *intel_dp,
789 cancel_delayed_work_sync(&dev_priv->psr.work); 883 cancel_delayed_work_sync(&dev_priv->psr.work);
790} 884}
791 885
792static void intel_psr_work(struct work_struct *work) 886static bool psr_wait_for_idle(struct drm_i915_private *dev_priv)
793{ 887{
794 struct drm_i915_private *dev_priv = 888 struct intel_dp *intel_dp;
795 container_of(work, typeof(*dev_priv), psr.work.work); 889 i915_reg_t reg;
796 struct intel_dp *intel_dp = dev_priv->psr.enabled; 890 u32 mask;
797 struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc; 891 int err;
798 enum pipe pipe = to_intel_crtc(crtc)->pipe; 892
893 intel_dp = dev_priv->psr.enabled;
894 if (!intel_dp)
895 return false;
799 896
800 /* We have to make sure PSR is ready for re-enable
801 * otherwise it keeps disabled until next full enable/disable cycle.
802 * PSR might take some time to get fully disabled
803 * and be ready for re-enable.
804 */
805 if (HAS_DDI(dev_priv)) { 897 if (HAS_DDI(dev_priv)) {
806 if (dev_priv->psr.psr2_support) { 898 if (dev_priv->psr.psr2_enabled) {
807 if (intel_wait_for_register(dev_priv, 899 reg = EDP_PSR2_STATUS;
808 EDP_PSR2_STATUS, 900 mask = EDP_PSR2_STATUS_STATE_MASK;
809 EDP_PSR2_STATUS_STATE_MASK,
810 0,
811 50)) {
812 DRM_ERROR("Timed out waiting for PSR2 Idle for re-enable\n");
813 return;
814 }
815 } else { 901 } else {
816 if (intel_wait_for_register(dev_priv, 902 reg = EDP_PSR_STATUS;
817 EDP_PSR_STATUS, 903 mask = EDP_PSR_STATUS_STATE_MASK;
818 EDP_PSR_STATUS_STATE_MASK,
819 0,
820 50)) {
821 DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
822 return;
823 }
824 } 904 }
825 } else { 905 } else {
826 if (intel_wait_for_register(dev_priv, 906 struct drm_crtc *crtc =
827 VLV_PSRSTAT(pipe), 907 dp_to_dig_port(intel_dp)->base.base.crtc;
828 VLV_EDP_PSR_IN_TRANS, 908 enum pipe pipe = to_intel_crtc(crtc)->pipe;
829 0, 909
830 1)) { 910 reg = VLV_PSRSTAT(pipe);
831 DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n"); 911 mask = VLV_EDP_PSR_IN_TRANS;
832 return;
833 }
834 } 912 }
913
914 mutex_unlock(&dev_priv->psr.lock);
915
916 err = intel_wait_for_register(dev_priv, reg, mask, 0, 50);
917 if (err)
918 DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
919
920 /* After the unlocked wait, verify that PSR is still wanted! */
835 mutex_lock(&dev_priv->psr.lock); 921 mutex_lock(&dev_priv->psr.lock);
836 intel_dp = dev_priv->psr.enabled; 922 return err == 0 && dev_priv->psr.enabled;
923}
837 924
838 if (!intel_dp) 925static void intel_psr_work(struct work_struct *work)
926{
927 struct drm_i915_private *dev_priv =
928 container_of(work, typeof(*dev_priv), psr.work.work);
929
930 mutex_lock(&dev_priv->psr.lock);
931
932 /*
933 * We have to make sure PSR is ready for re-enable
934 * otherwise it keeps disabled until next full enable/disable cycle.
935 * PSR might take some time to get fully disabled
936 * and be ready for re-enable.
937 */
938 if (!psr_wait_for_idle(dev_priv))
839 goto unlock; 939 goto unlock;
840 940
841 /* 941 /*
@@ -846,7 +946,7 @@ static void intel_psr_work(struct work_struct *work)
846 if (dev_priv->psr.busy_frontbuffer_bits) 946 if (dev_priv->psr.busy_frontbuffer_bits)
847 goto unlock; 947 goto unlock;
848 948
849 intel_psr_activate(intel_dp); 949 intel_psr_activate(dev_priv->psr.enabled);
850unlock: 950unlock:
851 mutex_unlock(&dev_priv->psr.lock); 951 mutex_unlock(&dev_priv->psr.lock);
852} 952}
@@ -862,11 +962,7 @@ static void intel_psr_exit(struct drm_i915_private *dev_priv)
862 return; 962 return;
863 963
864 if (HAS_DDI(dev_priv)) { 964 if (HAS_DDI(dev_priv)) {
865 if (dev_priv->psr.aux_frame_sync) 965 if (dev_priv->psr.psr2_enabled) {
866 drm_dp_dpcd_writeb(&intel_dp->aux,
867 DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF,
868 0);
869 if (dev_priv->psr.psr2_support) {
870 val = I915_READ(EDP_PSR2_CTL); 966 val = I915_READ(EDP_PSR2_CTL);
871 WARN_ON(!(val & EDP_PSR2_ENABLE)); 967 WARN_ON(!(val & EDP_PSR2_ENABLE));
872 I915_WRITE(EDP_PSR2_CTL, val & ~EDP_PSR2_ENABLE); 968 I915_WRITE(EDP_PSR2_CTL, val & ~EDP_PSR2_ENABLE);
@@ -957,6 +1053,7 @@ void intel_psr_single_frame_update(struct drm_i915_private *dev_priv,
957 * intel_psr_invalidate - Invalidade PSR 1053 * intel_psr_invalidate - Invalidade PSR
958 * @dev_priv: i915 device 1054 * @dev_priv: i915 device
959 * @frontbuffer_bits: frontbuffer plane tracking bits 1055 * @frontbuffer_bits: frontbuffer plane tracking bits
1056 * @origin: which operation caused the invalidate
960 * 1057 *
961 * Since the hardware frontbuffer tracking has gaps we need to integrate 1058 * Since the hardware frontbuffer tracking has gaps we need to integrate
962 * with the software frontbuffer tracking. This function gets called every 1059 * with the software frontbuffer tracking. This function gets called every
@@ -966,7 +1063,7 @@ void intel_psr_single_frame_update(struct drm_i915_private *dev_priv,
966 * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits." 1063 * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits."
967 */ 1064 */
968void intel_psr_invalidate(struct drm_i915_private *dev_priv, 1065void intel_psr_invalidate(struct drm_i915_private *dev_priv,
969 unsigned frontbuffer_bits) 1066 unsigned frontbuffer_bits, enum fb_op_origin origin)
970{ 1067{
971 struct drm_crtc *crtc; 1068 struct drm_crtc *crtc;
972 enum pipe pipe; 1069 enum pipe pipe;
@@ -974,6 +1071,9 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv,
974 if (!CAN_PSR(dev_priv)) 1071 if (!CAN_PSR(dev_priv))
975 return; 1072 return;
976 1073
1074 if (dev_priv->psr.has_hw_tracking && origin == ORIGIN_FLIP)
1075 return;
1076
977 mutex_lock(&dev_priv->psr.lock); 1077 mutex_lock(&dev_priv->psr.lock);
978 if (!dev_priv->psr.enabled) { 1078 if (!dev_priv->psr.enabled) {
979 mutex_unlock(&dev_priv->psr.lock); 1079 mutex_unlock(&dev_priv->psr.lock);
@@ -1014,6 +1114,9 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
1014 if (!CAN_PSR(dev_priv)) 1114 if (!CAN_PSR(dev_priv))
1015 return; 1115 return;
1016 1116
1117 if (dev_priv->psr.has_hw_tracking && origin == ORIGIN_FLIP)
1118 return;
1119
1017 mutex_lock(&dev_priv->psr.lock); 1120 mutex_lock(&dev_priv->psr.lock);
1018 if (!dev_priv->psr.enabled) { 1121 if (!dev_priv->psr.enabled) {
1019 mutex_unlock(&dev_priv->psr.lock); 1122 mutex_unlock(&dev_priv->psr.lock);
@@ -1027,8 +1130,23 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
1027 dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits; 1130 dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
1028 1131
1029 /* By definition flush = invalidate + flush */ 1132 /* By definition flush = invalidate + flush */
1030 if (frontbuffer_bits) 1133 if (frontbuffer_bits) {
1031 intel_psr_exit(dev_priv); 1134 if (dev_priv->psr.psr2_enabled ||
1135 IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1136 intel_psr_exit(dev_priv);
1137 } else {
1138 /*
1139 * Display WA #0884: all
1140 * This documented WA for bxt can be safely applied
1141 * broadly so we can force HW tracking to exit PSR
1142 * instead of disabling and re-enabling.
1143 * Workaround tells us to write 0 to CUR_SURFLIVE_A,
1144 * but it makes more sense write to the current active
1145 * pipe.
1146 */
1147 I915_WRITE(CURSURFLIVE(pipe), 0);
1148 }
1149 }
1032 1150
1033 if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) 1151 if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
1034 if (!work_busy(&dev_priv->psr.work.work)) 1152 if (!work_busy(&dev_priv->psr.work.work))
@@ -1055,9 +1173,12 @@ void intel_psr_init(struct drm_i915_private *dev_priv)
1055 if (!dev_priv->psr.sink_support) 1173 if (!dev_priv->psr.sink_support)
1056 return; 1174 return;
1057 1175
1058 /* Per platform default: all disabled. */ 1176 if (i915_modparams.enable_psr == -1) {
1059 if (i915_modparams.enable_psr == -1) 1177 i915_modparams.enable_psr = dev_priv->vbt.psr.enable;
1178
1179 /* Per platform default: all disabled. */
1060 i915_modparams.enable_psr = 0; 1180 i915_modparams.enable_psr = 0;
1181 }
1061 1182
1062 /* Set link_standby x link_off defaults */ 1183 /* Set link_standby x link_off defaults */
1063 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 1184 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
@@ -1090,6 +1211,7 @@ void intel_psr_init(struct drm_i915_private *dev_priv)
1090 dev_priv->psr.activate = vlv_psr_activate; 1211 dev_priv->psr.activate = vlv_psr_activate;
1091 dev_priv->psr.setup_vsc = vlv_psr_setup_vsc; 1212 dev_priv->psr.setup_vsc = vlv_psr_setup_vsc;
1092 } else { 1213 } else {
1214 dev_priv->psr.has_hw_tracking = true;
1093 dev_priv->psr.enable_source = hsw_psr_enable_source; 1215 dev_priv->psr.enable_source = hsw_psr_enable_source;
1094 dev_priv->psr.disable_source = hsw_psr_disable; 1216 dev_priv->psr.disable_source = hsw_psr_disable;
1095 dev_priv->psr.enable_sink = hsw_psr_enable_sink; 1217 dev_priv->psr.enable_sink = hsw_psr_enable_sink;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 1d599524a759..8f19349a6055 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -36,6 +36,7 @@
36#include "i915_gem_render_state.h" 36#include "i915_gem_render_state.h"
37#include "i915_trace.h" 37#include "i915_trace.h"
38#include "intel_drv.h" 38#include "intel_drv.h"
39#include "intel_workarounds.h"
39 40
40/* Rough estimate of the typical request size, performing a flush, 41/* Rough estimate of the typical request size, performing a flush,
41 * set-context and then emitting the batch. 42 * set-context and then emitting the batch.
@@ -557,7 +558,8 @@ static void reset_ring_common(struct intel_engine_cs *engine,
557 */ 558 */
558 if (request) { 559 if (request) {
559 struct drm_i915_private *dev_priv = request->i915; 560 struct drm_i915_private *dev_priv = request->i915;
560 struct intel_context *ce = &request->ctx->engine[engine->id]; 561 struct intel_context *ce = to_intel_context(request->ctx,
562 engine);
561 struct i915_hw_ppgtt *ppgtt; 563 struct i915_hw_ppgtt *ppgtt;
562 564
563 if (ce->state) { 565 if (ce->state) {
@@ -599,7 +601,7 @@ static int intel_rcs_ctx_init(struct i915_request *rq)
599{ 601{
600 int ret; 602 int ret;
601 603
602 ret = intel_ring_workarounds_emit(rq); 604 ret = intel_ctx_workarounds_emit(rq);
603 if (ret != 0) 605 if (ret != 0)
604 return ret; 606 return ret;
605 607
@@ -617,6 +619,8 @@ static int init_render_ring(struct intel_engine_cs *engine)
617 if (ret) 619 if (ret)
618 return ret; 620 return ret;
619 621
622 intel_whitelist_workarounds_apply(engine);
623
620 /* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */ 624 /* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */
621 if (IS_GEN(dev_priv, 4, 6)) 625 if (IS_GEN(dev_priv, 4, 6))
622 I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH)); 626 I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH));
@@ -658,7 +662,7 @@ static int init_render_ring(struct intel_engine_cs *engine)
658 if (INTEL_GEN(dev_priv) >= 6) 662 if (INTEL_GEN(dev_priv) >= 6)
659 I915_WRITE_IMR(engine, ~engine->irq_keep_mask); 663 I915_WRITE_IMR(engine, ~engine->irq_keep_mask);
660 664
661 return init_workarounds_ring(engine); 665 return 0;
662} 666}
663 667
664static u32 *gen6_signal(struct i915_request *rq, u32 *cs) 668static u32 *gen6_signal(struct i915_request *rq, u32 *cs)
@@ -693,17 +697,17 @@ static void cancel_requests(struct intel_engine_cs *engine)
693 struct i915_request *request; 697 struct i915_request *request;
694 unsigned long flags; 698 unsigned long flags;
695 699
696 spin_lock_irqsave(&engine->timeline->lock, flags); 700 spin_lock_irqsave(&engine->timeline.lock, flags);
697 701
698 /* Mark all submitted requests as skipped. */ 702 /* Mark all submitted requests as skipped. */
699 list_for_each_entry(request, &engine->timeline->requests, link) { 703 list_for_each_entry(request, &engine->timeline.requests, link) {
700 GEM_BUG_ON(!request->global_seqno); 704 GEM_BUG_ON(!request->global_seqno);
701 if (!i915_request_completed(request)) 705 if (!i915_request_completed(request))
702 dma_fence_set_error(&request->fence, -EIO); 706 dma_fence_set_error(&request->fence, -EIO);
703 } 707 }
704 /* Remaining _unready_ requests will be nop'ed when submitted */ 708 /* Remaining _unready_ requests will be nop'ed when submitted */
705 709
706 spin_unlock_irqrestore(&engine->timeline->lock, flags); 710 spin_unlock_irqrestore(&engine->timeline.lock, flags);
707} 711}
708 712
709static void i9xx_submit_request(struct i915_request *request) 713static void i9xx_submit_request(struct i915_request *request)
@@ -1062,7 +1066,6 @@ err:
1062 1066
1063void intel_ring_reset(struct intel_ring *ring, u32 tail) 1067void intel_ring_reset(struct intel_ring *ring, u32 tail)
1064{ 1068{
1065 GEM_BUG_ON(!list_empty(&ring->request_list));
1066 ring->tail = tail; 1069 ring->tail = tail;
1067 ring->head = tail; 1070 ring->head = tail;
1068 ring->emit = tail; 1071 ring->emit = tail;
@@ -1114,19 +1117,24 @@ err:
1114} 1117}
1115 1118
1116struct intel_ring * 1119struct intel_ring *
1117intel_engine_create_ring(struct intel_engine_cs *engine, int size) 1120intel_engine_create_ring(struct intel_engine_cs *engine,
1121 struct i915_timeline *timeline,
1122 int size)
1118{ 1123{
1119 struct intel_ring *ring; 1124 struct intel_ring *ring;
1120 struct i915_vma *vma; 1125 struct i915_vma *vma;
1121 1126
1122 GEM_BUG_ON(!is_power_of_2(size)); 1127 GEM_BUG_ON(!is_power_of_2(size));
1123 GEM_BUG_ON(RING_CTL_SIZE(size) & ~RING_NR_PAGES); 1128 GEM_BUG_ON(RING_CTL_SIZE(size) & ~RING_NR_PAGES);
1129 GEM_BUG_ON(timeline == &engine->timeline);
1130 lockdep_assert_held(&engine->i915->drm.struct_mutex);
1124 1131
1125 ring = kzalloc(sizeof(*ring), GFP_KERNEL); 1132 ring = kzalloc(sizeof(*ring), GFP_KERNEL);
1126 if (!ring) 1133 if (!ring)
1127 return ERR_PTR(-ENOMEM); 1134 return ERR_PTR(-ENOMEM);
1128 1135
1129 INIT_LIST_HEAD(&ring->request_list); 1136 INIT_LIST_HEAD(&ring->request_list);
1137 ring->timeline = i915_timeline_get(timeline);
1130 1138
1131 ring->size = size; 1139 ring->size = size;
1132 /* Workaround an erratum on the i830 which causes a hang if 1140 /* Workaround an erratum on the i830 which causes a hang if
@@ -1157,12 +1165,13 @@ intel_ring_free(struct intel_ring *ring)
1157 i915_vma_close(ring->vma); 1165 i915_vma_close(ring->vma);
1158 __i915_gem_object_release_unless_active(obj); 1166 __i915_gem_object_release_unless_active(obj);
1159 1167
1168 i915_timeline_put(ring->timeline);
1160 kfree(ring); 1169 kfree(ring);
1161} 1170}
1162 1171
1163static int context_pin(struct i915_gem_context *ctx) 1172static int context_pin(struct intel_context *ce)
1164{ 1173{
1165 struct i915_vma *vma = ctx->engine[RCS].state; 1174 struct i915_vma *vma = ce->state;
1166 int ret; 1175 int ret;
1167 1176
1168 /* 1177 /*
@@ -1253,7 +1262,7 @@ static struct intel_ring *
1253intel_ring_context_pin(struct intel_engine_cs *engine, 1262intel_ring_context_pin(struct intel_engine_cs *engine,
1254 struct i915_gem_context *ctx) 1263 struct i915_gem_context *ctx)
1255{ 1264{
1256 struct intel_context *ce = &ctx->engine[engine->id]; 1265 struct intel_context *ce = to_intel_context(ctx, engine);
1257 int ret; 1266 int ret;
1258 1267
1259 lockdep_assert_held(&ctx->i915->drm.struct_mutex); 1268 lockdep_assert_held(&ctx->i915->drm.struct_mutex);
@@ -1275,7 +1284,7 @@ intel_ring_context_pin(struct intel_engine_cs *engine,
1275 } 1284 }
1276 1285
1277 if (ce->state) { 1286 if (ce->state) {
1278 ret = context_pin(ctx); 1287 ret = context_pin(ce);
1279 if (ret) 1288 if (ret)
1280 goto err; 1289 goto err;
1281 1290
@@ -1296,7 +1305,7 @@ err:
1296static void intel_ring_context_unpin(struct intel_engine_cs *engine, 1305static void intel_ring_context_unpin(struct intel_engine_cs *engine,
1297 struct i915_gem_context *ctx) 1306 struct i915_gem_context *ctx)
1298{ 1307{
1299 struct intel_context *ce = &ctx->engine[engine->id]; 1308 struct intel_context *ce = to_intel_context(ctx, engine);
1300 1309
1301 lockdep_assert_held(&ctx->i915->drm.struct_mutex); 1310 lockdep_assert_held(&ctx->i915->drm.struct_mutex);
1302 GEM_BUG_ON(ce->pin_count == 0); 1311 GEM_BUG_ON(ce->pin_count == 0);
@@ -1315,6 +1324,7 @@ static void intel_ring_context_unpin(struct intel_engine_cs *engine,
1315static int intel_init_ring_buffer(struct intel_engine_cs *engine) 1324static int intel_init_ring_buffer(struct intel_engine_cs *engine)
1316{ 1325{
1317 struct intel_ring *ring; 1326 struct intel_ring *ring;
1327 struct i915_timeline *timeline;
1318 int err; 1328 int err;
1319 1329
1320 intel_engine_setup_common(engine); 1330 intel_engine_setup_common(engine);
@@ -1323,7 +1333,14 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
1323 if (err) 1333 if (err)
1324 goto err; 1334 goto err;
1325 1335
1326 ring = intel_engine_create_ring(engine, 32 * PAGE_SIZE); 1336 timeline = i915_timeline_create(engine->i915, engine->name);
1337 if (IS_ERR(timeline)) {
1338 err = PTR_ERR(timeline);
1339 goto err;
1340 }
1341
1342 ring = intel_engine_create_ring(engine, timeline, 32 * PAGE_SIZE);
1343 i915_timeline_put(timeline);
1327 if (IS_ERR(ring)) { 1344 if (IS_ERR(ring)) {
1328 err = PTR_ERR(ring); 1345 err = PTR_ERR(ring);
1329 goto err; 1346 goto err;
@@ -1424,7 +1441,7 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags)
1424 1441
1425 *cs++ = MI_NOOP; 1442 *cs++ = MI_NOOP;
1426 *cs++ = MI_SET_CONTEXT; 1443 *cs++ = MI_SET_CONTEXT;
1427 *cs++ = i915_ggtt_offset(rq->ctx->engine[RCS].state) | flags; 1444 *cs++ = i915_ggtt_offset(to_intel_context(rq->ctx, engine)->state) | flags;
1428 /* 1445 /*
1429 * w/a: MI_SET_CONTEXT must always be followed by MI_NOOP 1446 * w/a: MI_SET_CONTEXT must always be followed by MI_NOOP
1430 * WaMiSetContext_Hang:snb,ivb,vlv 1447 * WaMiSetContext_Hang:snb,ivb,vlv
@@ -1515,7 +1532,7 @@ static int switch_context(struct i915_request *rq)
1515 hw_flags = MI_FORCE_RESTORE; 1532 hw_flags = MI_FORCE_RESTORE;
1516 } 1533 }
1517 1534
1518 if (to_ctx->engine[engine->id].state && 1535 if (to_intel_context(to_ctx, engine)->state &&
1519 (to_ctx != from_ctx || hw_flags & MI_FORCE_RESTORE)) { 1536 (to_ctx != from_ctx || hw_flags & MI_FORCE_RESTORE)) {
1520 GEM_BUG_ON(engine->id != RCS); 1537 GEM_BUG_ON(engine->id != RCS);
1521 1538
@@ -1563,7 +1580,7 @@ static int ring_request_alloc(struct i915_request *request)
1563{ 1580{
1564 int ret; 1581 int ret;
1565 1582
1566 GEM_BUG_ON(!request->ctx->engine[request->engine->id].pin_count); 1583 GEM_BUG_ON(!to_intel_context(request->ctx, request->engine)->pin_count);
1567 1584
1568 /* Flush enough space to reduce the likelihood of waiting after 1585 /* Flush enough space to reduce the likelihood of waiting after
1569 * we start building the request - in which case we will just 1586 * we start building the request - in which case we will just
@@ -1593,6 +1610,7 @@ static noinline int wait_for_space(struct intel_ring *ring, unsigned int bytes)
1593 if (intel_ring_update_space(ring) >= bytes) 1610 if (intel_ring_update_space(ring) >= bytes)
1594 return 0; 1611 return 0;
1595 1612
1613 GEM_BUG_ON(list_empty(&ring->request_list));
1596 list_for_each_entry(target, &ring->request_list, ring_link) { 1614 list_for_each_entry(target, &ring->request_list, ring_link) {
1597 /* Would completion of this request free enough space? */ 1615 /* Would completion of this request free enough space? */
1598 if (bytes <= __intel_ring_space(target->postfix, 1616 if (bytes <= __intel_ring_space(target->postfix,
@@ -1692,17 +1710,18 @@ u32 *intel_ring_begin(struct i915_request *rq, unsigned int num_dwords)
1692 need_wrap &= ~1; 1710 need_wrap &= ~1;
1693 GEM_BUG_ON(need_wrap > ring->space); 1711 GEM_BUG_ON(need_wrap > ring->space);
1694 GEM_BUG_ON(ring->emit + need_wrap > ring->size); 1712 GEM_BUG_ON(ring->emit + need_wrap > ring->size);
1713 GEM_BUG_ON(!IS_ALIGNED(need_wrap, sizeof(u64)));
1695 1714
1696 /* Fill the tail with MI_NOOP */ 1715 /* Fill the tail with MI_NOOP */
1697 memset(ring->vaddr + ring->emit, 0, need_wrap); 1716 memset64(ring->vaddr + ring->emit, 0, need_wrap / sizeof(u64));
1698 ring->emit = 0;
1699 ring->space -= need_wrap; 1717 ring->space -= need_wrap;
1718 ring->emit = 0;
1700 } 1719 }
1701 1720
1702 GEM_BUG_ON(ring->emit > ring->size - bytes); 1721 GEM_BUG_ON(ring->emit > ring->size - bytes);
1703 GEM_BUG_ON(ring->space < bytes); 1722 GEM_BUG_ON(ring->space < bytes);
1704 cs = ring->vaddr + ring->emit; 1723 cs = ring->vaddr + ring->emit;
1705 GEM_DEBUG_EXEC(memset(cs, POISON_INUSE, bytes)); 1724 GEM_DEBUG_EXEC(memset32(cs, POISON_INUSE, bytes / sizeof(*cs)));
1706 ring->emit += bytes; 1725 ring->emit += bytes;
1707 ring->space -= bytes; 1726 ring->space -= bytes;
1708 1727
@@ -1712,22 +1731,24 @@ u32 *intel_ring_begin(struct i915_request *rq, unsigned int num_dwords)
1712/* Align the ring tail to a cacheline boundary */ 1731/* Align the ring tail to a cacheline boundary */
1713int intel_ring_cacheline_align(struct i915_request *rq) 1732int intel_ring_cacheline_align(struct i915_request *rq)
1714{ 1733{
1715 int num_dwords = (rq->ring->emit & (CACHELINE_BYTES - 1)) / sizeof(u32); 1734 int num_dwords;
1716 u32 *cs; 1735 void *cs;
1717 1736
1737 num_dwords = (rq->ring->emit & (CACHELINE_BYTES - 1)) / sizeof(u32);
1718 if (num_dwords == 0) 1738 if (num_dwords == 0)
1719 return 0; 1739 return 0;
1720 1740
1721 num_dwords = CACHELINE_BYTES / sizeof(u32) - num_dwords; 1741 num_dwords = CACHELINE_DWORDS - num_dwords;
1742 GEM_BUG_ON(num_dwords & 1);
1743
1722 cs = intel_ring_begin(rq, num_dwords); 1744 cs = intel_ring_begin(rq, num_dwords);
1723 if (IS_ERR(cs)) 1745 if (IS_ERR(cs))
1724 return PTR_ERR(cs); 1746 return PTR_ERR(cs);
1725 1747
1726 while (num_dwords--) 1748 memset64(cs, (u64)MI_NOOP << 32 | MI_NOOP, num_dwords / 2);
1727 *cs++ = MI_NOOP;
1728
1729 intel_ring_advance(rq, cs); 1749 intel_ring_advance(rq, cs);
1730 1750
1751 GEM_BUG_ON(rq->ring->emit & (CACHELINE_BYTES - 1));
1731 return 0; 1752 return 0;
1732} 1753}
1733 1754
@@ -1943,8 +1964,6 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv,
1943static void intel_ring_init_irq(struct drm_i915_private *dev_priv, 1964static void intel_ring_init_irq(struct drm_i915_private *dev_priv,
1944 struct intel_engine_cs *engine) 1965 struct intel_engine_cs *engine)
1945{ 1966{
1946 engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << engine->irq_shift;
1947
1948 if (INTEL_GEN(dev_priv) >= 6) { 1967 if (INTEL_GEN(dev_priv) >= 6) {
1949 engine->irq_enable = gen6_irq_enable; 1968 engine->irq_enable = gen6_irq_enable;
1950 engine->irq_disable = gen6_irq_disable; 1969 engine->irq_disable = gen6_irq_disable;
@@ -2029,6 +2048,8 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine)
2029 if (HAS_L3_DPF(dev_priv)) 2048 if (HAS_L3_DPF(dev_priv))
2030 engine->irq_keep_mask = GT_RENDER_L3_PARITY_ERROR_INTERRUPT; 2049 engine->irq_keep_mask = GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
2031 2050
2051 engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
2052
2032 if (INTEL_GEN(dev_priv) >= 6) { 2053 if (INTEL_GEN(dev_priv) >= 6) {
2033 engine->init_context = intel_rcs_ctx_init; 2054 engine->init_context = intel_rcs_ctx_init;
2034 engine->emit_flush = gen7_render_ring_flush; 2055 engine->emit_flush = gen7_render_ring_flush;
@@ -2079,7 +2100,6 @@ int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine)
2079 engine->emit_flush = gen6_bsd_ring_flush; 2100 engine->emit_flush = gen6_bsd_ring_flush;
2080 engine->irq_enable_mask = GT_BSD_USER_INTERRUPT; 2101 engine->irq_enable_mask = GT_BSD_USER_INTERRUPT;
2081 } else { 2102 } else {
2082 engine->mmio_base = BSD_RING_BASE;
2083 engine->emit_flush = bsd_ring_flush; 2103 engine->emit_flush = bsd_ring_flush;
2084 if (IS_GEN5(dev_priv)) 2104 if (IS_GEN5(dev_priv))
2085 engine->irq_enable_mask = ILK_BSD_USER_INTERRUPT; 2105 engine->irq_enable_mask = ILK_BSD_USER_INTERRUPT;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 0320c2c4cfba..010750e8ee44 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -3,15 +3,19 @@
3#define _INTEL_RINGBUFFER_H_ 3#define _INTEL_RINGBUFFER_H_
4 4
5#include <linux/hashtable.h> 5#include <linux/hashtable.h>
6#include <linux/seqlock.h>
6 7
7#include "i915_gem_batch_pool.h" 8#include "i915_gem_batch_pool.h"
8#include "i915_gem_timeline.h"
9 9
10#include "i915_reg.h"
10#include "i915_pmu.h" 11#include "i915_pmu.h"
11#include "i915_request.h" 12#include "i915_request.h"
12#include "i915_selftest.h" 13#include "i915_selftest.h"
14#include "i915_timeline.h"
15#include "intel_gpu_commands.h"
13 16
14struct drm_printer; 17struct drm_printer;
18struct i915_sched_attr;
15 19
16#define I915_CMD_HASH_ORDER 9 20#define I915_CMD_HASH_ORDER 9
17 21
@@ -84,7 +88,7 @@ hangcheck_action_to_str(const enum intel_engine_hangcheck_action a)
84} 88}
85 89
86#define I915_MAX_SLICES 3 90#define I915_MAX_SLICES 3
87#define I915_MAX_SUBSLICES 3 91#define I915_MAX_SUBSLICES 8
88 92
89#define instdone_slice_mask(dev_priv__) \ 93#define instdone_slice_mask(dev_priv__) \
90 (INTEL_GEN(dev_priv__) == 7 ? \ 94 (INTEL_GEN(dev_priv__) == 7 ? \
@@ -125,7 +129,9 @@ struct intel_ring {
125 struct i915_vma *vma; 129 struct i915_vma *vma;
126 void *vaddr; 130 void *vaddr;
127 131
132 struct i915_timeline *timeline;
128 struct list_head request_list; 133 struct list_head request_list;
134 struct list_head active_link;
129 135
130 u32 head; 136 u32 head;
131 u32 tail; 137 u32 tail;
@@ -330,10 +336,10 @@ struct intel_engine_cs {
330 u8 instance; 336 u8 instance;
331 u32 context_size; 337 u32 context_size;
332 u32 mmio_base; 338 u32 mmio_base;
333 unsigned int irq_shift;
334 339
335 struct intel_ring *buffer; 340 struct intel_ring *buffer;
336 struct intel_timeline *timeline; 341
342 struct i915_timeline timeline;
337 343
338 struct drm_i915_gem_object *default_state; 344 struct drm_i915_gem_object *default_state;
339 345
@@ -459,7 +465,8 @@ struct intel_engine_cs {
459 * 465 *
460 * Called under the struct_mutex. 466 * Called under the struct_mutex.
461 */ 467 */
462 void (*schedule)(struct i915_request *request, int priority); 468 void (*schedule)(struct i915_request *request,
469 const struct i915_sched_attr *attr);
463 470
464 /* 471 /*
465 * Cancel all requests on the hardware, or queued for execution. 472 * Cancel all requests on the hardware, or queued for execution.
@@ -561,6 +568,7 @@ struct intel_engine_cs {
561 568
562#define I915_ENGINE_NEEDS_CMD_PARSER BIT(0) 569#define I915_ENGINE_NEEDS_CMD_PARSER BIT(0)
563#define I915_ENGINE_SUPPORTS_STATS BIT(1) 570#define I915_ENGINE_SUPPORTS_STATS BIT(1)
571#define I915_ENGINE_HAS_PREEMPTION BIT(2)
564 unsigned int flags; 572 unsigned int flags;
565 573
566 /* 574 /*
@@ -591,7 +599,7 @@ struct intel_engine_cs {
591 /** 599 /**
592 * @lock: Lock protecting the below fields. 600 * @lock: Lock protecting the below fields.
593 */ 601 */
594 spinlock_t lock; 602 seqlock_t lock;
595 /** 603 /**
596 * @enabled: Reference count indicating number of listeners. 604 * @enabled: Reference count indicating number of listeners.
597 */ 605 */
@@ -620,16 +628,29 @@ struct intel_engine_cs {
620 } stats; 628 } stats;
621}; 629};
622 630
623static inline bool intel_engine_needs_cmd_parser(struct intel_engine_cs *engine) 631static inline bool
632intel_engine_needs_cmd_parser(const struct intel_engine_cs *engine)
624{ 633{
625 return engine->flags & I915_ENGINE_NEEDS_CMD_PARSER; 634 return engine->flags & I915_ENGINE_NEEDS_CMD_PARSER;
626} 635}
627 636
628static inline bool intel_engine_supports_stats(struct intel_engine_cs *engine) 637static inline bool
638intel_engine_supports_stats(const struct intel_engine_cs *engine)
629{ 639{
630 return engine->flags & I915_ENGINE_SUPPORTS_STATS; 640 return engine->flags & I915_ENGINE_SUPPORTS_STATS;
631} 641}
632 642
643static inline bool
644intel_engine_has_preemption(const struct intel_engine_cs *engine)
645{
646 return engine->flags & I915_ENGINE_HAS_PREEMPTION;
647}
648
649static inline bool __execlists_need_preempt(int prio, int last)
650{
651 return prio > max(0, last);
652}
653
633static inline void 654static inline void
634execlists_set_active(struct intel_engine_execlists *execlists, 655execlists_set_active(struct intel_engine_execlists *execlists,
635 unsigned int bit) 656 unsigned int bit)
@@ -637,6 +658,13 @@ execlists_set_active(struct intel_engine_execlists *execlists,
637 __set_bit(bit, (unsigned long *)&execlists->active); 658 __set_bit(bit, (unsigned long *)&execlists->active);
638} 659}
639 660
661static inline bool
662execlists_set_active_once(struct intel_engine_execlists *execlists,
663 unsigned int bit)
664{
665 return !__test_and_set_bit(bit, (unsigned long *)&execlists->active);
666}
667
640static inline void 668static inline void
641execlists_clear_active(struct intel_engine_execlists *execlists, 669execlists_clear_active(struct intel_engine_execlists *execlists,
642 unsigned int bit) 670 unsigned int bit)
@@ -651,6 +679,10 @@ execlists_is_active(const struct intel_engine_execlists *execlists,
651 return test_bit(bit, (unsigned long *)&execlists->active); 679 return test_bit(bit, (unsigned long *)&execlists->active);
652} 680}
653 681
682void execlists_user_begin(struct intel_engine_execlists *execlists,
683 const struct execlist_port *port);
684void execlists_user_end(struct intel_engine_execlists *execlists);
685
654void 686void
655execlists_cancel_port_requests(struct intel_engine_execlists * const execlists); 687execlists_cancel_port_requests(struct intel_engine_execlists * const execlists);
656 688
@@ -663,7 +695,7 @@ execlists_num_ports(const struct intel_engine_execlists * const execlists)
663 return execlists->port_mask + 1; 695 return execlists->port_mask + 1;
664} 696}
665 697
666static inline void 698static inline struct execlist_port *
667execlists_port_complete(struct intel_engine_execlists * const execlists, 699execlists_port_complete(struct intel_engine_execlists * const execlists,
668 struct execlist_port * const port) 700 struct execlist_port * const port)
669{ 701{
@@ -674,6 +706,8 @@ execlists_port_complete(struct intel_engine_execlists * const execlists,
674 706
675 memmove(port, port + 1, m * sizeof(struct execlist_port)); 707 memmove(port, port + 1, m * sizeof(struct execlist_port));
676 memset(port + m, 0, sizeof(struct execlist_port)); 708 memset(port + m, 0, sizeof(struct execlist_port));
709
710 return port;
677} 711}
678 712
679static inline unsigned int 713static inline unsigned int
@@ -736,7 +770,9 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
736#define CNL_HWS_CSB_WRITE_INDEX 0x2f 770#define CNL_HWS_CSB_WRITE_INDEX 0x2f
737 771
738struct intel_ring * 772struct intel_ring *
739intel_engine_create_ring(struct intel_engine_cs *engine, int size); 773intel_engine_create_ring(struct intel_engine_cs *engine,
774 struct i915_timeline *timeline,
775 int size);
740int intel_ring_pin(struct intel_ring *ring, 776int intel_ring_pin(struct intel_ring *ring,
741 struct drm_i915_private *i915, 777 struct drm_i915_private *i915,
742 unsigned int offset_bias); 778 unsigned int offset_bias);
@@ -854,12 +890,9 @@ static inline u32 intel_engine_last_submit(struct intel_engine_cs *engine)
854 * wtih serialising this hint with anything, so document it as 890 * wtih serialising this hint with anything, so document it as
855 * a hint and nothing more. 891 * a hint and nothing more.
856 */ 892 */
857 return READ_ONCE(engine->timeline->seqno); 893 return READ_ONCE(engine->timeline.seqno);
858} 894}
859 895
860int init_workarounds_ring(struct intel_engine_cs *engine);
861int intel_ring_workarounds_emit(struct i915_request *rq);
862
863void intel_engine_get_instdone(struct intel_engine_cs *engine, 896void intel_engine_get_instdone(struct intel_engine_cs *engine,
864 struct intel_instdone *instdone); 897 struct intel_instdone *instdone);
865 898
@@ -939,7 +972,7 @@ bool intel_engine_add_wait(struct intel_engine_cs *engine,
939 struct intel_wait *wait); 972 struct intel_wait *wait);
940void intel_engine_remove_wait(struct intel_engine_cs *engine, 973void intel_engine_remove_wait(struct intel_engine_cs *engine,
941 struct intel_wait *wait); 974 struct intel_wait *wait);
942void intel_engine_enable_signaling(struct i915_request *request, bool wakeup); 975bool intel_engine_enable_signaling(struct i915_request *request, bool wakeup);
943void intel_engine_cancel_signaling(struct i915_request *request); 976void intel_engine_cancel_signaling(struct i915_request *request);
944 977
945static inline bool intel_engine_has_waiter(const struct intel_engine_cs *engine) 978static inline bool intel_engine_has_waiter(const struct intel_engine_cs *engine)
@@ -1037,7 +1070,7 @@ static inline void intel_engine_context_in(struct intel_engine_cs *engine)
1037 if (READ_ONCE(engine->stats.enabled) == 0) 1070 if (READ_ONCE(engine->stats.enabled) == 0)
1038 return; 1071 return;
1039 1072
1040 spin_lock_irqsave(&engine->stats.lock, flags); 1073 write_seqlock_irqsave(&engine->stats.lock, flags);
1041 1074
1042 if (engine->stats.enabled > 0) { 1075 if (engine->stats.enabled > 0) {
1043 if (engine->stats.active++ == 0) 1076 if (engine->stats.active++ == 0)
@@ -1045,7 +1078,7 @@ static inline void intel_engine_context_in(struct intel_engine_cs *engine)
1045 GEM_BUG_ON(engine->stats.active == 0); 1078 GEM_BUG_ON(engine->stats.active == 0);
1046 } 1079 }
1047 1080
1048 spin_unlock_irqrestore(&engine->stats.lock, flags); 1081 write_sequnlock_irqrestore(&engine->stats.lock, flags);
1049} 1082}
1050 1083
1051static inline void intel_engine_context_out(struct intel_engine_cs *engine) 1084static inline void intel_engine_context_out(struct intel_engine_cs *engine)
@@ -1055,7 +1088,7 @@ static inline void intel_engine_context_out(struct intel_engine_cs *engine)
1055 if (READ_ONCE(engine->stats.enabled) == 0) 1088 if (READ_ONCE(engine->stats.enabled) == 0)
1056 return; 1089 return;
1057 1090
1058 spin_lock_irqsave(&engine->stats.lock, flags); 1091 write_seqlock_irqsave(&engine->stats.lock, flags);
1059 1092
1060 if (engine->stats.enabled > 0) { 1093 if (engine->stats.enabled > 0) {
1061 ktime_t last; 1094 ktime_t last;
@@ -1082,7 +1115,7 @@ static inline void intel_engine_context_out(struct intel_engine_cs *engine)
1082 } 1115 }
1083 } 1116 }
1084 1117
1085 spin_unlock_irqrestore(&engine->stats.lock, flags); 1118 write_sequnlock_irqrestore(&engine->stats.lock, flags);
1086} 1119}
1087 1120
1088int intel_enable_engine_stats(struct intel_engine_cs *engine); 1121int intel_enable_engine_stats(struct intel_engine_cs *engine);
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 66de4b2dc8b7..53a6eaa9671a 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -542,6 +542,29 @@ void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv)
542 dev_priv->csr.dc_state = val; 542 dev_priv->csr.dc_state = val;
543} 543}
544 544
545/**
546 * gen9_set_dc_state - set target display C power state
547 * @dev_priv: i915 device instance
548 * @state: target DC power state
549 * - DC_STATE_DISABLE
550 * - DC_STATE_EN_UPTO_DC5
551 * - DC_STATE_EN_UPTO_DC6
552 * - DC_STATE_EN_DC9
553 *
554 * Signal to DMC firmware/HW the target DC power state passed in @state.
555 * DMC/HW can turn off individual display clocks and power rails when entering
556 * a deeper DC power state (higher in number) and turns these back when exiting
557 * that state to a shallower power state (lower in number). The HW will decide
558 * when to actually enter a given state on an on-demand basis, for instance
559 * depending on the active state of display pipes. The state of display
560 * registers backed by affected power rails are saved/restored as needed.
561 *
562 * Based on the above enabling a deeper DC power state is asynchronous wrt.
563 * enabling it. Disabling a deeper power state is synchronous: for instance
564 * setting %DC_STATE_DISABLE won't complete until all HW resources are turned
565 * back on and register state is restored. This is guaranteed by the MMIO write
566 * to DC_STATE_EN blocking until the state is restored.
567 */
545static void gen9_set_dc_state(struct drm_i915_private *dev_priv, uint32_t state) 568static void gen9_set_dc_state(struct drm_i915_private *dev_priv, uint32_t state)
546{ 569{
547 uint32_t val; 570 uint32_t val;
@@ -635,7 +658,7 @@ static void assert_can_enable_dc6(struct drm_i915_private *dev_priv)
635 assert_csr_loaded(dev_priv); 658 assert_csr_loaded(dev_priv);
636} 659}
637 660
638void skl_enable_dc6(struct drm_i915_private *dev_priv) 661static void skl_enable_dc6(struct drm_i915_private *dev_priv)
639{ 662{
640 assert_can_enable_dc6(dev_priv); 663 assert_can_enable_dc6(dev_priv);
641 664
@@ -649,13 +672,6 @@ void skl_enable_dc6(struct drm_i915_private *dev_priv)
649 gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); 672 gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
650} 673}
651 674
652void skl_disable_dc6(struct drm_i915_private *dev_priv)
653{
654 DRM_DEBUG_KMS("Disabling DC6\n");
655
656 gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
657}
658
659static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, 675static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
660 struct i915_power_well *power_well) 676 struct i915_power_well *power_well)
661{ 677{
@@ -2626,32 +2642,69 @@ static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv)
2626 mutex_unlock(&power_domains->lock); 2642 mutex_unlock(&power_domains->lock);
2627} 2643}
2628 2644
2629static void gen9_dbuf_enable(struct drm_i915_private *dev_priv) 2645static inline
2646bool intel_dbuf_slice_set(struct drm_i915_private *dev_priv,
2647 i915_reg_t reg, bool enable)
2630{ 2648{
2631 I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) | DBUF_POWER_REQUEST); 2649 u32 val, status;
2632 POSTING_READ(DBUF_CTL);
2633 2650
2651 val = I915_READ(reg);
2652 val = enable ? (val | DBUF_POWER_REQUEST) : (val & ~DBUF_POWER_REQUEST);
2653 I915_WRITE(reg, val);
2654 POSTING_READ(reg);
2634 udelay(10); 2655 udelay(10);
2635 2656
2636 if (!(I915_READ(DBUF_CTL) & DBUF_POWER_STATE)) 2657 status = I915_READ(reg) & DBUF_POWER_STATE;
2637 DRM_ERROR("DBuf power enable timeout\n"); 2658 if ((enable && !status) || (!enable && status)) {
2659 DRM_ERROR("DBus power %s timeout!\n",
2660 enable ? "enable" : "disable");
2661 return false;
2662 }
2663 return true;
2664}
2665
2666static void gen9_dbuf_enable(struct drm_i915_private *dev_priv)
2667{
2668 intel_dbuf_slice_set(dev_priv, DBUF_CTL, true);
2638} 2669}
2639 2670
2640static void gen9_dbuf_disable(struct drm_i915_private *dev_priv) 2671static void gen9_dbuf_disable(struct drm_i915_private *dev_priv)
2641{ 2672{
2642 I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) & ~DBUF_POWER_REQUEST); 2673 intel_dbuf_slice_set(dev_priv, DBUF_CTL, false);
2643 POSTING_READ(DBUF_CTL); 2674}
2644 2675
2645 udelay(10); 2676static u8 intel_dbuf_max_slices(struct drm_i915_private *dev_priv)
2677{
2678 if (INTEL_GEN(dev_priv) < 11)
2679 return 1;
2680 return 2;
2681}
2646 2682
2647 if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE) 2683void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
2648 DRM_ERROR("DBuf power disable timeout!\n"); 2684 u8 req_slices)
2685{
2686 u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
2687 u32 val;
2688 bool ret;
2689
2690 if (req_slices > intel_dbuf_max_slices(dev_priv)) {
2691 DRM_ERROR("Invalid number of dbuf slices requested\n");
2692 return;
2693 }
2694
2695 if (req_slices == hw_enabled_slices || req_slices == 0)
2696 return;
2697
2698 val = I915_READ(DBUF_CTL_S2);
2699 if (req_slices > hw_enabled_slices)
2700 ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, true);
2701 else
2702 ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, false);
2703
2704 if (ret)
2705 dev_priv->wm.skl_hw.ddb.enabled_slices = req_slices;
2649} 2706}
2650 2707
2651/*
2652 * TODO: we shouldn't always enable DBUF_CTL_S2, we should only enable it when
2653 * needed and keep it disabled as much as possible.
2654 */
2655static void icl_dbuf_enable(struct drm_i915_private *dev_priv) 2708static void icl_dbuf_enable(struct drm_i915_private *dev_priv)
2656{ 2709{
2657 I915_WRITE(DBUF_CTL_S1, I915_READ(DBUF_CTL_S1) | DBUF_POWER_REQUEST); 2710 I915_WRITE(DBUF_CTL_S1, I915_READ(DBUF_CTL_S1) | DBUF_POWER_REQUEST);
@@ -2663,6 +2716,8 @@ static void icl_dbuf_enable(struct drm_i915_private *dev_priv)
2663 if (!(I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) || 2716 if (!(I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) ||
2664 !(I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE)) 2717 !(I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE))
2665 DRM_ERROR("DBuf power enable timeout\n"); 2718 DRM_ERROR("DBuf power enable timeout\n");
2719 else
2720 dev_priv->wm.skl_hw.ddb.enabled_slices = 2;
2666} 2721}
2667 2722
2668static void icl_dbuf_disable(struct drm_i915_private *dev_priv) 2723static void icl_dbuf_disable(struct drm_i915_private *dev_priv)
@@ -2676,6 +2731,8 @@ static void icl_dbuf_disable(struct drm_i915_private *dev_priv)
2676 if ((I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) || 2731 if ((I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) ||
2677 (I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE)) 2732 (I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE))
2678 DRM_ERROR("DBuf power disable timeout!\n"); 2733 DRM_ERROR("DBuf power disable timeout!\n");
2734 else
2735 dev_priv->wm.skl_hw.ddb.enabled_slices = 0;
2679} 2736}
2680 2737
2681static void icl_mbus_init(struct drm_i915_private *dev_priv) 2738static void icl_mbus_init(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 96e213ec202d..25005023c243 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2779,9 +2779,8 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
2779 return false; 2779 return false;
2780 2780
2781 for (i = 0; i < intel_sdvo_connector->format_supported_num; i++) 2781 for (i = 0; i < intel_sdvo_connector->format_supported_num; i++)
2782 drm_property_add_enum( 2782 drm_property_add_enum(intel_sdvo_connector->tv_format, i,
2783 intel_sdvo_connector->tv_format, i, 2783 tv_format_names[intel_sdvo_connector->tv_format_supported[i]]);
2784 i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]);
2785 2784
2786 intel_sdvo_connector->base.base.state->tv.mode = intel_sdvo_connector->tv_format_supported[0]; 2785 intel_sdvo_connector->base.base.state->tv.mode = intel_sdvo_connector->tv_format_supported[0];
2787 drm_object_attach_property(&intel_sdvo_connector->base.base.base, 2786 drm_object_attach_property(&intel_sdvo_connector->base.base.base,
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index dbdcf85032df..ee23613f9fd4 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -48,6 +48,7 @@ bool intel_format_is_yuv(u32 format)
48 case DRM_FORMAT_UYVY: 48 case DRM_FORMAT_UYVY:
49 case DRM_FORMAT_VYUY: 49 case DRM_FORMAT_VYUY:
50 case DRM_FORMAT_YVYU: 50 case DRM_FORMAT_YVYU:
51 case DRM_FORMAT_NV12:
51 return true; 52 return true;
52 default: 53 default:
53 return false; 54 return false;
@@ -130,7 +131,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
130 if (scanline < min || scanline > max) 131 if (scanline < min || scanline > max)
131 break; 132 break;
132 133
133 if (timeout <= 0) { 134 if (!timeout) {
134 DRM_ERROR("Potential atomic update failure on pipe %c\n", 135 DRM_ERROR("Potential atomic update failure on pipe %c\n",
135 pipe_name(crtc->pipe)); 136 pipe_name(crtc->pipe));
136 break; 137 break;
@@ -935,20 +936,11 @@ intel_check_sprite_plane(struct intel_plane *plane,
935 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 936 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
936 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); 937 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
937 struct drm_framebuffer *fb = state->base.fb; 938 struct drm_framebuffer *fb = state->base.fb;
938 int crtc_x, crtc_y;
939 unsigned int crtc_w, crtc_h;
940 uint32_t src_x, src_y, src_w, src_h;
941 struct drm_rect *src = &state->base.src;
942 struct drm_rect *dst = &state->base.dst;
943 struct drm_rect clip = {};
944 int max_stride = INTEL_GEN(dev_priv) >= 9 ? 32768 : 16384; 939 int max_stride = INTEL_GEN(dev_priv) >= 9 ? 32768 : 16384;
945 int hscale, vscale;
946 int max_scale, min_scale; 940 int max_scale, min_scale;
947 bool can_scale; 941 bool can_scale;
948 int ret; 942 int ret;
949 943 uint32_t pixel_format = 0;
950 *src = drm_plane_state_src(&state->base);
951 *dst = drm_plane_state_dest(&state->base);
952 944
953 if (!fb) { 945 if (!fb) {
954 state->base.visible = false; 946 state->base.visible = false;
@@ -969,11 +961,14 @@ intel_check_sprite_plane(struct intel_plane *plane,
969 961
970 /* setup can_scale, min_scale, max_scale */ 962 /* setup can_scale, min_scale, max_scale */
971 if (INTEL_GEN(dev_priv) >= 9) { 963 if (INTEL_GEN(dev_priv) >= 9) {
964 if (state->base.fb)
965 pixel_format = state->base.fb->format->format;
972 /* use scaler when colorkey is not required */ 966 /* use scaler when colorkey is not required */
973 if (!state->ckey.flags) { 967 if (!state->ckey.flags) {
974 can_scale = 1; 968 can_scale = 1;
975 min_scale = 1; 969 min_scale = 1;
976 max_scale = skl_max_scale(crtc, crtc_state); 970 max_scale =
971 skl_max_scale(crtc, crtc_state, pixel_format);
977 } else { 972 } else {
978 can_scale = 0; 973 can_scale = 0;
979 min_scale = DRM_PLANE_HELPER_NO_SCALING; 974 min_scale = DRM_PLANE_HELPER_NO_SCALING;
@@ -985,64 +980,19 @@ intel_check_sprite_plane(struct intel_plane *plane,
985 min_scale = plane->can_scale ? 1 : (1 << 16); 980 min_scale = plane->can_scale ? 1 : (1 << 16);
986 } 981 }
987 982
988 /* 983 ret = drm_atomic_helper_check_plane_state(&state->base,
989 * FIXME the following code does a bunch of fuzzy adjustments to the 984 &crtc_state->base,
990 * coordinates and sizes. We probably need some way to decide whether 985 min_scale, max_scale,
991 * more strict checking should be done instead. 986 true, true);
992 */ 987 if (ret)
993 drm_rect_rotate(src, fb->width << 16, fb->height << 16, 988 return ret;
994 state->base.rotation);
995
996 hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
997 BUG_ON(hscale < 0);
998
999 vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
1000 BUG_ON(vscale < 0);
1001
1002 if (crtc_state->base.enable)
1003 drm_mode_get_hv_timing(&crtc_state->base.mode,
1004 &clip.x2, &clip.y2);
1005
1006 state->base.visible = drm_rect_clip_scaled(src, dst, &clip, hscale, vscale);
1007
1008 crtc_x = dst->x1;
1009 crtc_y = dst->y1;
1010 crtc_w = drm_rect_width(dst);
1011 crtc_h = drm_rect_height(dst);
1012 989
1013 if (state->base.visible) { 990 if (state->base.visible) {
1014 /* check again in case clipping clamped the results */ 991 struct drm_rect *src = &state->base.src;
1015 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); 992 struct drm_rect *dst = &state->base.dst;
1016 if (hscale < 0) { 993 unsigned int crtc_w = drm_rect_width(dst);
1017 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); 994 unsigned int crtc_h = drm_rect_height(dst);
1018 drm_rect_debug_print("src: ", src, true); 995 uint32_t src_x, src_y, src_w, src_h;
1019 drm_rect_debug_print("dst: ", dst, false);
1020
1021 return hscale;
1022 }
1023
1024 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
1025 if (vscale < 0) {
1026 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
1027 drm_rect_debug_print("src: ", src, true);
1028 drm_rect_debug_print("dst: ", dst, false);
1029
1030 return vscale;
1031 }
1032
1033 /* Make the source viewport size an exact multiple of the scaling factors. */
1034 drm_rect_adjust_size(src,
1035 drm_rect_width(dst) * hscale - drm_rect_width(src),
1036 drm_rect_height(dst) * vscale - drm_rect_height(src));
1037
1038 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
1039 state->base.rotation);
1040
1041 /* sanity check to make sure the src viewport wasn't enlarged */
1042 WARN_ON(src->x1 < (int) state->base.src_x ||
1043 src->y1 < (int) state->base.src_y ||
1044 src->x2 > (int) state->base.src_x + state->base.src_w ||
1045 src->y2 > (int) state->base.src_y + state->base.src_h);
1046 996
1047 /* 997 /*
1048 * Hardware doesn't handle subpixel coordinates. 998 * Hardware doesn't handle subpixel coordinates.
@@ -1055,58 +1005,40 @@ intel_check_sprite_plane(struct intel_plane *plane,
1055 src_y = src->y1 >> 16; 1005 src_y = src->y1 >> 16;
1056 src_h = drm_rect_height(src) >> 16; 1006 src_h = drm_rect_height(src) >> 16;
1057 1007
1058 if (intel_format_is_yuv(fb->format->format)) { 1008 src->x1 = src_x << 16;
1059 src_x &= ~1; 1009 src->x2 = (src_x + src_w) << 16;
1060 src_w &= ~1; 1010 src->y1 = src_y << 16;
1061 1011 src->y2 = (src_y + src_h) << 16;
1062 /*
1063 * Must keep src and dst the
1064 * same if we can't scale.
1065 */
1066 if (!can_scale)
1067 crtc_w &= ~1;
1068 1012
1069 if (crtc_w == 0) 1013 if (intel_format_is_yuv(fb->format->format) &&
1070 state->base.visible = false; 1014 fb->format->format != DRM_FORMAT_NV12 &&
1015 (src_x % 2 || src_w % 2)) {
1016 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
1017 src_x, src_w);
1018 return -EINVAL;
1071 } 1019 }
1072 }
1073
1074 /* Check size restrictions when scaling */
1075 if (state->base.visible && (src_w != crtc_w || src_h != crtc_h)) {
1076 unsigned int width_bytes;
1077 int cpp = fb->format->cpp[0];
1078 1020
1079 WARN_ON(!can_scale); 1021 /* Check size restrictions when scaling */
1022 if (src_w != crtc_w || src_h != crtc_h) {
1023 unsigned int width_bytes;
1024 int cpp = fb->format->cpp[0];
1080 1025
1081 /* FIXME interlacing min height is 6 */ 1026 WARN_ON(!can_scale);
1082 1027
1083 if (crtc_w < 3 || crtc_h < 3) 1028 width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1084 state->base.visible = false;
1085 1029
1086 if (src_w < 3 || src_h < 3) 1030 /* FIXME interlacing min height is 6 */
1087 state->base.visible = false; 1031 if (INTEL_GEN(dev_priv) < 9 && (
1088 1032 src_w < 3 || src_h < 3 ||
1089 width_bytes = ((src_x * cpp) & 63) + src_w * cpp; 1033 src_w > 2048 || src_h > 2048 ||
1090 1034 crtc_w < 3 || crtc_h < 3 ||
1091 if (INTEL_GEN(dev_priv) < 9 && (src_w > 2048 || src_h > 2048 || 1035 width_bytes > 4096 || fb->pitches[0] > 4096)) {
1092 width_bytes > 4096 || fb->pitches[0] > 4096)) { 1036 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
1093 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); 1037 return -EINVAL;
1094 return -EINVAL; 1038 }
1095 } 1039 }
1096 } 1040 }
1097 1041
1098 if (state->base.visible) {
1099 src->x1 = src_x << 16;
1100 src->x2 = (src_x + src_w) << 16;
1101 src->y1 = src_y << 16;
1102 src->y2 = (src_y + src_h) << 16;
1103 }
1104
1105 dst->x1 = crtc_x;
1106 dst->x2 = crtc_x + crtc_w;
1107 dst->y1 = crtc_y;
1108 dst->y2 = crtc_y + crtc_h;
1109
1110 if (INTEL_GEN(dev_priv) >= 9) { 1042 if (INTEL_GEN(dev_priv) >= 9) {
1111 ret = skl_check_plane_surface(crtc_state, state); 1043 ret = skl_check_plane_surface(crtc_state, state);
1112 if (ret) 1044 if (ret)
@@ -1248,6 +1180,19 @@ static uint32_t skl_plane_formats[] = {
1248 DRM_FORMAT_VYUY, 1180 DRM_FORMAT_VYUY,
1249}; 1181};
1250 1182
1183static uint32_t skl_planar_formats[] = {
1184 DRM_FORMAT_RGB565,
1185 DRM_FORMAT_ABGR8888,
1186 DRM_FORMAT_ARGB8888,
1187 DRM_FORMAT_XBGR8888,
1188 DRM_FORMAT_XRGB8888,
1189 DRM_FORMAT_YUYV,
1190 DRM_FORMAT_YVYU,
1191 DRM_FORMAT_UYVY,
1192 DRM_FORMAT_VYUY,
1193 DRM_FORMAT_NV12,
1194};
1195
1251static const uint64_t skl_plane_format_modifiers_noccs[] = { 1196static const uint64_t skl_plane_format_modifiers_noccs[] = {
1252 I915_FORMAT_MOD_Yf_TILED, 1197 I915_FORMAT_MOD_Yf_TILED,
1253 I915_FORMAT_MOD_Y_TILED, 1198 I915_FORMAT_MOD_Y_TILED,
@@ -1342,6 +1287,7 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier)
1342 case DRM_FORMAT_YVYU: 1287 case DRM_FORMAT_YVYU:
1343 case DRM_FORMAT_UYVY: 1288 case DRM_FORMAT_UYVY:
1344 case DRM_FORMAT_VYUY: 1289 case DRM_FORMAT_VYUY:
1290 case DRM_FORMAT_NV12:
1345 if (modifier == I915_FORMAT_MOD_Yf_TILED) 1291 if (modifier == I915_FORMAT_MOD_Yf_TILED)
1346 return true; 1292 return true;
1347 /* fall through */ 1293 /* fall through */
@@ -1441,8 +1387,14 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1441 intel_plane->disable_plane = skl_disable_plane; 1387 intel_plane->disable_plane = skl_disable_plane;
1442 intel_plane->get_hw_state = skl_plane_get_hw_state; 1388 intel_plane->get_hw_state = skl_plane_get_hw_state;
1443 1389
1444 plane_formats = skl_plane_formats; 1390 if (skl_plane_has_planar(dev_priv, pipe,
1445 num_plane_formats = ARRAY_SIZE(skl_plane_formats); 1391 PLANE_SPRITE0 + plane)) {
1392 plane_formats = skl_planar_formats;
1393 num_plane_formats = ARRAY_SIZE(skl_planar_formats);
1394 } else {
1395 plane_formats = skl_plane_formats;
1396 num_plane_formats = ARRAY_SIZE(skl_plane_formats);
1397 }
1446 1398
1447 if (skl_plane_has_ccs(dev_priv, pipe, PLANE_SPRITE0 + plane)) 1399 if (skl_plane_has_ccs(dev_priv, pipe, PLANE_SPRITE0 + plane))
1448 modifiers = skl_plane_format_modifiers_ccs; 1400 modifiers = skl_plane_format_modifiers_ccs;
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index e5bf0d37bf43..1cffaf7b5dbe 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -69,13 +69,15 @@ static int __get_platform_enable_guc(struct drm_i915_private *dev_priv)
69 69
70static int __get_default_guc_log_level(struct drm_i915_private *dev_priv) 70static int __get_default_guc_log_level(struct drm_i915_private *dev_priv)
71{ 71{
72 int guc_log_level = 0; /* disabled */ 72 int guc_log_level;
73 73
74 /* Enable if we're running on platform with GuC and debug config */ 74 if (!HAS_GUC(dev_priv) || !intel_uc_is_using_guc())
75 if (HAS_GUC(dev_priv) && intel_uc_is_using_guc() && 75 guc_log_level = GUC_LOG_LEVEL_DISABLED;
76 (IS_ENABLED(CONFIG_DRM_I915_DEBUG) || 76 else if (IS_ENABLED(CONFIG_DRM_I915_DEBUG) ||
77 IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))) 77 IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
78 guc_log_level = 1 + GUC_LOG_VERBOSITY_MAX; 78 guc_log_level = GUC_LOG_LEVEL_MAX;
79 else
80 guc_log_level = GUC_LOG_LEVEL_NON_VERBOSE;
79 81
80 /* Any platform specific fine-tuning can be done here */ 82 /* Any platform specific fine-tuning can be done here */
81 83
@@ -83,7 +85,7 @@ static int __get_default_guc_log_level(struct drm_i915_private *dev_priv)
83} 85}
84 86
85/** 87/**
86 * intel_uc_sanitize_options - sanitize uC related modparam options 88 * sanitize_options_early - sanitize uC related modparam options
87 * @dev_priv: device private 89 * @dev_priv: device private
88 * 90 *
89 * In case of "enable_guc" option this function will attempt to modify 91 * In case of "enable_guc" option this function will attempt to modify
@@ -99,7 +101,7 @@ static int __get_default_guc_log_level(struct drm_i915_private *dev_priv)
99 * unless GuC is enabled on given platform and the driver is compiled with 101 * unless GuC is enabled on given platform and the driver is compiled with
100 * debug config when this modparam will default to "enable(1..4)". 102 * debug config when this modparam will default to "enable(1..4)".
101 */ 103 */
102void intel_uc_sanitize_options(struct drm_i915_private *dev_priv) 104static void sanitize_options_early(struct drm_i915_private *dev_priv)
103{ 105{
104 struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; 106 struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
105 struct intel_uc_fw *huc_fw = &dev_priv->huc.fw; 107 struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
@@ -142,51 +144,53 @@ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
142 i915_modparams.guc_log_level = 0; 144 i915_modparams.guc_log_level = 0;
143 } 145 }
144 146
145 if (i915_modparams.guc_log_level > 1 + GUC_LOG_VERBOSITY_MAX) { 147 if (i915_modparams.guc_log_level > GUC_LOG_LEVEL_MAX) {
146 DRM_WARN("Incompatible option detected: %s=%d, %s!\n", 148 DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
147 "guc_log_level", i915_modparams.guc_log_level, 149 "guc_log_level", i915_modparams.guc_log_level,
148 "verbosity too high"); 150 "verbosity too high");
149 i915_modparams.guc_log_level = 1 + GUC_LOG_VERBOSITY_MAX; 151 i915_modparams.guc_log_level = GUC_LOG_LEVEL_MAX;
150 } 152 }
151 153
152 DRM_DEBUG_DRIVER("guc_log_level=%d (enabled:%s verbosity:%d)\n", 154 DRM_DEBUG_DRIVER("guc_log_level=%d (enabled:%s, verbose:%s, verbosity:%d)\n",
153 i915_modparams.guc_log_level, 155 i915_modparams.guc_log_level,
154 yesno(i915_modparams.guc_log_level), 156 yesno(i915_modparams.guc_log_level),
155 i915_modparams.guc_log_level - 1); 157 yesno(GUC_LOG_LEVEL_IS_VERBOSE(i915_modparams.guc_log_level)),
158 GUC_LOG_LEVEL_TO_VERBOSITY(i915_modparams.guc_log_level));
156 159
157 /* Make sure that sanitization was done */ 160 /* Make sure that sanitization was done */
158 GEM_BUG_ON(i915_modparams.enable_guc < 0); 161 GEM_BUG_ON(i915_modparams.enable_guc < 0);
159 GEM_BUG_ON(i915_modparams.guc_log_level < 0); 162 GEM_BUG_ON(i915_modparams.guc_log_level < 0);
160} 163}
161 164
162void intel_uc_init_early(struct drm_i915_private *dev_priv) 165void intel_uc_init_early(struct drm_i915_private *i915)
163{ 166{
164 intel_guc_init_early(&dev_priv->guc); 167 struct intel_guc *guc = &i915->guc;
165 intel_huc_init_early(&dev_priv->huc); 168 struct intel_huc *huc = &i915->huc;
166}
167 169
168void intel_uc_init_fw(struct drm_i915_private *dev_priv) 170 intel_guc_init_early(guc);
169{ 171 intel_huc_init_early(huc);
170 if (!USES_GUC(dev_priv))
171 return;
172 172
173 if (USES_HUC(dev_priv)) 173 sanitize_options_early(i915);
174 intel_uc_fw_fetch(dev_priv, &dev_priv->huc.fw);
175 174
176 intel_uc_fw_fetch(dev_priv, &dev_priv->guc.fw); 175 if (USES_GUC(i915))
176 intel_uc_fw_fetch(i915, &guc->fw);
177
178 if (USES_HUC(i915))
179 intel_uc_fw_fetch(i915, &huc->fw);
177} 180}
178 181
179void intel_uc_fini_fw(struct drm_i915_private *dev_priv) 182void intel_uc_cleanup_early(struct drm_i915_private *i915)
180{ 183{
181 if (!USES_GUC(dev_priv)) 184 struct intel_guc *guc = &i915->guc;
182 return; 185 struct intel_huc *huc = &i915->huc;
183 186
184 intel_uc_fw_fini(&dev_priv->guc.fw); 187 if (USES_HUC(i915))
188 intel_uc_fw_fini(&huc->fw);
185 189
186 if (USES_HUC(dev_priv)) 190 if (USES_GUC(i915))
187 intel_uc_fw_fini(&dev_priv->huc.fw); 191 intel_uc_fw_fini(&guc->fw);
188 192
189 guc_free_load_err_log(&dev_priv->guc); 193 guc_free_load_err_log(guc);
190} 194}
191 195
192/** 196/**
@@ -223,10 +227,13 @@ static int guc_enable_communication(struct intel_guc *guc)
223{ 227{
224 struct drm_i915_private *dev_priv = guc_to_i915(guc); 228 struct drm_i915_private *dev_priv = guc_to_i915(guc);
225 229
230 gen9_enable_guc_interrupts(dev_priv);
231
226 if (HAS_GUC_CT(dev_priv)) 232 if (HAS_GUC_CT(dev_priv))
227 return intel_guc_enable_ct(guc); 233 return intel_guc_ct_enable(&guc->ct);
228 234
229 guc->send = intel_guc_send_mmio; 235 guc->send = intel_guc_send_mmio;
236 guc->handler = intel_guc_to_host_event_handler_mmio;
230 return 0; 237 return 0;
231} 238}
232 239
@@ -235,9 +242,12 @@ static void guc_disable_communication(struct intel_guc *guc)
235 struct drm_i915_private *dev_priv = guc_to_i915(guc); 242 struct drm_i915_private *dev_priv = guc_to_i915(guc);
236 243
237 if (HAS_GUC_CT(dev_priv)) 244 if (HAS_GUC_CT(dev_priv))
238 intel_guc_disable_ct(guc); 245 intel_guc_ct_disable(&guc->ct);
246
247 gen9_disable_guc_interrupts(dev_priv);
239 248
240 guc->send = intel_guc_send_nop; 249 guc->send = intel_guc_send_nop;
250 guc->handler = intel_guc_to_host_event_handler_nop;
241} 251}
242 252
243int intel_uc_init_misc(struct drm_i915_private *dev_priv) 253int intel_uc_init_misc(struct drm_i915_private *dev_priv)
@@ -248,24 +258,13 @@ int intel_uc_init_misc(struct drm_i915_private *dev_priv)
248 if (!USES_GUC(dev_priv)) 258 if (!USES_GUC(dev_priv))
249 return 0; 259 return 0;
250 260
251 ret = intel_guc_init_wq(guc); 261 intel_guc_init_ggtt_pin_bias(guc);
252 if (ret) {
253 DRM_ERROR("Couldn't allocate workqueues for GuC\n");
254 goto err;
255 }
256 262
257 ret = intel_guc_log_relay_create(guc); 263 ret = intel_guc_init_wq(guc);
258 if (ret) { 264 if (ret)
259 DRM_ERROR("Couldn't allocate relay for GuC log\n"); 265 return ret;
260 goto err_relay;
261 }
262 266
263 return 0; 267 return 0;
264
265err_relay:
266 intel_guc_fini_wq(guc);
267err:
268 return ret;
269} 268}
270 269
271void intel_uc_fini_misc(struct drm_i915_private *dev_priv) 270void intel_uc_fini_misc(struct drm_i915_private *dev_priv)
@@ -276,8 +275,6 @@ void intel_uc_fini_misc(struct drm_i915_private *dev_priv)
276 return; 275 return;
277 276
278 intel_guc_fini_wq(guc); 277 intel_guc_fini_wq(guc);
279
280 intel_guc_log_relay_destroy(guc);
281} 278}
282 279
283int intel_uc_init(struct drm_i915_private *dev_priv) 280int intel_uc_init(struct drm_i915_private *dev_priv)
@@ -325,6 +322,24 @@ void intel_uc_fini(struct drm_i915_private *dev_priv)
325 intel_guc_fini(guc); 322 intel_guc_fini(guc);
326} 323}
327 324
325void intel_uc_sanitize(struct drm_i915_private *i915)
326{
327 struct intel_guc *guc = &i915->guc;
328 struct intel_huc *huc = &i915->huc;
329
330 if (!USES_GUC(i915))
331 return;
332
333 GEM_BUG_ON(!HAS_GUC(i915));
334
335 guc_disable_communication(guc);
336
337 intel_huc_sanitize(huc);
338 intel_guc_sanitize(guc);
339
340 __intel_uc_reset_hw(i915);
341}
342
328int intel_uc_init_hw(struct drm_i915_private *dev_priv) 343int intel_uc_init_hw(struct drm_i915_private *dev_priv)
329{ 344{
330 struct intel_guc *guc = &dev_priv->guc; 345 struct intel_guc *guc = &dev_priv->guc;
@@ -336,14 +351,8 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
336 351
337 GEM_BUG_ON(!HAS_GUC(dev_priv)); 352 GEM_BUG_ON(!HAS_GUC(dev_priv));
338 353
339 guc_disable_communication(guc);
340 gen9_reset_guc_interrupts(dev_priv); 354 gen9_reset_guc_interrupts(dev_priv);
341 355
342 /* init WOPCM */
343 I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
344 I915_WRITE(DMA_GUC_WOPCM_OFFSET,
345 GUC_WOPCM_OFFSET_VALUE | HUC_LOADING_AGENT_GUC);
346
347 /* WaEnableuKernelHeaderValidFix:skl */ 356 /* WaEnableuKernelHeaderValidFix:skl */
348 /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */ 357 /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
349 if (IS_GEN9(dev_priv)) 358 if (IS_GEN9(dev_priv))
@@ -390,12 +399,9 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
390 } 399 }
391 400
392 if (USES_GUC_SUBMISSION(dev_priv)) { 401 if (USES_GUC_SUBMISSION(dev_priv)) {
393 if (i915_modparams.guc_log_level)
394 gen9_enable_guc_interrupts(dev_priv);
395
396 ret = intel_guc_submission_enable(guc); 402 ret = intel_guc_submission_enable(guc);
397 if (ret) 403 if (ret)
398 goto err_interrupts; 404 goto err_communication;
399 } 405 }
400 406
401 dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n", 407 dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n",
@@ -410,8 +416,6 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
410 /* 416 /*
411 * We've failed to load the firmware :( 417 * We've failed to load the firmware :(
412 */ 418 */
413err_interrupts:
414 gen9_disable_guc_interrupts(dev_priv);
415err_communication: 419err_communication:
416 guc_disable_communication(guc); 420 guc_disable_communication(guc);
417err_log_capture: 421err_log_capture:
@@ -441,9 +445,6 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
441 intel_guc_submission_disable(guc); 445 intel_guc_submission_disable(guc);
442 446
443 guc_disable_communication(guc); 447 guc_disable_communication(guc);
444
445 if (USES_GUC_SUBMISSION(dev_priv))
446 gen9_disable_guc_interrupts(dev_priv);
447} 448}
448 449
449int intel_uc_suspend(struct drm_i915_private *i915) 450int intel_uc_suspend(struct drm_i915_private *i915)
@@ -479,8 +480,7 @@ int intel_uc_resume(struct drm_i915_private *i915)
479 if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) 480 if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
480 return 0; 481 return 0;
481 482
482 if (i915_modparams.guc_log_level) 483 gen9_enable_guc_interrupts(i915);
483 gen9_enable_guc_interrupts(i915);
484 484
485 err = intel_guc_resume(guc); 485 err = intel_guc_resume(guc);
486 if (err) { 486 if (err) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index f76d51d1ce70..25d73ada74ae 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -28,13 +28,12 @@
28#include "intel_huc.h" 28#include "intel_huc.h"
29#include "i915_params.h" 29#include "i915_params.h"
30 30
31void intel_uc_sanitize_options(struct drm_i915_private *dev_priv);
32void intel_uc_init_early(struct drm_i915_private *dev_priv); 31void intel_uc_init_early(struct drm_i915_private *dev_priv);
32void intel_uc_cleanup_early(struct drm_i915_private *dev_priv);
33void intel_uc_init_mmio(struct drm_i915_private *dev_priv); 33void intel_uc_init_mmio(struct drm_i915_private *dev_priv);
34void intel_uc_init_fw(struct drm_i915_private *dev_priv);
35void intel_uc_fini_fw(struct drm_i915_private *dev_priv);
36int intel_uc_init_misc(struct drm_i915_private *dev_priv); 34int intel_uc_init_misc(struct drm_i915_private *dev_priv);
37void intel_uc_fini_misc(struct drm_i915_private *dev_priv); 35void intel_uc_fini_misc(struct drm_i915_private *dev_priv);
36void intel_uc_sanitize(struct drm_i915_private *dev_priv);
38int intel_uc_init_hw(struct drm_i915_private *dev_priv); 37int intel_uc_init_hw(struct drm_i915_private *dev_priv);
39void intel_uc_fini_hw(struct drm_i915_private *dev_priv); 38void intel_uc_fini_hw(struct drm_i915_private *dev_priv);
40int intel_uc_init(struct drm_i915_private *dev_priv); 39int intel_uc_init(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c b/drivers/gpu/drm/i915/intel_uc_fw.c
index 3ec0ce505b76..6e8e0b546743 100644
--- a/drivers/gpu/drm/i915/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/intel_uc_fw.c
@@ -95,15 +95,6 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
95 uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size; 95 uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
96 uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32); 96 uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
97 97
98 /* Header and uCode will be loaded to WOPCM */
99 size = uc_fw->header_size + uc_fw->ucode_size;
100 if (size > intel_guc_wopcm_size(dev_priv)) {
101 DRM_WARN("%s: Firmware is too large to fit in WOPCM\n",
102 intel_uc_fw_type_repr(uc_fw->type));
103 err = -E2BIG;
104 goto fail;
105 }
106
107 /* now RSA */ 98 /* now RSA */
108 if (css->key_size_dw != UOS_RSA_SCRATCH_COUNT) { 99 if (css->key_size_dw != UOS_RSA_SCRATCH_COUNT) {
109 DRM_WARN("%s: Mismatched firmware RSA key size (%u)\n", 100 DRM_WARN("%s: Mismatched firmware RSA key size (%u)\n",
@@ -209,6 +200,7 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
209 struct i915_vma *vma)) 200 struct i915_vma *vma))
210{ 201{
211 struct i915_vma *vma; 202 struct i915_vma *vma;
203 u32 ggtt_pin_bias;
212 int err; 204 int err;
213 205
214 DRM_DEBUG_DRIVER("%s fw load %s\n", 206 DRM_DEBUG_DRIVER("%s fw load %s\n",
@@ -230,8 +222,9 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
230 goto fail; 222 goto fail;
231 } 223 }
232 224
225 ggtt_pin_bias = to_i915(uc_fw->obj->base.dev)->guc.ggtt_pin_bias;
233 vma = i915_gem_object_ggtt_pin(uc_fw->obj, NULL, 0, 0, 226 vma = i915_gem_object_ggtt_pin(uc_fw->obj, NULL, 0, 0,
234 PIN_OFFSET_BIAS | GUC_WOPCM_TOP); 227 PIN_OFFSET_BIAS | ggtt_pin_bias);
235 if (IS_ERR(vma)) { 228 if (IS_ERR(vma)) {
236 err = PTR_ERR(vma); 229 err = PTR_ERR(vma);
237 DRM_DEBUG_DRIVER("%s fw ggtt-pin err=%d\n", 230 DRM_DEBUG_DRIVER("%s fw ggtt-pin err=%d\n",
diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h
index d5fd4609c785..87910aa83267 100644
--- a/drivers/gpu/drm/i915/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/intel_uc_fw.h
@@ -30,7 +30,7 @@ struct drm_i915_private;
30struct i915_vma; 30struct i915_vma;
31 31
32/* Home of GuC, HuC and DMC firmwares */ 32/* Home of GuC, HuC and DMC firmwares */
33#define INTEL_UC_FIRMWARE_URL "https://01.org/linuxgraphics/downloads/firmware" 33#define INTEL_UC_FIRMWARE_URL "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/i915"
34 34
35enum intel_uc_fw_status { 35enum intel_uc_fw_status {
36 INTEL_UC_FIRMWARE_FAIL = -1, 36 INTEL_UC_FIRMWARE_FAIL = -1,
@@ -115,6 +115,28 @@ static inline bool intel_uc_fw_is_selected(struct intel_uc_fw *uc_fw)
115 return uc_fw->path != NULL; 115 return uc_fw->path != NULL;
116} 116}
117 117
118static inline void intel_uc_fw_sanitize(struct intel_uc_fw *uc_fw)
119{
120 if (uc_fw->load_status == INTEL_UC_FIRMWARE_SUCCESS)
121 uc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
122}
123
124/**
125 * intel_uc_fw_get_upload_size() - Get size of firmware needed to be uploaded.
126 * @uc_fw: uC firmware.
127 *
128 * Get the size of the firmware and header that will be uploaded to WOPCM.
129 *
130 * Return: Upload firmware size, or zero on firmware fetch failure.
131 */
132static inline u32 intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
133{
134 if (uc_fw->fetch_status != INTEL_UC_FIRMWARE_SUCCESS)
135 return 0;
136
137 return uc_fw->header_size + uc_fw->ucode_size;
138}
139
118void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, 140void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
119 struct intel_uc_fw *uc_fw); 141 struct intel_uc_fw *uc_fw);
120int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, 142int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 4df7c2ef8576..448293eb638d 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -62,6 +62,11 @@ static inline void
62fw_domain_reset(struct drm_i915_private *i915, 62fw_domain_reset(struct drm_i915_private *i915,
63 const struct intel_uncore_forcewake_domain *d) 63 const struct intel_uncore_forcewake_domain *d)
64{ 64{
65 /*
66 * We don't really know if the powerwell for the forcewake domain we are
67 * trying to reset here does exist at this point (engines could be fused
68 * off in ICL+), so no waiting for acks
69 */
65 __raw_i915_write32(i915, d->reg_set, i915->uncore.fw_reset); 70 __raw_i915_write32(i915, d->reg_set, i915->uncore.fw_reset);
66} 71}
67 72
@@ -134,7 +139,9 @@ fw_domain_wait_ack_with_fallback(const struct drm_i915_private *i915,
134 * in the hope that the original ack will be delivered along with 139 * in the hope that the original ack will be delivered along with
135 * the fallback ack. 140 * the fallback ack.
136 * 141 *
137 * This workaround is described in HSDES #1604254524 142 * This workaround is described in HSDES #1604254524 and it's known as:
143 * WaRsForcewakeAddDelayForAck:skl,bxt,kbl,glk,cfl,cnl,icl
144 * although the name is a bit misleading.
138 */ 145 */
139 146
140 pass = 1; 147 pass = 1;
@@ -1353,6 +1360,23 @@ static void fw_domain_init(struct drm_i915_private *dev_priv,
1353 fw_domain_reset(dev_priv, d); 1360 fw_domain_reset(dev_priv, d);
1354} 1361}
1355 1362
1363static void fw_domain_fini(struct drm_i915_private *dev_priv,
1364 enum forcewake_domain_id domain_id)
1365{
1366 struct intel_uncore_forcewake_domain *d;
1367
1368 if (WARN_ON(domain_id >= FW_DOMAIN_ID_COUNT))
1369 return;
1370
1371 d = &dev_priv->uncore.fw_domain[domain_id];
1372
1373 WARN_ON(d->wake_count);
1374 WARN_ON(hrtimer_cancel(&d->timer));
1375 memset(d, 0, sizeof(*d));
1376
1377 dev_priv->uncore.fw_domains &= ~BIT(domain_id);
1378}
1379
1356static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv) 1380static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv)
1357{ 1381{
1358 if (INTEL_GEN(dev_priv) <= 5 || intel_vgpu_active(dev_priv)) 1382 if (INTEL_GEN(dev_priv) <= 5 || intel_vgpu_active(dev_priv))
@@ -1372,7 +1396,8 @@ static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv)
1372 if (INTEL_GEN(dev_priv) >= 11) { 1396 if (INTEL_GEN(dev_priv) >= 11) {
1373 int i; 1397 int i;
1374 1398
1375 dev_priv->uncore.funcs.force_wake_get = fw_domains_get; 1399 dev_priv->uncore.funcs.force_wake_get =
1400 fw_domains_get_with_fallback;
1376 dev_priv->uncore.funcs.force_wake_put = fw_domains_put; 1401 dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
1377 fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, 1402 fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
1378 FORCEWAKE_RENDER_GEN9, 1403 FORCEWAKE_RENDER_GEN9,
@@ -1565,6 +1590,40 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
1565 &dev_priv->uncore.pmic_bus_access_nb); 1590 &dev_priv->uncore.pmic_bus_access_nb);
1566} 1591}
1567 1592
1593/*
1594 * We might have detected that some engines are fused off after we initialized
1595 * the forcewake domains. Prune them, to make sure they only reference existing
1596 * engines.
1597 */
1598void intel_uncore_prune(struct drm_i915_private *dev_priv)
1599{
1600 if (INTEL_GEN(dev_priv) >= 11) {
1601 enum forcewake_domains fw_domains = dev_priv->uncore.fw_domains;
1602 enum forcewake_domain_id domain_id;
1603 int i;
1604
1605 for (i = 0; i < I915_MAX_VCS; i++) {
1606 domain_id = FW_DOMAIN_ID_MEDIA_VDBOX0 + i;
1607
1608 if (HAS_ENGINE(dev_priv, _VCS(i)))
1609 continue;
1610
1611 if (fw_domains & BIT(domain_id))
1612 fw_domain_fini(dev_priv, domain_id);
1613 }
1614
1615 for (i = 0; i < I915_MAX_VECS; i++) {
1616 domain_id = FW_DOMAIN_ID_MEDIA_VEBOX0 + i;
1617
1618 if (HAS_ENGINE(dev_priv, _VECS(i)))
1619 continue;
1620
1621 if (fw_domains & BIT(domain_id))
1622 fw_domain_fini(dev_priv, domain_id);
1623 }
1624 }
1625}
1626
1568void intel_uncore_fini(struct drm_i915_private *dev_priv) 1627void intel_uncore_fini(struct drm_i915_private *dev_priv)
1569{ 1628{
1570 /* Paranoia: make sure we have disabled everything before we exit. */ 1629 /* Paranoia: make sure we have disabled everything before we exit. */
@@ -1646,11 +1705,10 @@ static void gen3_stop_engine(struct intel_engine_cs *engine)
1646 const i915_reg_t mode = RING_MI_MODE(base); 1705 const i915_reg_t mode = RING_MI_MODE(base);
1647 1706
1648 I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING)); 1707 I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING));
1649 if (intel_wait_for_register_fw(dev_priv, 1708 if (__intel_wait_for_register_fw(dev_priv,
1650 mode, 1709 mode, MODE_IDLE, MODE_IDLE,
1651 MODE_IDLE, 1710 500, 0,
1652 MODE_IDLE, 1711 NULL))
1653 500))
1654 DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", 1712 DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n",
1655 engine->name); 1713 engine->name);
1656 1714
@@ -1804,9 +1862,10 @@ static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv,
1804 __raw_i915_write32(dev_priv, GEN6_GDRST, hw_domain_mask); 1862 __raw_i915_write32(dev_priv, GEN6_GDRST, hw_domain_mask);
1805 1863
1806 /* Wait for the device to ack the reset requests */ 1864 /* Wait for the device to ack the reset requests */
1807 err = intel_wait_for_register_fw(dev_priv, 1865 err = __intel_wait_for_register_fw(dev_priv,
1808 GEN6_GDRST, hw_domain_mask, 0, 1866 GEN6_GDRST, hw_domain_mask, 0,
1809 500); 1867 500, 0,
1868 NULL);
1810 if (err) 1869 if (err)
1811 DRM_DEBUG_DRIVER("Wait for 0x%08x engines reset failed\n", 1870 DRM_DEBUG_DRIVER("Wait for 0x%08x engines reset failed\n",
1812 hw_domain_mask); 1871 hw_domain_mask);
@@ -1854,6 +1913,50 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv,
1854} 1913}
1855 1914
1856/** 1915/**
1916 * gen11_reset_engines - reset individual engines
1917 * @dev_priv: i915 device
1918 * @engine_mask: mask of intel_ring_flag() engines or ALL_ENGINES for full reset
1919 *
1920 * This function will reset the individual engines that are set in engine_mask.
1921 * If you provide ALL_ENGINES as mask, full global domain reset will be issued.
1922 *
1923 * Note: It is responsibility of the caller to handle the difference between
1924 * asking full domain reset versus reset for all available individual engines.
1925 *
1926 * Returns 0 on success, nonzero on error.
1927 */
1928static int gen11_reset_engines(struct drm_i915_private *dev_priv,
1929 unsigned engine_mask)
1930{
1931 struct intel_engine_cs *engine;
1932 const u32 hw_engine_mask[I915_NUM_ENGINES] = {
1933 [RCS] = GEN11_GRDOM_RENDER,
1934 [BCS] = GEN11_GRDOM_BLT,
1935 [VCS] = GEN11_GRDOM_MEDIA,
1936 [VCS2] = GEN11_GRDOM_MEDIA2,
1937 [VCS3] = GEN11_GRDOM_MEDIA3,
1938 [VCS4] = GEN11_GRDOM_MEDIA4,
1939 [VECS] = GEN11_GRDOM_VECS,
1940 [VECS2] = GEN11_GRDOM_VECS2,
1941 };
1942 u32 hw_mask;
1943
1944 BUILD_BUG_ON(VECS2 + 1 != I915_NUM_ENGINES);
1945
1946 if (engine_mask == ALL_ENGINES) {
1947 hw_mask = GEN11_GRDOM_FULL;
1948 } else {
1949 unsigned int tmp;
1950
1951 hw_mask = 0;
1952 for_each_engine_masked(engine, dev_priv, engine_mask, tmp)
1953 hw_mask |= hw_engine_mask[engine->id];
1954 }
1955
1956 return gen6_hw_domain_reset(dev_priv, hw_mask);
1957}
1958
1959/**
1857 * __intel_wait_for_register_fw - wait until register matches expected state 1960 * __intel_wait_for_register_fw - wait until register matches expected state
1858 * @dev_priv: the i915 device 1961 * @dev_priv: the i915 device
1859 * @reg: the register to read 1962 * @reg: the register to read
@@ -1940,7 +2043,7 @@ int __intel_wait_for_register(struct drm_i915_private *dev_priv,
1940 u32 reg_value; 2043 u32 reg_value;
1941 int ret; 2044 int ret;
1942 2045
1943 might_sleep(); 2046 might_sleep_if(slow_timeout_ms);
1944 2047
1945 spin_lock_irq(&dev_priv->uncore.lock); 2048 spin_lock_irq(&dev_priv->uncore.lock);
1946 intel_uncore_forcewake_get__locked(dev_priv, fw); 2049 intel_uncore_forcewake_get__locked(dev_priv, fw);
@@ -1952,7 +2055,7 @@ int __intel_wait_for_register(struct drm_i915_private *dev_priv,
1952 intel_uncore_forcewake_put__locked(dev_priv, fw); 2055 intel_uncore_forcewake_put__locked(dev_priv, fw);
1953 spin_unlock_irq(&dev_priv->uncore.lock); 2056 spin_unlock_irq(&dev_priv->uncore.lock);
1954 2057
1955 if (ret) 2058 if (ret && slow_timeout_ms)
1956 ret = __wait_for(reg_value = I915_READ_NOTRACE(reg), 2059 ret = __wait_for(reg_value = I915_READ_NOTRACE(reg),
1957 (reg_value & mask) == value, 2060 (reg_value & mask) == value,
1958 slow_timeout_ms * 1000, 10, 1000); 2061 slow_timeout_ms * 1000, 10, 1000);
@@ -1971,11 +2074,12 @@ static int gen8_reset_engine_start(struct intel_engine_cs *engine)
1971 I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base), 2074 I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base),
1972 _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET)); 2075 _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET));
1973 2076
1974 ret = intel_wait_for_register_fw(dev_priv, 2077 ret = __intel_wait_for_register_fw(dev_priv,
1975 RING_RESET_CTL(engine->mmio_base), 2078 RING_RESET_CTL(engine->mmio_base),
1976 RESET_CTL_READY_TO_RESET, 2079 RESET_CTL_READY_TO_RESET,
1977 RESET_CTL_READY_TO_RESET, 2080 RESET_CTL_READY_TO_RESET,
1978 700); 2081 700, 0,
2082 NULL);
1979 if (ret) 2083 if (ret)
1980 DRM_ERROR("%s: reset request timeout\n", engine->name); 2084 DRM_ERROR("%s: reset request timeout\n", engine->name);
1981 2085
@@ -2000,7 +2104,10 @@ static int gen8_reset_engines(struct drm_i915_private *dev_priv,
2000 if (gen8_reset_engine_start(engine)) 2104 if (gen8_reset_engine_start(engine))
2001 goto not_ready; 2105 goto not_ready;
2002 2106
2003 return gen6_reset_engines(dev_priv, engine_mask); 2107 if (INTEL_GEN(dev_priv) >= 11)
2108 return gen11_reset_engines(dev_priv, engine_mask);
2109 else
2110 return gen6_reset_engines(dev_priv, engine_mask);
2004 2111
2005not_ready: 2112not_ready:
2006 for_each_engine_masked(engine, dev_priv, engine_mask, tmp) 2113 for_each_engine_masked(engine, dev_priv, engine_mask, tmp)
@@ -2038,15 +2145,31 @@ int intel_gpu_reset(struct drm_i915_private *dev_priv, unsigned engine_mask)
2038 int retry; 2145 int retry;
2039 int ret; 2146 int ret;
2040 2147
2041 might_sleep(); 2148 /*
2149 * We want to perform per-engine reset from atomic context (e.g.
2150 * softirq), which imposes the constraint that we cannot sleep.
2151 * However, experience suggests that spending a bit of time waiting
2152 * for a reset helps in various cases, so for a full-device reset
2153 * we apply the opposite rule and wait if we want to. As we should
2154 * always follow up a failed per-engine reset with a full device reset,
2155 * being a little faster, stricter and more error prone for the
2156 * atomic case seems an acceptable compromise.
2157 *
2158 * Unfortunately this leads to a bimodal routine, when the goal was
2159 * to have a single reset function that worked for resetting any
2160 * number of engines simultaneously.
2161 */
2162 might_sleep_if(engine_mask == ALL_ENGINES);
2042 2163
2043 /* If the power well sleeps during the reset, the reset 2164 /*
2165 * If the power well sleeps during the reset, the reset
2044 * request may be dropped and never completes (causing -EIO). 2166 * request may be dropped and never completes (causing -EIO).
2045 */ 2167 */
2046 intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); 2168 intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
2047 for (retry = 0; retry < 3; retry++) { 2169 for (retry = 0; retry < 3; retry++) {
2048 2170
2049 /* We stop engines, otherwise we might get failed reset and a 2171 /*
2172 * We stop engines, otherwise we might get failed reset and a
2050 * dead gpu (on elk). Also as modern gpu as kbl can suffer 2173 * dead gpu (on elk). Also as modern gpu as kbl can suffer
2051 * from system hang if batchbuffer is progressing when 2174 * from system hang if batchbuffer is progressing when
2052 * the reset is issued, regardless of READY_TO_RESET ack. 2175 * the reset is issued, regardless of READY_TO_RESET ack.
@@ -2060,9 +2183,11 @@ int intel_gpu_reset(struct drm_i915_private *dev_priv, unsigned engine_mask)
2060 i915_stop_engines(dev_priv, engine_mask); 2183 i915_stop_engines(dev_priv, engine_mask);
2061 2184
2062 ret = -ENODEV; 2185 ret = -ENODEV;
2063 if (reset) 2186 if (reset) {
2187 GEM_TRACE("engine_mask=%x\n", engine_mask);
2064 ret = reset(dev_priv, engine_mask); 2188 ret = reset(dev_priv, engine_mask);
2065 if (ret != -ETIMEDOUT) 2189 }
2190 if (ret != -ETIMEDOUT || engine_mask != ALL_ENGINES)
2066 break; 2191 break;
2067 2192
2068 cond_resched(); 2193 cond_resched();
@@ -2085,12 +2210,14 @@ bool intel_has_reset_engine(struct drm_i915_private *dev_priv)
2085 2210
2086int intel_reset_guc(struct drm_i915_private *dev_priv) 2211int intel_reset_guc(struct drm_i915_private *dev_priv)
2087{ 2212{
2213 u32 guc_domain = INTEL_GEN(dev_priv) >= 11 ? GEN11_GRDOM_GUC :
2214 GEN9_GRDOM_GUC;
2088 int ret; 2215 int ret;
2089 2216
2090 GEM_BUG_ON(!HAS_GUC(dev_priv)); 2217 GEM_BUG_ON(!HAS_GUC(dev_priv));
2091 2218
2092 intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); 2219 intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
2093 ret = gen6_hw_domain_reset(dev_priv, GEN9_GRDOM_GUC); 2220 ret = gen6_hw_domain_reset(dev_priv, guc_domain);
2094 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); 2221 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
2095 2222
2096 return ret; 2223 return ret;
diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h
index dfdf444e4bcc..47478d609630 100644
--- a/drivers/gpu/drm/i915/intel_uncore.h
+++ b/drivers/gpu/drm/i915/intel_uncore.h
@@ -140,6 +140,7 @@ struct intel_uncore {
140 140
141void intel_uncore_sanitize(struct drm_i915_private *dev_priv); 141void intel_uncore_sanitize(struct drm_i915_private *dev_priv);
142void intel_uncore_init(struct drm_i915_private *dev_priv); 142void intel_uncore_init(struct drm_i915_private *dev_priv);
143void intel_uncore_prune(struct drm_i915_private *dev_priv);
143bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv); 144bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv);
144bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv); 145bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv);
145void intel_uncore_fini(struct drm_i915_private *dev_priv); 146void intel_uncore_fini(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/intel_wopcm.c
new file mode 100644
index 000000000000..74bf76f3fddc
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_wopcm.c
@@ -0,0 +1,275 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright © 2017-2018 Intel Corporation
5 */
6
7#include "intel_wopcm.h"
8#include "i915_drv.h"
9
10/**
11 * DOC: WOPCM Layout
12 *
13 * The layout of the WOPCM will be fixed after writing to GuC WOPCM size and
14 * offset registers whose values are calculated and determined by HuC/GuC
15 * firmware size and set of hardware requirements/restrictions as shown below:
16 *
17 * ::
18 *
19 * +=========> +====================+ <== WOPCM Top
20 * ^ | HW contexts RSVD |
21 * | +===> +====================+ <== GuC WOPCM Top
22 * | ^ | |
23 * | | | |
24 * | | | |
25 * | GuC | |
26 * | WOPCM | |
27 * | Size +--------------------+
28 * WOPCM | | GuC FW RSVD |
29 * | | +--------------------+
30 * | | | GuC Stack RSVD |
31 * | | +------------------- +
32 * | v | GuC WOPCM RSVD |
33 * | +===> +====================+ <== GuC WOPCM base
34 * | | WOPCM RSVD |
35 * | +------------------- + <== HuC Firmware Top
36 * v | HuC FW |
37 * +=========> +====================+ <== WOPCM Base
38 *
39 * GuC accessible WOPCM starts at GuC WOPCM base and ends at GuC WOPCM top.
40 * The top part of the WOPCM is reserved for hardware contexts (e.g. RC6
41 * context).
42 */
43
44/* Default WOPCM size 1MB. */
45#define GEN9_WOPCM_SIZE (1024 * 1024)
46/* 16KB WOPCM (RSVD WOPCM) is reserved from HuC firmware top. */
47#define WOPCM_RESERVED_SIZE (16 * 1024)
48
49/* 16KB reserved at the beginning of GuC WOPCM. */
50#define GUC_WOPCM_RESERVED (16 * 1024)
51/* 8KB from GUC_WOPCM_RESERVED is reserved for GuC stack. */
52#define GUC_WOPCM_STACK_RESERVED (8 * 1024)
53
54/* GuC WOPCM Offset value needs to be aligned to 16KB. */
55#define GUC_WOPCM_OFFSET_ALIGNMENT (1UL << GUC_WOPCM_OFFSET_SHIFT)
56
57/* 24KB at the end of WOPCM is reserved for RC6 CTX on BXT. */
58#define BXT_WOPCM_RC6_CTX_RESERVED (24 * 1024)
59/* 36KB WOPCM reserved at the end of WOPCM on CNL. */
60#define CNL_WOPCM_HW_CTX_RESERVED (36 * 1024)
61
62/* 128KB from GUC_WOPCM_RESERVED is reserved for FW on Gen9. */
63#define GEN9_GUC_FW_RESERVED (128 * 1024)
64#define GEN9_GUC_WOPCM_OFFSET (GUC_WOPCM_RESERVED + GEN9_GUC_FW_RESERVED)
65
66/**
67 * intel_wopcm_init_early() - Early initialization of the WOPCM.
68 * @wopcm: pointer to intel_wopcm.
69 *
70 * Setup the size of WOPCM which will be used by later on WOPCM partitioning.
71 */
72void intel_wopcm_init_early(struct intel_wopcm *wopcm)
73{
74 wopcm->size = GEN9_WOPCM_SIZE;
75
76 DRM_DEBUG_DRIVER("WOPCM size: %uKiB\n", wopcm->size / 1024);
77}
78
79static inline u32 context_reserved_size(struct drm_i915_private *i915)
80{
81 if (IS_GEN9_LP(i915))
82 return BXT_WOPCM_RC6_CTX_RESERVED;
83 else if (INTEL_GEN(i915) >= 10)
84 return CNL_WOPCM_HW_CTX_RESERVED;
85 else
86 return 0;
87}
88
89static inline int gen9_check_dword_gap(u32 guc_wopcm_base, u32 guc_wopcm_size)
90{
91 u32 offset;
92
93 /*
94 * GuC WOPCM size shall be at least a dword larger than the offset from
95 * WOPCM base (GuC WOPCM offset from WOPCM base + GEN9_GUC_WOPCM_OFFSET)
96 * due to hardware limitation on Gen9.
97 */
98 offset = guc_wopcm_base + GEN9_GUC_WOPCM_OFFSET;
99 if (offset > guc_wopcm_size ||
100 (guc_wopcm_size - offset) < sizeof(u32)) {
101 DRM_ERROR("GuC WOPCM size %uKiB is too small. %uKiB needed.\n",
102 guc_wopcm_size / 1024,
103 (u32)(offset + sizeof(u32)) / 1024);
104 return -E2BIG;
105 }
106
107 return 0;
108}
109
110static inline int gen9_check_huc_fw_fits(u32 guc_wopcm_size, u32 huc_fw_size)
111{
112 /*
113 * On Gen9 & CNL A0, hardware requires the total available GuC WOPCM
114 * size to be larger than or equal to HuC firmware size. Otherwise,
115 * firmware uploading would fail.
116 */
117 if (huc_fw_size > guc_wopcm_size - GUC_WOPCM_RESERVED) {
118 DRM_ERROR("HuC FW (%uKiB) won't fit in GuC WOPCM (%uKiB).\n",
119 huc_fw_size / 1024,
120 (guc_wopcm_size - GUC_WOPCM_RESERVED) / 1024);
121 return -E2BIG;
122 }
123
124 return 0;
125}
126
127static inline int check_hw_restriction(struct drm_i915_private *i915,
128 u32 guc_wopcm_base, u32 guc_wopcm_size,
129 u32 huc_fw_size)
130{
131 int err = 0;
132
133 if (IS_GEN9(i915))
134 err = gen9_check_dword_gap(guc_wopcm_base, guc_wopcm_size);
135
136 if (!err &&
137 (IS_GEN9(i915) || IS_CNL_REVID(i915, CNL_REVID_A0, CNL_REVID_A0)))
138 err = gen9_check_huc_fw_fits(guc_wopcm_size, huc_fw_size);
139
140 return err;
141}
142
143/**
144 * intel_wopcm_init() - Initialize the WOPCM structure.
145 * @wopcm: pointer to intel_wopcm.
146 *
147 * This function will partition WOPCM space based on GuC and HuC firmware sizes
148 * and will allocate max remaining for use by GuC. This function will also
149 * enforce platform dependent hardware restrictions on GuC WOPCM offset and
150 * size. It will fail the WOPCM init if any of these checks were failed, so that
151 * the following GuC firmware uploading would be aborted.
152 *
153 * Return: 0 on success, non-zero error code on failure.
154 */
155int intel_wopcm_init(struct intel_wopcm *wopcm)
156{
157 struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
158 u32 guc_fw_size = intel_uc_fw_get_upload_size(&i915->guc.fw);
159 u32 huc_fw_size = intel_uc_fw_get_upload_size(&i915->huc.fw);
160 u32 ctx_rsvd = context_reserved_size(i915);
161 u32 guc_wopcm_base;
162 u32 guc_wopcm_size;
163 u32 guc_wopcm_rsvd;
164 int err;
165
166 GEM_BUG_ON(!wopcm->size);
167
168 if (guc_fw_size >= wopcm->size) {
169 DRM_ERROR("GuC FW (%uKiB) is too big to fit in WOPCM.",
170 guc_fw_size / 1024);
171 return -E2BIG;
172 }
173
174 if (huc_fw_size >= wopcm->size) {
175 DRM_ERROR("HuC FW (%uKiB) is too big to fit in WOPCM.",
176 huc_fw_size / 1024);
177 return -E2BIG;
178 }
179
180 guc_wopcm_base = ALIGN(huc_fw_size + WOPCM_RESERVED_SIZE,
181 GUC_WOPCM_OFFSET_ALIGNMENT);
182 if ((guc_wopcm_base + ctx_rsvd) >= wopcm->size) {
183 DRM_ERROR("GuC WOPCM base (%uKiB) is too big.\n",
184 guc_wopcm_base / 1024);
185 return -E2BIG;
186 }
187
188 guc_wopcm_size = wopcm->size - guc_wopcm_base - ctx_rsvd;
189 guc_wopcm_size &= GUC_WOPCM_SIZE_MASK;
190
191 DRM_DEBUG_DRIVER("Calculated GuC WOPCM Region: [%uKiB, %uKiB)\n",
192 guc_wopcm_base / 1024, guc_wopcm_size / 1024);
193
194 guc_wopcm_rsvd = GUC_WOPCM_RESERVED + GUC_WOPCM_STACK_RESERVED;
195 if ((guc_fw_size + guc_wopcm_rsvd) > guc_wopcm_size) {
196 DRM_ERROR("Need %uKiB WOPCM for GuC, %uKiB available.\n",
197 (guc_fw_size + guc_wopcm_rsvd) / 1024,
198 guc_wopcm_size / 1024);
199 return -E2BIG;
200 }
201
202 err = check_hw_restriction(i915, guc_wopcm_base, guc_wopcm_size,
203 huc_fw_size);
204 if (err)
205 return err;
206
207 wopcm->guc.base = guc_wopcm_base;
208 wopcm->guc.size = guc_wopcm_size;
209
210 return 0;
211}
212
213static inline int write_and_verify(struct drm_i915_private *dev_priv,
214 i915_reg_t reg, u32 val, u32 mask,
215 u32 locked_bit)
216{
217 u32 reg_val;
218
219 GEM_BUG_ON(val & ~mask);
220
221 I915_WRITE(reg, val);
222
223 reg_val = I915_READ(reg);
224
225 return (reg_val & mask) != (val | locked_bit) ? -EIO : 0;
226}
227
228/**
229 * intel_wopcm_init_hw() - Setup GuC WOPCM registers.
230 * @wopcm: pointer to intel_wopcm.
231 *
232 * Setup the GuC WOPCM size and offset registers with the calculated values. It
233 * will verify the register values to make sure the registers are locked with
234 * correct values.
235 *
236 * Return: 0 on success. -EIO if registers were locked with incorrect values.
237 */
238int intel_wopcm_init_hw(struct intel_wopcm *wopcm)
239{
240 struct drm_i915_private *dev_priv = wopcm_to_i915(wopcm);
241 u32 huc_agent;
242 u32 mask;
243 int err;
244
245 if (!USES_GUC(dev_priv))
246 return 0;
247
248 GEM_BUG_ON(!HAS_GUC(dev_priv));
249 GEM_BUG_ON(!wopcm->guc.size);
250 GEM_BUG_ON(!wopcm->guc.base);
251
252 err = write_and_verify(dev_priv, GUC_WOPCM_SIZE, wopcm->guc.size,
253 GUC_WOPCM_SIZE_MASK | GUC_WOPCM_SIZE_LOCKED,
254 GUC_WOPCM_SIZE_LOCKED);
255 if (err)
256 goto err_out;
257
258 huc_agent = USES_HUC(dev_priv) ? HUC_LOADING_AGENT_GUC : 0;
259 mask = GUC_WOPCM_OFFSET_MASK | GUC_WOPCM_OFFSET_VALID | huc_agent;
260 err = write_and_verify(dev_priv, DMA_GUC_WOPCM_OFFSET,
261 wopcm->guc.base | huc_agent, mask,
262 GUC_WOPCM_OFFSET_VALID);
263 if (err)
264 goto err_out;
265
266 return 0;
267
268err_out:
269 DRM_ERROR("Failed to init WOPCM registers:\n");
270 DRM_ERROR("DMA_GUC_WOPCM_OFFSET=%#x\n",
271 I915_READ(DMA_GUC_WOPCM_OFFSET));
272 DRM_ERROR("GUC_WOPCM_SIZE=%#x\n", I915_READ(GUC_WOPCM_SIZE));
273
274 return err;
275}
diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/intel_wopcm.h
new file mode 100644
index 000000000000..6298910a384c
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_wopcm.h
@@ -0,0 +1,31 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright © 2017-2018 Intel Corporation
5 */
6
7#ifndef _INTEL_WOPCM_H_
8#define _INTEL_WOPCM_H_
9
10#include <linux/types.h>
11
12/**
13 * struct intel_wopcm - Overall WOPCM info and WOPCM regions.
14 * @size: Size of overall WOPCM.
15 * @guc: GuC WOPCM Region info.
16 * @guc.base: GuC WOPCM base which is offset from WOPCM base.
17 * @guc.size: Size of the GuC WOPCM region.
18 */
19struct intel_wopcm {
20 u32 size;
21 struct {
22 u32 base;
23 u32 size;
24 } guc;
25};
26
27void intel_wopcm_init_early(struct intel_wopcm *wopcm);
28int intel_wopcm_init(struct intel_wopcm *wopcm);
29int intel_wopcm_init_hw(struct intel_wopcm *wopcm);
30
31#endif
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
new file mode 100644
index 000000000000..2df3538ceba5
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -0,0 +1,949 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright © 2014-2018 Intel Corporation
5 */
6
7#include "i915_drv.h"
8#include "intel_workarounds.h"
9
10/**
11 * DOC: Hardware workarounds
12 *
13 * This file is intended as a central place to implement most [1]_ of the
14 * required workarounds for hardware to work as originally intended. They fall
15 * in five basic categories depending on how/when they are applied:
16 *
17 * - Workarounds that touch registers that are saved/restored to/from the HW
18 * context image. The list is emitted (via Load Register Immediate commands)
19 * everytime a new context is created.
20 * - GT workarounds. The list of these WAs is applied whenever these registers
21 * revert to default values (on GPU reset, suspend/resume [2]_, etc..).
22 * - Display workarounds. The list is applied during display clock-gating
23 * initialization.
24 * - Workarounds that whitelist a privileged register, so that UMDs can manage
25 * them directly. This is just a special case of a MMMIO workaround (as we
26 * write the list of these to/be-whitelisted registers to some special HW
27 * registers).
28 * - Workaround batchbuffers, that get executed automatically by the hardware
29 * on every HW context restore.
30 *
31 * .. [1] Please notice that there are other WAs that, due to their nature,
32 * cannot be applied from a central place. Those are peppered around the rest
33 * of the code, as needed.
34 *
35 * .. [2] Technically, some registers are powercontext saved & restored, so they
36 * survive a suspend/resume. In practice, writing them again is not too
37 * costly and simplifies things. We can revisit this in the future.
38 *
39 * Layout
40 * ''''''
41 *
42 * Keep things in this file ordered by WA type, as per the above (context, GT,
43 * display, register whitelist, batchbuffer). Then, inside each type, keep the
44 * following order:
45 *
46 * - Infrastructure functions and macros
47 * - WAs per platform in standard gen/chrono order
48 * - Public functions to init or apply the given workaround type.
49 */
50
51static int wa_add(struct drm_i915_private *dev_priv,
52 i915_reg_t addr,
53 const u32 mask, const u32 val)
54{
55 const unsigned int idx = dev_priv->workarounds.count;
56
57 if (WARN_ON(idx >= I915_MAX_WA_REGS))
58 return -ENOSPC;
59
60 dev_priv->workarounds.reg[idx].addr = addr;
61 dev_priv->workarounds.reg[idx].value = val;
62 dev_priv->workarounds.reg[idx].mask = mask;
63
64 dev_priv->workarounds.count++;
65
66 return 0;
67}
68
69#define WA_REG(addr, mask, val) do { \
70 const int r = wa_add(dev_priv, (addr), (mask), (val)); \
71 if (r) \
72 return r; \
73 } while (0)
74
75#define WA_SET_BIT_MASKED(addr, mask) \
76 WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask))
77
78#define WA_CLR_BIT_MASKED(addr, mask) \
79 WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask))
80
81#define WA_SET_FIELD_MASKED(addr, mask, value) \
82 WA_REG(addr, (mask), _MASKED_FIELD(mask, value))
83
84static int gen8_ctx_workarounds_init(struct drm_i915_private *dev_priv)
85{
86 WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
87
88 /* WaDisableAsyncFlipPerfMode:bdw,chv */
89 WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE);
90
91 /* WaDisablePartialInstShootdown:bdw,chv */
92 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
93 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
94
95 /* Use Force Non-Coherent whenever executing a 3D context. This is a
96 * workaround for for a possible hang in the unlikely event a TLB
97 * invalidation occurs during a PSD flush.
98 */
99 /* WaForceEnableNonCoherent:bdw,chv */
100 /* WaHdcDisableFetchWhenMasked:bdw,chv */
101 WA_SET_BIT_MASKED(HDC_CHICKEN0,
102 HDC_DONOT_FETCH_MEM_WHEN_MASKED |
103 HDC_FORCE_NON_COHERENT);
104
105 /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
106 * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
107 * polygons in the same 8x4 pixel/sample area to be processed without
108 * stalling waiting for the earlier ones to write to Hierarchical Z
109 * buffer."
110 *
111 * This optimization is off by default for BDW and CHV; turn it on.
112 */
113 WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
114
115 /* Wa4x4STCOptimizationDisable:bdw,chv */
116 WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);
117
118 /*
119 * BSpec recommends 8x4 when MSAA is used,
120 * however in practice 16x4 seems fastest.
121 *
122 * Note that PS/WM thread counts depend on the WIZ hashing
123 * disable bit, which we don't touch here, but it's good
124 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
125 */
126 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
127 GEN6_WIZ_HASHING_MASK,
128 GEN6_WIZ_HASHING_16x4);
129
130 return 0;
131}
132
133static int bdw_ctx_workarounds_init(struct drm_i915_private *dev_priv)
134{
135 int ret;
136
137 ret = gen8_ctx_workarounds_init(dev_priv);
138 if (ret)
139 return ret;
140
141 /* WaDisableThreadStallDopClockGating:bdw (pre-production) */
142 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
143
144 /* WaDisableDopClockGating:bdw
145 *
146 * Also see the related UCGTCL1 write in broadwell_init_clock_gating()
147 * to disable EUTC clock gating.
148 */
149 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2,
150 DOP_CLOCK_GATING_DISABLE);
151
152 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
153 GEN8_SAMPLER_POWER_BYPASS_DIS);
154
155 WA_SET_BIT_MASKED(HDC_CHICKEN0,
156 /* WaForceContextSaveRestoreNonCoherent:bdw */
157 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
158 /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */
159 (IS_BDW_GT3(dev_priv) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
160
161 return 0;
162}
163
164static int chv_ctx_workarounds_init(struct drm_i915_private *dev_priv)
165{
166 int ret;
167
168 ret = gen8_ctx_workarounds_init(dev_priv);
169 if (ret)
170 return ret;
171
172 /* WaDisableThreadStallDopClockGating:chv */
173 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
174
175 /* Improve HiZ throughput on CHV. */
176 WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
177
178 return 0;
179}
180
181static int gen9_ctx_workarounds_init(struct drm_i915_private *dev_priv)
182{
183 if (HAS_LLC(dev_priv)) {
184 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
185 *
186 * Must match Display Engine. See
187 * WaCompressedResourceDisplayNewHashMode.
188 */
189 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
190 GEN9_PBE_COMPRESSED_HASH_SELECTION);
191 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
192 GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR);
193 }
194
195 /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */
196 /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */
197 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
198 FLOW_CONTROL_ENABLE |
199 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
200
201 /* Syncing dependencies between camera and graphics:skl,bxt,kbl */
202 if (!IS_COFFEELAKE(dev_priv))
203 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
204 GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
205
206 /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */
207 /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */
208 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
209 GEN9_ENABLE_YV12_BUGFIX |
210 GEN9_ENABLE_GPGPU_PREEMPTION);
211
212 /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk,cfl */
213 /* WaDisablePartialResolveInVc:skl,bxt,kbl,cfl */
214 WA_SET_BIT_MASKED(CACHE_MODE_1,
215 GEN8_4x4_STC_OPTIMIZATION_DISABLE |
216 GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE);
217
218 /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */
219 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
220 GEN9_CCS_TLB_PREFETCH_ENABLE);
221
222 /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */
223 WA_SET_BIT_MASKED(HDC_CHICKEN0,
224 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
225 HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
226
227 /* WaForceEnableNonCoherent and WaDisableHDCInvalidation are
228 * both tied to WaForceContextSaveRestoreNonCoherent
229 * in some hsds for skl. We keep the tie for all gen9. The
230 * documentation is a bit hazy and so we want to get common behaviour,
231 * even though there is no clear evidence we would need both on kbl/bxt.
232 * This area has been source of system hangs so we play it safe
233 * and mimic the skl regardless of what bspec says.
234 *
235 * Use Force Non-Coherent whenever executing a 3D context. This
236 * is a workaround for a possible hang in the unlikely event
237 * a TLB invalidation occurs during a PSD flush.
238 */
239
240 /* WaForceEnableNonCoherent:skl,bxt,kbl,cfl */
241 WA_SET_BIT_MASKED(HDC_CHICKEN0,
242 HDC_FORCE_NON_COHERENT);
243
244 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */
245 if (IS_SKYLAKE(dev_priv) ||
246 IS_KABYLAKE(dev_priv) ||
247 IS_COFFEELAKE(dev_priv))
248 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
249 GEN8_SAMPLER_POWER_BYPASS_DIS);
250
251 /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */
252 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
253
254 /*
255 * Supporting preemption with fine-granularity requires changes in the
256 * batch buffer programming. Since we can't break old userspace, we
257 * need to set our default preemption level to safe value. Userspace is
258 * still able to use more fine-grained preemption levels, since in
259 * WaEnablePreemptionGranularityControlByUMD we're whitelisting the
260 * per-ctx register. As such, WaDisable{3D,GPGPU}MidCmdPreemption are
261 * not real HW workarounds, but merely a way to start using preemption
262 * while maintaining old contract with userspace.
263 */
264
265 /* WaDisable3DMidCmdPreemption:skl,bxt,glk,cfl,[cnl] */
266 WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL);
267
268 /* WaDisableGPGPUMidCmdPreemption:skl,bxt,blk,cfl,[cnl] */
269 WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1,
270 GEN9_PREEMPT_GPGPU_LEVEL_MASK,
271 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);
272
273 /* WaClearHIZ_WM_CHICKEN3:bxt,glk */
274 if (IS_GEN9_LP(dev_priv))
275 WA_SET_BIT_MASKED(GEN9_WM_CHICKEN3, GEN9_FACTOR_IN_CLR_VAL_HIZ);
276
277 return 0;
278}
279
280static int skl_tune_iz_hashing(struct drm_i915_private *dev_priv)
281{
282 u8 vals[3] = { 0, 0, 0 };
283 unsigned int i;
284
285 for (i = 0; i < 3; i++) {
286 u8 ss;
287
288 /*
289 * Only consider slices where one, and only one, subslice has 7
290 * EUs
291 */
292 if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]))
293 continue;
294
295 /*
296 * subslice_7eu[i] != 0 (because of the check above) and
297 * ss_max == 4 (maximum number of subslices possible per slice)
298 *
299 * -> 0 <= ss <= 3;
300 */
301 ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1;
302 vals[i] = 3 - ss;
303 }
304
305 if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
306 return 0;
307
308 /* Tune IZ hashing. See intel_device_info_runtime_init() */
309 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
310 GEN9_IZ_HASHING_MASK(2) |
311 GEN9_IZ_HASHING_MASK(1) |
312 GEN9_IZ_HASHING_MASK(0),
313 GEN9_IZ_HASHING(2, vals[2]) |
314 GEN9_IZ_HASHING(1, vals[1]) |
315 GEN9_IZ_HASHING(0, vals[0]));
316
317 return 0;
318}
319
320static int skl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
321{
322 int ret;
323
324 ret = gen9_ctx_workarounds_init(dev_priv);
325 if (ret)
326 return ret;
327
328 return skl_tune_iz_hashing(dev_priv);
329}
330
331static int bxt_ctx_workarounds_init(struct drm_i915_private *dev_priv)
332{
333 int ret;
334
335 ret = gen9_ctx_workarounds_init(dev_priv);
336 if (ret)
337 return ret;
338
339